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