1bf215546Sopenharmony_ci/* -*- mesa-c++  -*-
2bf215546Sopenharmony_ci *
3bf215546Sopenharmony_ci * Copyright (c) 2021 Collabora LTD
4bf215546Sopenharmony_ci *
5bf215546Sopenharmony_ci * Author: Gert Wollny <gert.wollny@collabora.com>
6bf215546Sopenharmony_ci *
7bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
8bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
9bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
10bf215546Sopenharmony_ci * on the rights to use, copy, modify, merge, publish, distribute, sub
11bf215546Sopenharmony_ci * license, and/or sell copies of the Software, and to permit persons to whom
12bf215546Sopenharmony_ci * the Software is furnished to do so, subject to the following conditions:
13bf215546Sopenharmony_ci *
14bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
15bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
16bf215546Sopenharmony_ci * Software.
17bf215546Sopenharmony_ci *
18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21bf215546Sopenharmony_ci * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
22bf215546Sopenharmony_ci * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23bf215546Sopenharmony_ci * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24bf215546Sopenharmony_ci * USE OR OTHER DEALINGS IN THE SOFTWARE.
25bf215546Sopenharmony_ci */
26bf215546Sopenharmony_ci
27bf215546Sopenharmony_ci#pragma once
28bf215546Sopenharmony_ci
29bf215546Sopenharmony_ci#include "sfn_memorypool.h"
30bf215546Sopenharmony_ci#include "sfn_alu_defines.h"
31bf215546Sopenharmony_ci#include <memory>
32bf215546Sopenharmony_ci#include <vector>
33bf215546Sopenharmony_ci#include <iosfwd>
34bf215546Sopenharmony_ci#include <map>
35bf215546Sopenharmony_ci#include <set>
36bf215546Sopenharmony_ci#include <array>
37bf215546Sopenharmony_ci#include <cassert>
38bf215546Sopenharmony_ci
39bf215546Sopenharmony_ci#if __cpp_exceptions >= 199711L
40bf215546Sopenharmony_ci#include <exception>
41bf215546Sopenharmony_ci#define ASSERT_OR_THROW(EXPR, ERROR) if (!(EXPR))  throw std::invalid_argument(ERROR)
42bf215546Sopenharmony_ci#else
43bf215546Sopenharmony_ci#define ASSERT_OR_THROW(EXPR, ERROR) if (!(EXPR)) unreachable(ERROR)
44bf215546Sopenharmony_ci#endif
45bf215546Sopenharmony_ci
46bf215546Sopenharmony_cinamespace r600 {
47bf215546Sopenharmony_ci
48bf215546Sopenharmony_cienum Pin {
49bf215546Sopenharmony_ci   pin_none,
50bf215546Sopenharmony_ci   pin_chan,
51bf215546Sopenharmony_ci   pin_array,
52bf215546Sopenharmony_ci   pin_group,
53bf215546Sopenharmony_ci   pin_chgr,
54bf215546Sopenharmony_ci   pin_fully,
55bf215546Sopenharmony_ci   pin_free
56bf215546Sopenharmony_ci};
57bf215546Sopenharmony_ci
58bf215546Sopenharmony_cistd::ostream& operator << (std::ostream& os, Pin pin);
59bf215546Sopenharmony_ci
60bf215546Sopenharmony_ciclass Register;
61bf215546Sopenharmony_ciclass RegisterVisitor;
62bf215546Sopenharmony_ciclass ConstRegisterVisitor;
63bf215546Sopenharmony_ciclass Instr;
64bf215546Sopenharmony_ciclass InlineConstant;
65bf215546Sopenharmony_ciclass LiteralConstant;
66bf215546Sopenharmony_ciclass UniformValue;
67bf215546Sopenharmony_ci
68bf215546Sopenharmony_ciusing InstructionSet = std::set<Instr *, std::less<Instr *>,  Allocator<Instr *>>;
69bf215546Sopenharmony_ci
70bf215546Sopenharmony_ciclass VirtualValue : public Allocate {
71bf215546Sopenharmony_cipublic:
72bf215546Sopenharmony_ci
73bf215546Sopenharmony_ci   static const uint32_t virtual_register_base = 1024;
74bf215546Sopenharmony_ci   static const uint32_t clause_temp_registers = 2;
75bf215546Sopenharmony_ci   static const uint32_t gpr_register_end = 128 - 2 * clause_temp_registers;
76bf215546Sopenharmony_ci   static const uint32_t clause_temp_register_begin = gpr_register_end;
77bf215546Sopenharmony_ci   static const uint32_t clause_temp_register_end = 128;
78bf215546Sopenharmony_ci
79bf215546Sopenharmony_ci   static const uint32_t uniforms_begin = 512;
80bf215546Sopenharmony_ci   static const uint32_t uniforms_end = 640;
81bf215546Sopenharmony_ci
82bf215546Sopenharmony_ci   using Pointer = R600_POINTER_TYPE(VirtualValue);
83bf215546Sopenharmony_ci
84bf215546Sopenharmony_ci   VirtualValue(int sel, int chan, Pin pin);
85bf215546Sopenharmony_ci   VirtualValue(const VirtualValue& orig) = default;
86bf215546Sopenharmony_ci
87bf215546Sopenharmony_ci   int sel() const { return m_sel; }
88bf215546Sopenharmony_ci   int chan() const { return m_chan;}
89bf215546Sopenharmony_ci   Pin pin() const { return m_pins;};
90bf215546Sopenharmony_ci   bool is_virtual() const;
91bf215546Sopenharmony_ci
92bf215546Sopenharmony_ci   void set_pin(Pin p) { m_pins = p;}
93bf215546Sopenharmony_ci
94bf215546Sopenharmony_ci
95bf215546Sopenharmony_ci   virtual void accept(RegisterVisitor& vistor) = 0;
96bf215546Sopenharmony_ci   virtual void accept(ConstRegisterVisitor& vistor) const = 0;
97bf215546Sopenharmony_ci   virtual void print(std::ostream& os) const = 0;
98bf215546Sopenharmony_ci
99bf215546Sopenharmony_ci   bool equal_to(const VirtualValue& other) const;
100bf215546Sopenharmony_ci   Pointer get_addr() const;
101bf215546Sopenharmony_ci
102bf215546Sopenharmony_ci   static Pointer from_string(const std::string& s);
103bf215546Sopenharmony_ci
104bf215546Sopenharmony_ci   virtual Register *as_register() { return nullptr;}
105bf215546Sopenharmony_ci   virtual InlineConstant * as_inline_const() { return nullptr;}
106bf215546Sopenharmony_ci   virtual LiteralConstant *as_literal() { return nullptr;}
107bf215546Sopenharmony_ci   virtual UniformValue *as_uniform() { return nullptr;}
108bf215546Sopenharmony_ci   virtual bool ready(int block, int index) const;
109bf215546Sopenharmony_ci
110bf215546Sopenharmony_ci   static constexpr char chanchar[9] = "xyzw01?_";
111bf215546Sopenharmony_ci
112bf215546Sopenharmony_ciprotected:
113bf215546Sopenharmony_ci   void do_set_chan(int c) {m_chan = c;}
114bf215546Sopenharmony_ci   void set_sel_internal(int sel) { m_sel = sel; }
115bf215546Sopenharmony_ci
116bf215546Sopenharmony_ciprivate:
117bf215546Sopenharmony_ci   uint32_t m_sel;
118bf215546Sopenharmony_ci   int m_chan;
119bf215546Sopenharmony_ci   Pin m_pins;
120bf215546Sopenharmony_ci};
121bf215546Sopenharmony_ciusing PVirtualValue = VirtualValue::Pointer;
122bf215546Sopenharmony_ci
123bf215546Sopenharmony_ci
124bf215546Sopenharmony_ciinline std::ostream& operator << (std::ostream& os, const VirtualValue& val)
125bf215546Sopenharmony_ci{
126bf215546Sopenharmony_ci    val.print(os);
127bf215546Sopenharmony_ci    return os;
128bf215546Sopenharmony_ci}
129bf215546Sopenharmony_ci
130bf215546Sopenharmony_ciinline bool operator == (const VirtualValue& lhs, const VirtualValue& rhs)
131bf215546Sopenharmony_ci{
132bf215546Sopenharmony_ci    return lhs.equal_to(rhs);
133bf215546Sopenharmony_ci}
134bf215546Sopenharmony_ci
135bf215546Sopenharmony_cistruct LiveRange {
136bf215546Sopenharmony_ci   LiveRange(): start(-1), end(-1), is_pinned(false) {}
137bf215546Sopenharmony_ci   LiveRange(int s, int e): start(s), end(e), is_pinned(false) {}
138bf215546Sopenharmony_ci   int start;
139bf215546Sopenharmony_ci   int end;
140bf215546Sopenharmony_ci   int is_pinned;
141bf215546Sopenharmony_ci};
142bf215546Sopenharmony_ci
143bf215546Sopenharmony_ciclass Register : public VirtualValue {
144bf215546Sopenharmony_cipublic:
145bf215546Sopenharmony_ci    using Pointer = R600_POINTER_TYPE(Register);
146bf215546Sopenharmony_ci
147bf215546Sopenharmony_ci    Register(int sel, int chan, Pin pin);
148bf215546Sopenharmony_ci    void accept(RegisterVisitor& vistor) override;
149bf215546Sopenharmony_ci    void accept(ConstRegisterVisitor& vistor) const override;
150bf215546Sopenharmony_ci    void print(std::ostream& os) const override;
151bf215546Sopenharmony_ci
152bf215546Sopenharmony_ci    int live_start_pinned() const { return m_pin_start;}
153bf215546Sopenharmony_ci    int live_end_pinned() const { return m_pin_end;}
154bf215546Sopenharmony_ci
155bf215546Sopenharmony_ci    void pin_live_range(bool start, bool end = false);
156bf215546Sopenharmony_ci
157bf215546Sopenharmony_ci    static Pointer from_string(const std::string& s);
158bf215546Sopenharmony_ci
159bf215546Sopenharmony_ci    Register *as_register() override { return this;}
160bf215546Sopenharmony_ci
161bf215546Sopenharmony_ci    void set_is_ssa(bool value);
162bf215546Sopenharmony_ci
163bf215546Sopenharmony_ci    bool is_ssa() const { return m_is_ssa;}
164bf215546Sopenharmony_ci
165bf215546Sopenharmony_ci    void add_parent(Instr *instr);
166bf215546Sopenharmony_ci    void del_parent(Instr *instr);
167bf215546Sopenharmony_ci    const InstructionSet& parents() const {return m_parents;}
168bf215546Sopenharmony_ci
169bf215546Sopenharmony_ci    bool ready(int block, int index) const override;
170bf215546Sopenharmony_ci
171bf215546Sopenharmony_ci    const InstructionSet& uses() const {return m_uses;}
172bf215546Sopenharmony_ci    void add_use(Instr *instr);
173bf215546Sopenharmony_ci    void del_use(Instr *instr);
174bf215546Sopenharmony_ci    bool has_uses() const {return !m_uses.empty() || pin() == pin_array;}
175bf215546Sopenharmony_ci    void set_chan(int c) {do_set_chan(c);}
176bf215546Sopenharmony_ci
177bf215546Sopenharmony_ci    virtual VirtualValue *addr() const { return nullptr;}
178bf215546Sopenharmony_ci
179bf215546Sopenharmony_ci    int index() const {return m_index;}
180bf215546Sopenharmony_ci    void set_index(int idx) {m_index = idx;}
181bf215546Sopenharmony_ci
182bf215546Sopenharmony_ci    void set_sel(int new_sel) { set_sel_internal(new_sel); m_is_ssa = false;}
183bf215546Sopenharmony_ci
184bf215546Sopenharmony_ciprivate:
185bf215546Sopenharmony_ci    Register(const Register& orig) = delete;
186bf215546Sopenharmony_ci    Register(const Register&& orig) = delete;
187bf215546Sopenharmony_ci    Register& operator = (const Register& orig) = delete;
188bf215546Sopenharmony_ci    Register& operator = (Register&& orig) = delete;
189bf215546Sopenharmony_ci
190bf215546Sopenharmony_ci    virtual void forward_del_use(Instr *instr) {(void)instr;}
191bf215546Sopenharmony_ci    virtual void forward_add_use(Instr *instr) {(void)instr;}
192bf215546Sopenharmony_ci    virtual void add_parent_to_array(Instr *instr);
193bf215546Sopenharmony_ci    virtual void del_parent_from_array(Instr *instr);
194bf215546Sopenharmony_ci
195bf215546Sopenharmony_ci    InstructionSet m_parents;
196bf215546Sopenharmony_ci    InstructionSet m_uses;
197bf215546Sopenharmony_ci
198bf215546Sopenharmony_ci    int m_index{-1};
199bf215546Sopenharmony_ci
200bf215546Sopenharmony_ci    bool m_is_ssa {false};
201bf215546Sopenharmony_ci    bool m_pin_start {false};
202bf215546Sopenharmony_ci    bool m_pin_end {false};
203bf215546Sopenharmony_ci};
204bf215546Sopenharmony_ciusing PRegister = Register::Pointer;
205bf215546Sopenharmony_ci
206bf215546Sopenharmony_ciinline std::ostream& operator << (std::ostream& os, const Register& val)
207bf215546Sopenharmony_ci{
208bf215546Sopenharmony_ci    val.print(os);
209bf215546Sopenharmony_ci    return os;
210bf215546Sopenharmony_ci}
211bf215546Sopenharmony_ci
212bf215546Sopenharmony_ciclass InlineConstant : public VirtualValue {
213bf215546Sopenharmony_cipublic:
214bf215546Sopenharmony_ci    using Pointer = R600_POINTER_TYPE(InlineConstant);
215bf215546Sopenharmony_ci
216bf215546Sopenharmony_ci    InlineConstant(int sel, int chan = 0);
217bf215546Sopenharmony_ci
218bf215546Sopenharmony_ci    void accept(RegisterVisitor& vistor) override;
219bf215546Sopenharmony_ci    void accept(ConstRegisterVisitor& vistor) const override;
220bf215546Sopenharmony_ci    void print(std::ostream& os) const override;
221bf215546Sopenharmony_ci    static Pointer from_string(const std::string& s);
222bf215546Sopenharmony_ci	 static Pointer param_from_string(const std::string& s);
223bf215546Sopenharmony_ci
224bf215546Sopenharmony_ci    InlineConstant * as_inline_const() override { return this;}
225bf215546Sopenharmony_ciprivate:
226bf215546Sopenharmony_ci    InlineConstant(const InlineConstant& orig) = default;
227bf215546Sopenharmony_ci    static std::map<std::string, std::pair<AluInlineConstants, bool>> s_opmap;
228bf215546Sopenharmony_ci
229bf215546Sopenharmony_ci};
230bf215546Sopenharmony_ciusing PInlineConstant = InlineConstant::Pointer;
231bf215546Sopenharmony_ci
232bf215546Sopenharmony_ciinline std::ostream& operator << (std::ostream& os, const InlineConstant& val)
233bf215546Sopenharmony_ci{
234bf215546Sopenharmony_ci    val.print(os);
235bf215546Sopenharmony_ci    return os;
236bf215546Sopenharmony_ci}
237bf215546Sopenharmony_ci
238bf215546Sopenharmony_ciclass RegisterVec4 {
239bf215546Sopenharmony_cipublic:
240bf215546Sopenharmony_ci	using Swizzle = std::array<uint8_t, 4>;
241bf215546Sopenharmony_ci   RegisterVec4();
242bf215546Sopenharmony_ci   RegisterVec4(int sel, bool is_ssa = false, const Swizzle& swz = {0,1,2,3}, Pin pin = pin_group);
243bf215546Sopenharmony_ci   RegisterVec4(PRegister x, PRegister y, PRegister z, PRegister w, Pin pin);
244bf215546Sopenharmony_ci
245bf215546Sopenharmony_ci   RegisterVec4(const RegisterVec4& orig);
246bf215546Sopenharmony_ci
247bf215546Sopenharmony_ci   RegisterVec4(RegisterVec4&& orig) = default;
248bf215546Sopenharmony_ci   RegisterVec4& operator = (RegisterVec4& orig) = default;
249bf215546Sopenharmony_ci   RegisterVec4& operator = (RegisterVec4&& orig) = default;
250bf215546Sopenharmony_ci
251bf215546Sopenharmony_ci   void add_use(Instr *instr);
252bf215546Sopenharmony_ci   void del_use(Instr *instr);
253bf215546Sopenharmony_ci   bool has_uses() const;
254bf215546Sopenharmony_ci
255bf215546Sopenharmony_ci   int sel() const;
256bf215546Sopenharmony_ci   void print(std::ostream& os) const;
257bf215546Sopenharmony_ci
258bf215546Sopenharmony_ci   class Element  : public Allocate {
259bf215546Sopenharmony_ci   public:
260bf215546Sopenharmony_ci      Element(const RegisterVec4& parent, int chan);
261bf215546Sopenharmony_ci      Element(const RegisterVec4& parent, PRegister value);
262bf215546Sopenharmony_ci      PRegister value() { return m_value; }
263bf215546Sopenharmony_ci      void set_value(PRegister reg) { m_value = reg;}
264bf215546Sopenharmony_ci   private:
265bf215546Sopenharmony_ci      const RegisterVec4& m_parent;
266bf215546Sopenharmony_ci      PRegister m_value;
267bf215546Sopenharmony_ci	};
268bf215546Sopenharmony_ci
269bf215546Sopenharmony_ci	friend class Element;
270bf215546Sopenharmony_ci
271bf215546Sopenharmony_ci	PRegister operator [] (int i) const {
272bf215546Sopenharmony_ci           return m_values[i]->value();
273bf215546Sopenharmony_ci	}
274bf215546Sopenharmony_ci
275bf215546Sopenharmony_ci        PRegister operator [] (int i) {
276bf215546Sopenharmony_ci           return m_values[i]->value();
277bf215546Sopenharmony_ci        }
278bf215546Sopenharmony_ci
279bf215546Sopenharmony_ci        void set_value(int i, PRegister reg) {
280bf215546Sopenharmony_ci           assert(reg->sel() == m_sel);
281bf215546Sopenharmony_ci           m_swz[i] = reg->chan();
282bf215546Sopenharmony_ci           m_values[i]->set_value(reg);
283bf215546Sopenharmony_ci        }
284bf215546Sopenharmony_ci
285bf215546Sopenharmony_ci        bool ready(int block_id, int index) const;
286bf215546Sopenharmony_ciprivate:
287bf215546Sopenharmony_ci        int m_sel;
288bf215546Sopenharmony_ci        Swizzle m_swz;
289bf215546Sopenharmony_ci        std::array<R600_POINTER_TYPE(Element), 4> m_values;
290bf215546Sopenharmony_ci};
291bf215546Sopenharmony_ci
292bf215546Sopenharmony_cibool operator == (const RegisterVec4& lhs, const RegisterVec4& rhs);
293bf215546Sopenharmony_ci
294bf215546Sopenharmony_ciinline bool operator != (const RegisterVec4& lhs, const RegisterVec4& rhs)
295bf215546Sopenharmony_ci{
296bf215546Sopenharmony_ci   return !(lhs == rhs);
297bf215546Sopenharmony_ci}
298bf215546Sopenharmony_ci
299bf215546Sopenharmony_ciinline std::ostream& operator << (std::ostream& os, const RegisterVec4& val)
300bf215546Sopenharmony_ci{
301bf215546Sopenharmony_ci    val.print(os);
302bf215546Sopenharmony_ci    return os;
303bf215546Sopenharmony_ci}
304bf215546Sopenharmony_ci
305bf215546Sopenharmony_ci
306bf215546Sopenharmony_ciclass LiteralConstant : public VirtualValue {
307bf215546Sopenharmony_cipublic:
308bf215546Sopenharmony_ci   using Pointer = R600_POINTER_TYPE(LiteralConstant);
309bf215546Sopenharmony_ci
310bf215546Sopenharmony_ci   LiteralConstant(uint32_t value);
311bf215546Sopenharmony_ci   void accept(RegisterVisitor& vistor) override;
312bf215546Sopenharmony_ci   void accept(ConstRegisterVisitor& vistor) const override;
313bf215546Sopenharmony_ci   void print(std::ostream& os) const override;
314bf215546Sopenharmony_ci   uint32_t value() const {return m_value;}
315bf215546Sopenharmony_ci   static Pointer from_string(const std::string& s);
316bf215546Sopenharmony_ci   LiteralConstant *as_literal() override { return this;}
317bf215546Sopenharmony_ci
318bf215546Sopenharmony_ciprivate:
319bf215546Sopenharmony_ci   LiteralConstant(const LiteralConstant& orig) = default;
320bf215546Sopenharmony_ci   uint32_t m_value;
321bf215546Sopenharmony_ci};
322bf215546Sopenharmony_ciusing PLiteralVirtualValue = LiteralConstant::Pointer;
323bf215546Sopenharmony_ci
324bf215546Sopenharmony_ci
325bf215546Sopenharmony_ciclass UniformValue : public VirtualValue {
326bf215546Sopenharmony_cipublic:
327bf215546Sopenharmony_ci   using Pointer = R600_POINTER_TYPE(UniformValue);
328bf215546Sopenharmony_ci
329bf215546Sopenharmony_ci   UniformValue(int sel, int chan, int kcache_bank = 0);
330bf215546Sopenharmony_ci   UniformValue(int sel, int chan, PVirtualValue buf_addr);
331bf215546Sopenharmony_ci
332bf215546Sopenharmony_ci   void accept(RegisterVisitor& vistor) override;
333bf215546Sopenharmony_ci   void accept(ConstRegisterVisitor& vistor) const override;
334bf215546Sopenharmony_ci   void print(std::ostream& os) const override;
335bf215546Sopenharmony_ci   int kcache_bank() const { return m_kcache_bank; }
336bf215546Sopenharmony_ci   PVirtualValue buf_addr() const;
337bf215546Sopenharmony_ci   UniformValue *as_uniform() override { return this;}
338bf215546Sopenharmony_ci
339bf215546Sopenharmony_ci   bool equal_buf_and_cache(const UniformValue& other) const;
340bf215546Sopenharmony_ci   static Pointer from_string(const std::string& s);
341bf215546Sopenharmony_ci
342bf215546Sopenharmony_ciprivate:
343bf215546Sopenharmony_ci   int m_kcache_bank;
344bf215546Sopenharmony_ci   PVirtualValue m_buf_addr;
345bf215546Sopenharmony_ci};
346bf215546Sopenharmony_ciusing PUniformVirtualValue = UniformValue::Pointer;
347bf215546Sopenharmony_ci
348bf215546Sopenharmony_ciinline std::ostream& operator << (std::ostream& os, const UniformValue& val)
349bf215546Sopenharmony_ci{
350bf215546Sopenharmony_ci    val.print(os);
351bf215546Sopenharmony_ci    return os;
352bf215546Sopenharmony_ci}
353bf215546Sopenharmony_ci
354bf215546Sopenharmony_ciclass LocalArrayValue;
355bf215546Sopenharmony_ciclass LocalArray : public Register {
356bf215546Sopenharmony_cipublic:
357bf215546Sopenharmony_ci   using Pointer = R600_POINTER_TYPE(LocalArray);
358bf215546Sopenharmony_ci   using Values = std::vector<LocalArrayValue *, Allocator<LocalArrayValue *> >;
359bf215546Sopenharmony_ci
360bf215546Sopenharmony_ci   LocalArray(int base_sel, int nchannels, int size, int frac = 0);
361bf215546Sopenharmony_ci   void accept(RegisterVisitor& vistor) override;
362bf215546Sopenharmony_ci   void accept(ConstRegisterVisitor& vistor) const override;
363bf215546Sopenharmony_ci   void print(std::ostream& os) const override;
364bf215546Sopenharmony_ci   bool ready_for_direct(int block, int index, int chan) const;
365bf215546Sopenharmony_ci   bool ready_for_indirect(int block, int index, int chan) const;
366bf215546Sopenharmony_ci
367bf215546Sopenharmony_ci   PRegister element(size_t offset, PVirtualValue indirect, uint32_t chan);
368bf215546Sopenharmony_ci
369bf215546Sopenharmony_ci   size_t size() const;
370bf215546Sopenharmony_ci   uint32_t nchannels() const;
371bf215546Sopenharmony_ci   uint32_t frac() const { return m_frac;}
372bf215546Sopenharmony_ci
373bf215546Sopenharmony_ci   void add_parent_to_elements(Instr *instr);
374bf215546Sopenharmony_ci
375bf215546Sopenharmony_ci   const Register& operator ()(size_t idx, size_t chan) const;
376bf215546Sopenharmony_ci
377bf215546Sopenharmony_ci   Values::iterator begin() { return m_values.begin();}
378bf215546Sopenharmony_ci   Values::iterator end() { return m_values.end();}
379bf215546Sopenharmony_ci
380bf215546Sopenharmony_ciprivate:
381bf215546Sopenharmony_ci    uint32_t m_base_sel;
382bf215546Sopenharmony_ci    uint32_t m_nchannels;
383bf215546Sopenharmony_ci    size_t m_size;
384bf215546Sopenharmony_ci    Values m_values;
385bf215546Sopenharmony_ci    Values m_values_indirect;
386bf215546Sopenharmony_ci    int m_frac;
387bf215546Sopenharmony_ci};
388bf215546Sopenharmony_ci
389bf215546Sopenharmony_ciinline std::ostream& operator << (std::ostream& os, const LocalArray & val)
390bf215546Sopenharmony_ci{
391bf215546Sopenharmony_ci    val.print(os);
392bf215546Sopenharmony_ci    return os;
393bf215546Sopenharmony_ci}
394bf215546Sopenharmony_ci
395bf215546Sopenharmony_ciclass LocalArrayValue : public Register {
396bf215546Sopenharmony_cipublic:
397bf215546Sopenharmony_ci    using Pointer = R600_POINTER_TYPE(LocalArrayValue);
398bf215546Sopenharmony_ci
399bf215546Sopenharmony_ci    LocalArrayValue(PRegister reg, LocalArray& array);
400bf215546Sopenharmony_ci    LocalArrayValue(PRegister reg, PVirtualValue index, LocalArray &array);
401bf215546Sopenharmony_ci
402bf215546Sopenharmony_ci    void accept(RegisterVisitor& vistor) override;
403bf215546Sopenharmony_ci    void accept(ConstRegisterVisitor& vistor) const override;
404bf215546Sopenharmony_ci    void print(std::ostream& os) const override;
405bf215546Sopenharmony_ci    bool ready(int block, int index) const override;
406bf215546Sopenharmony_ci
407bf215546Sopenharmony_ci    VirtualValue *addr() const override;
408bf215546Sopenharmony_ci    const LocalArray& array() const;
409bf215546Sopenharmony_ciprivate:
410bf215546Sopenharmony_ci    void forward_del_use(Instr *instr) override;
411bf215546Sopenharmony_ci    void forward_add_use(Instr *instr) override;
412bf215546Sopenharmony_ci    void add_parent_to_array(Instr *instr) override;
413bf215546Sopenharmony_ci    void del_parent_from_array(Instr *instr) override;
414bf215546Sopenharmony_ci
415bf215546Sopenharmony_ci    PVirtualValue m_addr;
416bf215546Sopenharmony_ci    LocalArray& m_array;
417bf215546Sopenharmony_ci};
418bf215546Sopenharmony_ci
419bf215546Sopenharmony_ciinline std::ostream& operator << (std::ostream& os, const LocalArrayValue& val)
420bf215546Sopenharmony_ci{
421bf215546Sopenharmony_ci    val.print(os);
422bf215546Sopenharmony_ci    return os;
423bf215546Sopenharmony_ci}
424bf215546Sopenharmony_ci
425bf215546Sopenharmony_citemplate <typename T>
426bf215546Sopenharmony_cibool sfn_value_equal(const T* lhs, const T* rhs)
427bf215546Sopenharmony_ci{
428bf215546Sopenharmony_ci   if (lhs) {
429bf215546Sopenharmony_ci      if (!rhs) return
430bf215546Sopenharmony_ci            false;
431bf215546Sopenharmony_ci      if ( !lhs->equal_to(*rhs))
432bf215546Sopenharmony_ci         return false;
433bf215546Sopenharmony_ci   } else {
434bf215546Sopenharmony_ci      if (rhs)
435bf215546Sopenharmony_ci         return false;
436bf215546Sopenharmony_ci   }
437bf215546Sopenharmony_ci   return true;
438bf215546Sopenharmony_ci}
439bf215546Sopenharmony_ci
440bf215546Sopenharmony_ciclass RegisterVisitor {
441bf215546Sopenharmony_cipublic:
442bf215546Sopenharmony_ci    virtual void visit(Register& value) = 0;
443bf215546Sopenharmony_ci    virtual void visit(LocalArray& value) = 0;
444bf215546Sopenharmony_ci    virtual void visit(LocalArrayValue& value) = 0;
445bf215546Sopenharmony_ci    virtual void visit(UniformValue& value) = 0;
446bf215546Sopenharmony_ci    virtual void visit(LiteralConstant& value) = 0;
447bf215546Sopenharmony_ci    virtual void visit(InlineConstant& value) = 0;
448bf215546Sopenharmony_ci};
449bf215546Sopenharmony_ci
450bf215546Sopenharmony_ciclass ConstRegisterVisitor {
451bf215546Sopenharmony_cipublic:
452bf215546Sopenharmony_ci    virtual void visit(const Register& value) = 0;
453bf215546Sopenharmony_ci    virtual void visit(const LocalArray& value) = 0;
454bf215546Sopenharmony_ci    virtual void visit(const LocalArrayValue& value) = 0;
455bf215546Sopenharmony_ci    virtual void visit(const UniformValue& value) = 0;
456bf215546Sopenharmony_ci    virtual void visit(const LiteralConstant& value) = 0;
457bf215546Sopenharmony_ci    virtual void visit(const InlineConstant& value) = 0;
458bf215546Sopenharmony_ci};
459bf215546Sopenharmony_ci
460bf215546Sopenharmony_ci}
461bf215546Sopenharmony_ci
462