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#include "sfn_instr_alugroup.h" 28bf215546Sopenharmony_ci#include "sfn_instr_export.h" 29bf215546Sopenharmony_ci#include "sfn_instr_fetch.h" 30bf215546Sopenharmony_ci#include "sfn_instr_mem.h" 31bf215546Sopenharmony_ci#include "sfn_instr_lds.h" 32bf215546Sopenharmony_ci#include "sfn_instr_tex.h" 33bf215546Sopenharmony_ci#include "sfn_instr_controlflow.h" 34bf215546Sopenharmony_ci 35bf215546Sopenharmony_ci#include <iostream> 36bf215546Sopenharmony_ci#include <sstream> 37bf215546Sopenharmony_ci#include <numeric> 38bf215546Sopenharmony_ci 39bf215546Sopenharmony_cinamespace r600 { 40bf215546Sopenharmony_ci 41bf215546Sopenharmony_ciusing std::string; 42bf215546Sopenharmony_ciusing std::vector; 43bf215546Sopenharmony_ci 44bf215546Sopenharmony_ciInstr::Instr(): 45bf215546Sopenharmony_ci m_use_count(0), 46bf215546Sopenharmony_ci m_block_id(std::numeric_limits<int>::max()), 47bf215546Sopenharmony_ci m_index(std::numeric_limits<int>::max()) 48bf215546Sopenharmony_ci{ 49bf215546Sopenharmony_ci} 50bf215546Sopenharmony_ci 51bf215546Sopenharmony_ciInstr::~Instr() 52bf215546Sopenharmony_ci{ 53bf215546Sopenharmony_ci 54bf215546Sopenharmony_ci} 55bf215546Sopenharmony_ci 56bf215546Sopenharmony_civoid Instr::print(std::ostream& os) const 57bf215546Sopenharmony_ci{ 58bf215546Sopenharmony_ci do_print(os); 59bf215546Sopenharmony_ci} 60bf215546Sopenharmony_ci 61bf215546Sopenharmony_cibool Instr::ready() const 62bf215546Sopenharmony_ci{ 63bf215546Sopenharmony_ci for (auto& i : m_required_instr) 64bf215546Sopenharmony_ci if (!i->ready()) 65bf215546Sopenharmony_ci return false; 66bf215546Sopenharmony_ci return do_ready(); 67bf215546Sopenharmony_ci} 68bf215546Sopenharmony_ci 69bf215546Sopenharmony_ciint int_from_string_with_prefix(const std::string& str, const std::string& prefix) 70bf215546Sopenharmony_ci{ 71bf215546Sopenharmony_ci if (str.substr(0, prefix.length()) != prefix) { 72bf215546Sopenharmony_ci std::cerr << "Expect '" << prefix << "' as start of '" << str << "'\n"; 73bf215546Sopenharmony_ci assert(0); 74bf215546Sopenharmony_ci } 75bf215546Sopenharmony_ci 76bf215546Sopenharmony_ci std::stringstream help(str.substr(prefix.length())); 77bf215546Sopenharmony_ci int retval; 78bf215546Sopenharmony_ci help >> retval; 79bf215546Sopenharmony_ci return retval; 80bf215546Sopenharmony_ci} 81bf215546Sopenharmony_ci 82bf215546Sopenharmony_ciint sel_and_szw_from_string(const std::string& str, RegisterVec4::Swizzle &swz, bool& is_ssa) 83bf215546Sopenharmony_ci{ 84bf215546Sopenharmony_ci assert(str[0] == 'R' || str[0] == '_' || str[0] == 'S'); 85bf215546Sopenharmony_ci int sel = 0; 86bf215546Sopenharmony_ci 87bf215546Sopenharmony_ci auto istr = str.begin() + 1; 88bf215546Sopenharmony_ci 89bf215546Sopenharmony_ci if (str[0] == '_') { 90bf215546Sopenharmony_ci while (istr != str.end() && *istr == '_') 91bf215546Sopenharmony_ci ++istr; 92bf215546Sopenharmony_ci sel = std::numeric_limits<int>::max(); 93bf215546Sopenharmony_ci } else { 94bf215546Sopenharmony_ci while (istr != str.end() && isdigit(*istr)) { 95bf215546Sopenharmony_ci sel *= 10; 96bf215546Sopenharmony_ci sel += *istr - '0'; 97bf215546Sopenharmony_ci ++istr; 98bf215546Sopenharmony_ci } 99bf215546Sopenharmony_ci } 100bf215546Sopenharmony_ci 101bf215546Sopenharmony_ci assert(*istr == '.'); 102bf215546Sopenharmony_ci istr++; 103bf215546Sopenharmony_ci 104bf215546Sopenharmony_ci int i = 0; 105bf215546Sopenharmony_ci while (istr != str.end()) { 106bf215546Sopenharmony_ci switch (*istr) { 107bf215546Sopenharmony_ci case 'x': swz[i] = 0; break; 108bf215546Sopenharmony_ci case 'y': swz[i] = 1; break; 109bf215546Sopenharmony_ci case 'z': swz[i] = 2; break; 110bf215546Sopenharmony_ci case 'w': swz[i] = 3; break; 111bf215546Sopenharmony_ci case '0': swz[i] = 4; break; 112bf215546Sopenharmony_ci case '1': swz[i] = 5; break; 113bf215546Sopenharmony_ci case '_': swz[i] = 7; break; 114bf215546Sopenharmony_ci default: 115bf215546Sopenharmony_ci unreachable("Unknown swizzle character"); 116bf215546Sopenharmony_ci } 117bf215546Sopenharmony_ci ++istr; 118bf215546Sopenharmony_ci ++i; 119bf215546Sopenharmony_ci } 120bf215546Sopenharmony_ci 121bf215546Sopenharmony_ci is_ssa = str[0] == 'S'; 122bf215546Sopenharmony_ci 123bf215546Sopenharmony_ci return sel; 124bf215546Sopenharmony_ci} 125bf215546Sopenharmony_ci 126bf215546Sopenharmony_cibool Instr::is_last() const 127bf215546Sopenharmony_ci{ 128bf215546Sopenharmony_ci return true; 129bf215546Sopenharmony_ci} 130bf215546Sopenharmony_ci 131bf215546Sopenharmony_cibool Instr::set_dead() 132bf215546Sopenharmony_ci{ 133bf215546Sopenharmony_ci if (m_instr_flags.test(always_keep)) 134bf215546Sopenharmony_ci return false; 135bf215546Sopenharmony_ci bool is_dead = propagate_death(); 136bf215546Sopenharmony_ci m_instr_flags.set(dead); 137bf215546Sopenharmony_ci return is_dead; 138bf215546Sopenharmony_ci} 139bf215546Sopenharmony_ci 140bf215546Sopenharmony_cibool Instr::propagate_death() 141bf215546Sopenharmony_ci{ 142bf215546Sopenharmony_ci return true; 143bf215546Sopenharmony_ci} 144bf215546Sopenharmony_ci 145bf215546Sopenharmony_cibool Instr::replace_source(PRegister old_src, PVirtualValue new_src) 146bf215546Sopenharmony_ci{ 147bf215546Sopenharmony_ci (void)old_src; 148bf215546Sopenharmony_ci (void)new_src; 149bf215546Sopenharmony_ci return false; 150bf215546Sopenharmony_ci} 151bf215546Sopenharmony_ci 152bf215546Sopenharmony_civoid Instr::add_required_instr(Instr *instr) 153bf215546Sopenharmony_ci{ 154bf215546Sopenharmony_ci assert(instr); 155bf215546Sopenharmony_ci m_required_instr.push_back(instr); 156bf215546Sopenharmony_ci instr->m_dependend_instr.push_back(this); 157bf215546Sopenharmony_ci} 158bf215546Sopenharmony_ci 159bf215546Sopenharmony_civoid Instr::replace_required_instr(Instr *old_instr, Instr *new_instr) 160bf215546Sopenharmony_ci{ 161bf215546Sopenharmony_ci 162bf215546Sopenharmony_ci for (auto i = m_required_instr.begin(); i != m_required_instr.end(); ++i) { 163bf215546Sopenharmony_ci if (*i == old_instr) 164bf215546Sopenharmony_ci *i = new_instr; 165bf215546Sopenharmony_ci } 166bf215546Sopenharmony_ci} 167bf215546Sopenharmony_ci 168bf215546Sopenharmony_cibool Instr::replace_dest(PRegister new_dest, r600::AluInstr *move_instr) 169bf215546Sopenharmony_ci{ 170bf215546Sopenharmony_ci (void)new_dest; 171bf215546Sopenharmony_ci (void)move_instr; 172bf215546Sopenharmony_ci return false; 173bf215546Sopenharmony_ci} 174bf215546Sopenharmony_ci 175bf215546Sopenharmony_civoid Instr::set_blockid(int id, int index) 176bf215546Sopenharmony_ci{ 177bf215546Sopenharmony_ci m_block_id = id; 178bf215546Sopenharmony_ci m_index = index; 179bf215546Sopenharmony_ci forward_set_blockid(id, index); 180bf215546Sopenharmony_ci} 181bf215546Sopenharmony_ci 182bf215546Sopenharmony_ci 183bf215546Sopenharmony_civoid Instr::forward_set_blockid(int id, int index) 184bf215546Sopenharmony_ci{ 185bf215546Sopenharmony_ci (void)id; 186bf215546Sopenharmony_ci (void)index; 187bf215546Sopenharmony_ci} 188bf215546Sopenharmony_ci 189bf215546Sopenharmony_ciInstrWithVectorResult::InstrWithVectorResult(const RegisterVec4& dest, 190bf215546Sopenharmony_ci const RegisterVec4::Swizzle& dest_swizzle): 191bf215546Sopenharmony_ci m_dest(dest), 192bf215546Sopenharmony_ci m_dest_swizzle(dest_swizzle) 193bf215546Sopenharmony_ci{ 194bf215546Sopenharmony_ci for (int i = 0; i < 4; ++i) { 195bf215546Sopenharmony_ci if (m_dest_swizzle[i] < 6) 196bf215546Sopenharmony_ci m_dest[i]->add_parent(this); 197bf215546Sopenharmony_ci } 198bf215546Sopenharmony_ci} 199bf215546Sopenharmony_ci 200bf215546Sopenharmony_civoid InstrWithVectorResult::print_dest(std::ostream& os) const 201bf215546Sopenharmony_ci{ 202bf215546Sopenharmony_ci os << (m_dest[0]->is_ssa() ? 'S' : 'R' ) << m_dest.sel(); 203bf215546Sopenharmony_ci os << "."; 204bf215546Sopenharmony_ci for (int i = 0; i < 4; ++i) 205bf215546Sopenharmony_ci os << VirtualValue::chanchar[m_dest_swizzle[i]]; 206bf215546Sopenharmony_ci} 207bf215546Sopenharmony_ci 208bf215546Sopenharmony_cibool InstrWithVectorResult::comp_dest(const RegisterVec4& dest, 209bf215546Sopenharmony_ci const RegisterVec4::Swizzle& dest_swizzle) const 210bf215546Sopenharmony_ci{ 211bf215546Sopenharmony_ci for(int i = 0; i < 4; ++i) { 212bf215546Sopenharmony_ci if (!m_dest[i]->equal_to(*dest[i])) { 213bf215546Sopenharmony_ci return false; 214bf215546Sopenharmony_ci } 215bf215546Sopenharmony_ci if (m_dest_swizzle[i] != dest_swizzle[i]) 216bf215546Sopenharmony_ci return false; 217bf215546Sopenharmony_ci } 218bf215546Sopenharmony_ci return true; 219bf215546Sopenharmony_ci} 220bf215546Sopenharmony_ci 221bf215546Sopenharmony_civoid Block::do_print(std::ostream& os) const 222bf215546Sopenharmony_ci{ 223bf215546Sopenharmony_ci for (int j = 0; j < 2 * m_nesting_depth; ++j) 224bf215546Sopenharmony_ci os << ' '; 225bf215546Sopenharmony_ci os << "BLOCK START\n"; 226bf215546Sopenharmony_ci for (auto& i : m_instructions) { 227bf215546Sopenharmony_ci for (int j = 0; j < 2 * (m_nesting_depth + i->nesting_corr()) + 2; ++j) 228bf215546Sopenharmony_ci os << ' '; 229bf215546Sopenharmony_ci os << *i << "\n"; 230bf215546Sopenharmony_ci } 231bf215546Sopenharmony_ci for (int j = 0; j < 2 * m_nesting_depth; ++j) 232bf215546Sopenharmony_ci os << ' '; 233bf215546Sopenharmony_ci os << "BLOCK END\n"; 234bf215546Sopenharmony_ci} 235bf215546Sopenharmony_ci 236bf215546Sopenharmony_cibool Block::is_equal_to(const Block& lhs) const 237bf215546Sopenharmony_ci{ 238bf215546Sopenharmony_ci if (m_id != lhs.m_id || m_nesting_depth != lhs.m_nesting_depth) 239bf215546Sopenharmony_ci return false; 240bf215546Sopenharmony_ci 241bf215546Sopenharmony_ci if (m_instructions.size() != lhs.m_instructions.size()) 242bf215546Sopenharmony_ci return false; 243bf215546Sopenharmony_ci 244bf215546Sopenharmony_ci return std::inner_product(m_instructions.begin(), m_instructions.end(), lhs.m_instructions.begin(), 245bf215546Sopenharmony_ci true, 246bf215546Sopenharmony_ci [] (bool l, bool r) { return l && r;}, 247bf215546Sopenharmony_ci [](PInst l, PInst r) { return l->equal_to(*r);}); 248bf215546Sopenharmony_ci} 249bf215546Sopenharmony_ci 250bf215546Sopenharmony_ciinline bool operator != (const Block& lhs, const Block& rhs) 251bf215546Sopenharmony_ci{ 252bf215546Sopenharmony_ci return !lhs.is_equal_to(rhs); 253bf215546Sopenharmony_ci} 254bf215546Sopenharmony_ci 255bf215546Sopenharmony_civoid Block::erase(iterator node) 256bf215546Sopenharmony_ci{ 257bf215546Sopenharmony_ci m_instructions.erase(node); 258bf215546Sopenharmony_ci} 259bf215546Sopenharmony_ci 260bf215546Sopenharmony_civoid Block::set_type(Type t) 261bf215546Sopenharmony_ci{ 262bf215546Sopenharmony_ci m_blocK_type = t; 263bf215546Sopenharmony_ci switch (t) { 264bf215546Sopenharmony_ci case vtx: 265bf215546Sopenharmony_ci case gds: 266bf215546Sopenharmony_ci case tex: m_remaining_slots = 8; break; /* TODO: 16 for >= EVERGREEN */ 267bf215546Sopenharmony_ci default: 268bf215546Sopenharmony_ci m_remaining_slots = 0xffff; 269bf215546Sopenharmony_ci } 270bf215546Sopenharmony_ci} 271bf215546Sopenharmony_ci 272bf215546Sopenharmony_ciBlock::Block(int nesting_depth, int id): 273bf215546Sopenharmony_ci m_nesting_depth(nesting_depth), 274bf215546Sopenharmony_ci m_id(id), 275bf215546Sopenharmony_ci m_next_index(0) 276bf215546Sopenharmony_ci{ 277bf215546Sopenharmony_ci assert(!has_instr_flag(force_cf)); 278bf215546Sopenharmony_ci} 279bf215546Sopenharmony_ci 280bf215546Sopenharmony_civoid Block::accept(ConstInstrVisitor& visitor) const 281bf215546Sopenharmony_ci{ 282bf215546Sopenharmony_ci visitor.visit(*this); 283bf215546Sopenharmony_ci} 284bf215546Sopenharmony_ci 285bf215546Sopenharmony_civoid Block::accept(InstrVisitor& visitor) 286bf215546Sopenharmony_ci{ 287bf215546Sopenharmony_ci visitor.visit(this); 288bf215546Sopenharmony_ci} 289bf215546Sopenharmony_ci 290bf215546Sopenharmony_civoid Block::push_back(PInst instr) 291bf215546Sopenharmony_ci{ 292bf215546Sopenharmony_ci instr->set_blockid(m_id, m_next_index++); 293bf215546Sopenharmony_ci if (m_remaining_slots != 0xffff) { 294bf215546Sopenharmony_ci uint32_t new_slots = instr->slots(); 295bf215546Sopenharmony_ci m_remaining_slots -= new_slots; 296bf215546Sopenharmony_ci } 297bf215546Sopenharmony_ci if (m_lds_group_start) 298bf215546Sopenharmony_ci m_lds_group_requirement += instr->slots(); 299bf215546Sopenharmony_ci 300bf215546Sopenharmony_ci m_instructions.push_back(instr); 301bf215546Sopenharmony_ci} 302bf215546Sopenharmony_ci 303bf215546Sopenharmony_cibool Block::try_reserve_kcache(const AluGroup& group) 304bf215546Sopenharmony_ci{ 305bf215546Sopenharmony_ci auto kcache = m_kcache; 306bf215546Sopenharmony_ci 307bf215546Sopenharmony_ci auto kcache_constants = group.get_kconsts(); 308bf215546Sopenharmony_ci for (auto& kc : kcache_constants) { 309bf215546Sopenharmony_ci auto u = kc->as_uniform(); 310bf215546Sopenharmony_ci assert(u); 311bf215546Sopenharmony_ci if (!try_reserve_kcache(*u, kcache)) { 312bf215546Sopenharmony_ci m_kcache_alloc_failed = true; 313bf215546Sopenharmony_ci return false; 314bf215546Sopenharmony_ci } 315bf215546Sopenharmony_ci } 316bf215546Sopenharmony_ci 317bf215546Sopenharmony_ci m_kcache = kcache; 318bf215546Sopenharmony_ci m_kcache_alloc_failed = false; 319bf215546Sopenharmony_ci return true; 320bf215546Sopenharmony_ci} 321bf215546Sopenharmony_ci 322bf215546Sopenharmony_cibool Block::try_reserve_kcache(const AluInstr& instr) 323bf215546Sopenharmony_ci{ 324bf215546Sopenharmony_ci auto kcache = m_kcache; 325bf215546Sopenharmony_ci 326bf215546Sopenharmony_ci for (auto& src : instr.sources()) { 327bf215546Sopenharmony_ci auto u = src->as_uniform(); 328bf215546Sopenharmony_ci if (u) { 329bf215546Sopenharmony_ci if (!try_reserve_kcache(*u, kcache)) { 330bf215546Sopenharmony_ci m_kcache_alloc_failed = true; 331bf215546Sopenharmony_ci return false; 332bf215546Sopenharmony_ci } 333bf215546Sopenharmony_ci } 334bf215546Sopenharmony_ci } 335bf215546Sopenharmony_ci m_kcache = kcache; 336bf215546Sopenharmony_ci m_kcache_alloc_failed = false; 337bf215546Sopenharmony_ci return true; 338bf215546Sopenharmony_ci} 339bf215546Sopenharmony_ci 340bf215546Sopenharmony_civoid Block::set_chipclass(r600_chip_class chip_class) 341bf215546Sopenharmony_ci{ 342bf215546Sopenharmony_ci if (chip_class < ISA_CC_EVERGREEN) 343bf215546Sopenharmony_ci s_max_kcache_banks = 2; 344bf215546Sopenharmony_ci else 345bf215546Sopenharmony_ci s_max_kcache_banks = 4; 346bf215546Sopenharmony_ci} 347bf215546Sopenharmony_ci 348bf215546Sopenharmony_ciunsigned Block::s_max_kcache_banks = 4; 349bf215546Sopenharmony_ci 350bf215546Sopenharmony_cibool Block::try_reserve_kcache(const UniformValue& u, 351bf215546Sopenharmony_ci std::array<KCacheLine, 4>& kcache) const 352bf215546Sopenharmony_ci{ 353bf215546Sopenharmony_ci const int kcache_banks = s_max_kcache_banks; // TODO: handle pre-evergreen 354bf215546Sopenharmony_ci 355bf215546Sopenharmony_ci int bank = u.kcache_bank(); 356bf215546Sopenharmony_ci int sel = (u.sel() - 512); 357bf215546Sopenharmony_ci int line = sel >> 4; 358bf215546Sopenharmony_ci 359bf215546Sopenharmony_ci bool found = false; 360bf215546Sopenharmony_ci 361bf215546Sopenharmony_ci for (int i = 0; i < kcache_banks && !found; ++i) { 362bf215546Sopenharmony_ci if (kcache[i].mode) { 363bf215546Sopenharmony_ci if (kcache[i].bank < bank) 364bf215546Sopenharmony_ci continue; 365bf215546Sopenharmony_ci 366bf215546Sopenharmony_ci if ((kcache[i].bank == bank && 367bf215546Sopenharmony_ci kcache[i].addr > line + 1) || 368bf215546Sopenharmony_ci kcache[i].bank > bank) { 369bf215546Sopenharmony_ci if (kcache[kcache_banks - 1].mode) 370bf215546Sopenharmony_ci return false; 371bf215546Sopenharmony_ci 372bf215546Sopenharmony_ci memmove(&kcache[i+1],&kcache[i], (kcache_banks-i-1)*sizeof(KCacheLine)); 373bf215546Sopenharmony_ci kcache[i].mode = KCacheLine::lock_1; 374bf215546Sopenharmony_ci kcache[i].bank = bank; 375bf215546Sopenharmony_ci kcache[i].addr = line; 376bf215546Sopenharmony_ci return true; 377bf215546Sopenharmony_ci } 378bf215546Sopenharmony_ci 379bf215546Sopenharmony_ci int d = line - kcache[i].addr; 380bf215546Sopenharmony_ci 381bf215546Sopenharmony_ci if (d == -1) { 382bf215546Sopenharmony_ci kcache[i].addr--; 383bf215546Sopenharmony_ci if (kcache[i].mode == KCacheLine::lock_2) { 384bf215546Sopenharmony_ci /* we are prepending the line to the current set, 385bf215546Sopenharmony_ci * discarding the existing second line, 386bf215546Sopenharmony_ci * so we'll have to insert line+2 after it */ 387bf215546Sopenharmony_ci line += 2; 388bf215546Sopenharmony_ci continue; 389bf215546Sopenharmony_ci } else if (kcache[i].mode == KCacheLine::lock_1) { 390bf215546Sopenharmony_ci kcache[i].mode = KCacheLine::lock_2; 391bf215546Sopenharmony_ci return true; 392bf215546Sopenharmony_ci } else { 393bf215546Sopenharmony_ci /* V_SQ_CF_KCACHE_LOCK_LOOP_INDEX is not supported */ 394bf215546Sopenharmony_ci return false; 395bf215546Sopenharmony_ci } 396bf215546Sopenharmony_ci } else if (d == 1) { 397bf215546Sopenharmony_ci kcache[i].mode = KCacheLine::lock_2; 398bf215546Sopenharmony_ci return true; 399bf215546Sopenharmony_ci } else if (d == 0) { 400bf215546Sopenharmony_ci return true; 401bf215546Sopenharmony_ci } 402bf215546Sopenharmony_ci } else { /* free kcache set - use it */ 403bf215546Sopenharmony_ci kcache[i].mode = KCacheLine::lock_1; 404bf215546Sopenharmony_ci kcache[i].bank = bank; 405bf215546Sopenharmony_ci kcache[i].addr = line; 406bf215546Sopenharmony_ci return true; 407bf215546Sopenharmony_ci } 408bf215546Sopenharmony_ci } 409bf215546Sopenharmony_ci return false; 410bf215546Sopenharmony_ci} 411bf215546Sopenharmony_ci 412bf215546Sopenharmony_civoid Block::lds_group_start(AluInstr *alu) 413bf215546Sopenharmony_ci{ 414bf215546Sopenharmony_ci assert(!m_lds_group_start); 415bf215546Sopenharmony_ci m_lds_group_start = alu; 416bf215546Sopenharmony_ci m_lds_group_requirement = 0; 417bf215546Sopenharmony_ci} 418bf215546Sopenharmony_ci 419bf215546Sopenharmony_civoid Block::lds_group_end() 420bf215546Sopenharmony_ci{ 421bf215546Sopenharmony_ci assert(m_lds_group_start); 422bf215546Sopenharmony_ci m_lds_group_start->set_required_slots(m_lds_group_requirement); 423bf215546Sopenharmony_ci m_lds_group_start = 0; 424bf215546Sopenharmony_ci} 425bf215546Sopenharmony_ci 426bf215546Sopenharmony_ciInstrWithVectorResult::InstrWithVectorResult(const InstrWithVectorResult& orig): 427bf215546Sopenharmony_ci m_dest(orig.m_dest), 428bf215546Sopenharmony_ci m_dest_swizzle(orig.m_dest_swizzle) 429bf215546Sopenharmony_ci{ 430bf215546Sopenharmony_ci} 431bf215546Sopenharmony_ci 432bf215546Sopenharmony_ciclass InstrComparer : public ConstInstrVisitor { 433bf215546Sopenharmony_cipublic: 434bf215546Sopenharmony_ci InstrComparer() = default; 435bf215546Sopenharmony_ci bool result {false}; 436bf215546Sopenharmony_ci 437bf215546Sopenharmony_ci#define DECLARE_MEMBER(TYPE) \ 438bf215546Sopenharmony_ci InstrComparer(const TYPE *instr) \ 439bf215546Sopenharmony_ci { \ 440bf215546Sopenharmony_ci this_ ## TYPE = instr; \ 441bf215546Sopenharmony_ci } \ 442bf215546Sopenharmony_ci \ 443bf215546Sopenharmony_ci void visit(const TYPE& instr) \ 444bf215546Sopenharmony_ci { \ 445bf215546Sopenharmony_ci result = false; \ 446bf215546Sopenharmony_ci if (!this_ ## TYPE) \ 447bf215546Sopenharmony_ci return; \ 448bf215546Sopenharmony_ci result = this_ ## TYPE->is_equal_to(instr); \ 449bf215546Sopenharmony_ci } \ 450bf215546Sopenharmony_ci \ 451bf215546Sopenharmony_ci const TYPE *this_ ## TYPE{nullptr}; 452bf215546Sopenharmony_ci 453bf215546Sopenharmony_ci DECLARE_MEMBER(AluInstr); 454bf215546Sopenharmony_ci DECLARE_MEMBER(AluGroup); 455bf215546Sopenharmony_ci DECLARE_MEMBER(TexInstr); 456bf215546Sopenharmony_ci DECLARE_MEMBER(ExportInstr); 457bf215546Sopenharmony_ci DECLARE_MEMBER(FetchInstr); 458bf215546Sopenharmony_ci DECLARE_MEMBER(Block); 459bf215546Sopenharmony_ci DECLARE_MEMBER(ControlFlowInstr); 460bf215546Sopenharmony_ci DECLARE_MEMBER(IfInstr); 461bf215546Sopenharmony_ci DECLARE_MEMBER(ScratchIOInstr); 462bf215546Sopenharmony_ci DECLARE_MEMBER(StreamOutInstr); 463bf215546Sopenharmony_ci DECLARE_MEMBER(MemRingOutInstr); 464bf215546Sopenharmony_ci DECLARE_MEMBER(EmitVertexInstr); 465bf215546Sopenharmony_ci DECLARE_MEMBER(GDSInstr); 466bf215546Sopenharmony_ci DECLARE_MEMBER(WriteTFInstr); 467bf215546Sopenharmony_ci DECLARE_MEMBER(LDSAtomicInstr); 468bf215546Sopenharmony_ci DECLARE_MEMBER(LDSReadInstr); 469bf215546Sopenharmony_ci DECLARE_MEMBER(RatInstr); 470bf215546Sopenharmony_ci}; 471bf215546Sopenharmony_ci 472bf215546Sopenharmony_ciclass InstrCompareForward: public ConstInstrVisitor { 473bf215546Sopenharmony_cipublic: 474bf215546Sopenharmony_ci 475bf215546Sopenharmony_ci void visit(const AluInstr& instr) override { 476bf215546Sopenharmony_ci m_comparer = InstrComparer(&instr); 477bf215546Sopenharmony_ci } 478bf215546Sopenharmony_ci 479bf215546Sopenharmony_ci void visit(const AluGroup& instr) override { 480bf215546Sopenharmony_ci m_comparer = InstrComparer(&instr); 481bf215546Sopenharmony_ci } 482bf215546Sopenharmony_ci 483bf215546Sopenharmony_ci void visit(const TexInstr& instr) override { 484bf215546Sopenharmony_ci m_comparer = InstrComparer(&instr); 485bf215546Sopenharmony_ci } 486bf215546Sopenharmony_ci 487bf215546Sopenharmony_ci void visit(const ExportInstr& instr) override { 488bf215546Sopenharmony_ci m_comparer = InstrComparer(&instr); 489bf215546Sopenharmony_ci } 490bf215546Sopenharmony_ci 491bf215546Sopenharmony_ci void visit(const FetchInstr& instr) override { 492bf215546Sopenharmony_ci m_comparer = InstrComparer(&instr); 493bf215546Sopenharmony_ci } 494bf215546Sopenharmony_ci 495bf215546Sopenharmony_ci void visit(const Block& instr) override { 496bf215546Sopenharmony_ci m_comparer = InstrComparer(&instr); 497bf215546Sopenharmony_ci } 498bf215546Sopenharmony_ci 499bf215546Sopenharmony_ci void visit(const ControlFlowInstr& instr) override { 500bf215546Sopenharmony_ci m_comparer = InstrComparer(&instr); 501bf215546Sopenharmony_ci } 502bf215546Sopenharmony_ci 503bf215546Sopenharmony_ci void visit(const IfInstr& instr) override { 504bf215546Sopenharmony_ci m_comparer = InstrComparer(&instr); 505bf215546Sopenharmony_ci } 506bf215546Sopenharmony_ci 507bf215546Sopenharmony_ci void visit(const ScratchIOInstr& instr) override { 508bf215546Sopenharmony_ci m_comparer = InstrComparer(&instr); 509bf215546Sopenharmony_ci } 510bf215546Sopenharmony_ci 511bf215546Sopenharmony_ci void visit(const StreamOutInstr& instr) override { 512bf215546Sopenharmony_ci m_comparer = InstrComparer(&instr); 513bf215546Sopenharmony_ci } 514bf215546Sopenharmony_ci 515bf215546Sopenharmony_ci void visit(const MemRingOutInstr& instr) override { 516bf215546Sopenharmony_ci m_comparer = InstrComparer(&instr); 517bf215546Sopenharmony_ci } 518bf215546Sopenharmony_ci 519bf215546Sopenharmony_ci void visit(const EmitVertexInstr& instr) override { 520bf215546Sopenharmony_ci m_comparer = InstrComparer(&instr); 521bf215546Sopenharmony_ci } 522bf215546Sopenharmony_ci 523bf215546Sopenharmony_ci void visit(const GDSInstr& instr) override { 524bf215546Sopenharmony_ci m_comparer = InstrComparer(&instr); 525bf215546Sopenharmony_ci } 526bf215546Sopenharmony_ci 527bf215546Sopenharmony_ci void visit(const WriteTFInstr& instr) override { 528bf215546Sopenharmony_ci m_comparer = InstrComparer(&instr); 529bf215546Sopenharmony_ci } 530bf215546Sopenharmony_ci 531bf215546Sopenharmony_ci void visit(const LDSAtomicInstr& instr) override { 532bf215546Sopenharmony_ci m_comparer = InstrComparer(&instr); 533bf215546Sopenharmony_ci } 534bf215546Sopenharmony_ci 535bf215546Sopenharmony_ci void visit(const LDSReadInstr& instr) override { 536bf215546Sopenharmony_ci m_comparer = InstrComparer(&instr); 537bf215546Sopenharmony_ci } 538bf215546Sopenharmony_ci 539bf215546Sopenharmony_ci void visit(const RatInstr& instr) override { 540bf215546Sopenharmony_ci m_comparer = InstrComparer(&instr); 541bf215546Sopenharmony_ci } 542bf215546Sopenharmony_ci 543bf215546Sopenharmony_ci InstrComparer m_comparer; 544bf215546Sopenharmony_ci}; 545bf215546Sopenharmony_ci 546bf215546Sopenharmony_ci 547bf215546Sopenharmony_cibool Instr::equal_to(const Instr& lhs) const 548bf215546Sopenharmony_ci{ 549bf215546Sopenharmony_ci InstrCompareForward cmp; 550bf215546Sopenharmony_ci accept(cmp); 551bf215546Sopenharmony_ci lhs.accept(cmp.m_comparer); 552bf215546Sopenharmony_ci 553bf215546Sopenharmony_ci return cmp.m_comparer.result; 554bf215546Sopenharmony_ci} 555bf215546Sopenharmony_ci 556bf215546Sopenharmony_ci 557bf215546Sopenharmony_ci 558bf215546Sopenharmony_ci 559bf215546Sopenharmony_ci} // ns r600 560