1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright 2011 Christoph Bumiller 3bf215546Sopenharmony_ci * 2014 Red Hat Inc. 4bf215546Sopenharmony_ci * 5bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 6bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 7bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 8bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 10bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 11bf215546Sopenharmony_ci * 12bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be included in 13bf215546Sopenharmony_ci * all copies or substantial portions of the Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 19bf215546Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 20bf215546Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 21bf215546Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE. 22bf215546Sopenharmony_ci */ 23bf215546Sopenharmony_ci 24bf215546Sopenharmony_ci#include "nv50_ir.h" 25bf215546Sopenharmony_ci#include "nv50_ir_build_util.h" 26bf215546Sopenharmony_ci 27bf215546Sopenharmony_ci#include "nv50_ir_target_nvc0.h" 28bf215546Sopenharmony_ci#include "nv50_ir_lowering_gm107.h" 29bf215546Sopenharmony_ci 30bf215546Sopenharmony_ci#include <limits> 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_cinamespace nv50_ir { 33bf215546Sopenharmony_ci 34bf215546Sopenharmony_ci#define QOP_ADD 0 35bf215546Sopenharmony_ci#define QOP_SUBR 1 36bf215546Sopenharmony_ci#define QOP_SUB 2 37bf215546Sopenharmony_ci#define QOP_MOV2 3 38bf215546Sopenharmony_ci 39bf215546Sopenharmony_ci// UL UR LL LR 40bf215546Sopenharmony_ci#define QUADOP(q, r, s, t) \ 41bf215546Sopenharmony_ci ((QOP_##q << 6) | (QOP_##r << 4) | \ 42bf215546Sopenharmony_ci (QOP_##s << 2) | (QOP_##t << 0)) 43bf215546Sopenharmony_ci 44bf215546Sopenharmony_ci#define SHFL_BOUND_QUAD 0x1c03 45bf215546Sopenharmony_ci 46bf215546Sopenharmony_civoid 47bf215546Sopenharmony_ciGM107LegalizeSSA::handlePFETCH(Instruction *i) 48bf215546Sopenharmony_ci{ 49bf215546Sopenharmony_ci Value *src0; 50bf215546Sopenharmony_ci 51bf215546Sopenharmony_ci if (i->src(0).getFile() == FILE_GPR && !i->srcExists(1)) 52bf215546Sopenharmony_ci return; 53bf215546Sopenharmony_ci 54bf215546Sopenharmony_ci bld.setPosition(i, false); 55bf215546Sopenharmony_ci src0 = bld.getSSA(); 56bf215546Sopenharmony_ci 57bf215546Sopenharmony_ci if (i->srcExists(1)) 58bf215546Sopenharmony_ci bld.mkOp2(OP_ADD , TYPE_U32, src0, i->getSrc(0), i->getSrc(1)); 59bf215546Sopenharmony_ci else 60bf215546Sopenharmony_ci bld.mkOp1(OP_MOV , TYPE_U32, src0, i->getSrc(0)); 61bf215546Sopenharmony_ci 62bf215546Sopenharmony_ci i->setSrc(0, src0); 63bf215546Sopenharmony_ci i->setSrc(1, NULL); 64bf215546Sopenharmony_ci} 65bf215546Sopenharmony_ci 66bf215546Sopenharmony_civoid 67bf215546Sopenharmony_ciGM107LegalizeSSA::handleLOAD(Instruction *i) 68bf215546Sopenharmony_ci{ 69bf215546Sopenharmony_ci if (i->src(0).getFile() != FILE_MEMORY_CONST) 70bf215546Sopenharmony_ci return; 71bf215546Sopenharmony_ci if (i->src(0).isIndirect(0)) 72bf215546Sopenharmony_ci return; 73bf215546Sopenharmony_ci if (typeSizeof(i->dType) != 4) 74bf215546Sopenharmony_ci return; 75bf215546Sopenharmony_ci 76bf215546Sopenharmony_ci i->op = OP_MOV; 77bf215546Sopenharmony_ci} 78bf215546Sopenharmony_ci 79bf215546Sopenharmony_civoid 80bf215546Sopenharmony_ciGM107LegalizeSSA::handleQUADON(Instruction *i) 81bf215546Sopenharmony_ci{ 82bf215546Sopenharmony_ci i->setDef(0, NULL); 83bf215546Sopenharmony_ci} 84bf215546Sopenharmony_ci 85bf215546Sopenharmony_civoid 86bf215546Sopenharmony_ciGM107LegalizeSSA::handleQUADPOP(Instruction *i) 87bf215546Sopenharmony_ci{ 88bf215546Sopenharmony_ci i->setSrc(0, NULL); 89bf215546Sopenharmony_ci} 90bf215546Sopenharmony_ci 91bf215546Sopenharmony_cibool 92bf215546Sopenharmony_ciGM107LegalizeSSA::visit(Instruction *i) 93bf215546Sopenharmony_ci{ 94bf215546Sopenharmony_ci switch (i->op) { 95bf215546Sopenharmony_ci case OP_QUADON: 96bf215546Sopenharmony_ci handleQUADON(i); 97bf215546Sopenharmony_ci break; 98bf215546Sopenharmony_ci case OP_QUADPOP: 99bf215546Sopenharmony_ci handleQUADPOP(i); 100bf215546Sopenharmony_ci break; 101bf215546Sopenharmony_ci case OP_PFETCH: 102bf215546Sopenharmony_ci handlePFETCH(i); 103bf215546Sopenharmony_ci break; 104bf215546Sopenharmony_ci case OP_LOAD: 105bf215546Sopenharmony_ci handleLOAD(i); 106bf215546Sopenharmony_ci break; 107bf215546Sopenharmony_ci default: 108bf215546Sopenharmony_ci break; 109bf215546Sopenharmony_ci } 110bf215546Sopenharmony_ci return true; 111bf215546Sopenharmony_ci} 112bf215546Sopenharmony_ci 113bf215546Sopenharmony_cibool 114bf215546Sopenharmony_ciGM107LoweringPass::handleManualTXD(TexInstruction *i) 115bf215546Sopenharmony_ci{ 116bf215546Sopenharmony_ci // See NVC0LoweringPass::handleManualTXD for rationale. This function 117bf215546Sopenharmony_ci // implements the same logic, but using SM50-friendly primitives. 118bf215546Sopenharmony_ci static const uint8_t qOps[2] = 119bf215546Sopenharmony_ci { QUADOP(MOV2, ADD, MOV2, ADD), QUADOP(MOV2, MOV2, ADD, ADD) }; 120bf215546Sopenharmony_ci Value *def[4][4]; 121bf215546Sopenharmony_ci Value *crd[3], *arr, *shadow; 122bf215546Sopenharmony_ci Value *tmp; 123bf215546Sopenharmony_ci Instruction *tex, *add; 124bf215546Sopenharmony_ci Value *quad = bld.mkImm(SHFL_BOUND_QUAD); 125bf215546Sopenharmony_ci int l, c; 126bf215546Sopenharmony_ci const int dim = i->tex.target.getDim() + i->tex.target.isCube(); 127bf215546Sopenharmony_ci const int array = i->tex.target.isArray(); 128bf215546Sopenharmony_ci const int indirect = i->tex.rIndirectSrc >= 0; 129bf215546Sopenharmony_ci 130bf215546Sopenharmony_ci i->op = OP_TEX; // no need to clone dPdx/dPdy later 131bf215546Sopenharmony_ci 132bf215546Sopenharmony_ci for (c = 0; c < dim; ++c) 133bf215546Sopenharmony_ci crd[c] = bld.getScratch(); 134bf215546Sopenharmony_ci arr = bld.getScratch(); 135bf215546Sopenharmony_ci shadow = bld.getScratch(); 136bf215546Sopenharmony_ci tmp = bld.getScratch(); 137bf215546Sopenharmony_ci 138bf215546Sopenharmony_ci for (l = 0; l < 4; ++l) { 139bf215546Sopenharmony_ci Value *bar = bld.getSSA(4, FILE_BARRIER); 140bf215546Sopenharmony_ci Value *src[3], *val; 141bf215546Sopenharmony_ci Value *lane = bld.mkImm(l); 142bf215546Sopenharmony_ci bld.mkOp(OP_QUADON, TYPE_U32, bar); 143bf215546Sopenharmony_ci // Make sure lane 0 has the appropriate array/depth compare values 144bf215546Sopenharmony_ci if (l != 0) { 145bf215546Sopenharmony_ci if (array) 146bf215546Sopenharmony_ci bld.mkOp3(OP_SHFL, TYPE_F32, arr, i->getSrc(0), lane, quad); 147bf215546Sopenharmony_ci if (i->tex.target.isShadow()) 148bf215546Sopenharmony_ci bld.mkOp3(OP_SHFL, TYPE_F32, shadow, i->getSrc(array + dim + indirect), lane, quad); 149bf215546Sopenharmony_ci } 150bf215546Sopenharmony_ci 151bf215546Sopenharmony_ci // mov coordinates from lane l to all lanes 152bf215546Sopenharmony_ci for (c = 0; c < dim; ++c) { 153bf215546Sopenharmony_ci bld.mkOp3(OP_SHFL, TYPE_F32, crd[c], i->getSrc(c + array), lane, quad); 154bf215546Sopenharmony_ci } 155bf215546Sopenharmony_ci 156bf215546Sopenharmony_ci // add dPdx from lane l to lanes dx 157bf215546Sopenharmony_ci for (c = 0; c < dim; ++c) { 158bf215546Sopenharmony_ci bld.mkOp3(OP_SHFL, TYPE_F32, tmp, i->dPdx[c].get(), lane, quad); 159bf215546Sopenharmony_ci add = bld.mkOp2(OP_QUADOP, TYPE_F32, crd[c], tmp, crd[c]); 160bf215546Sopenharmony_ci add->subOp = qOps[0]; 161bf215546Sopenharmony_ci add->lanes = 1; /* abused for .ndv */ 162bf215546Sopenharmony_ci } 163bf215546Sopenharmony_ci 164bf215546Sopenharmony_ci // add dPdy from lane l to lanes dy 165bf215546Sopenharmony_ci for (c = 0; c < dim; ++c) { 166bf215546Sopenharmony_ci bld.mkOp3(OP_SHFL, TYPE_F32, tmp, i->dPdy[c].get(), lane, quad); 167bf215546Sopenharmony_ci add = bld.mkOp2(OP_QUADOP, TYPE_F32, crd[c], tmp, crd[c]); 168bf215546Sopenharmony_ci add->subOp = qOps[1]; 169bf215546Sopenharmony_ci add->lanes = 1; /* abused for .ndv */ 170bf215546Sopenharmony_ci } 171bf215546Sopenharmony_ci 172bf215546Sopenharmony_ci // normalize cube coordinates if necessary 173bf215546Sopenharmony_ci if (i->tex.target.isCube()) { 174bf215546Sopenharmony_ci for (c = 0; c < 3; ++c) 175bf215546Sopenharmony_ci src[c] = bld.mkOp1v(OP_ABS, TYPE_F32, bld.getSSA(), crd[c]); 176bf215546Sopenharmony_ci val = bld.getScratch(); 177bf215546Sopenharmony_ci bld.mkOp2(OP_MAX, TYPE_F32, val, src[0], src[1]); 178bf215546Sopenharmony_ci bld.mkOp2(OP_MAX, TYPE_F32, val, src[2], val); 179bf215546Sopenharmony_ci bld.mkOp1(OP_RCP, TYPE_F32, val, val); 180bf215546Sopenharmony_ci for (c = 0; c < 3; ++c) 181bf215546Sopenharmony_ci src[c] = bld.mkOp2v(OP_MUL, TYPE_F32, bld.getSSA(), crd[c], val); 182bf215546Sopenharmony_ci } else { 183bf215546Sopenharmony_ci for (c = 0; c < dim; ++c) 184bf215546Sopenharmony_ci src[c] = crd[c]; 185bf215546Sopenharmony_ci } 186bf215546Sopenharmony_ci 187bf215546Sopenharmony_ci // texture 188bf215546Sopenharmony_ci bld.insert(tex = cloneForward(func, i)); 189bf215546Sopenharmony_ci if (l != 0) { 190bf215546Sopenharmony_ci if (array) 191bf215546Sopenharmony_ci tex->setSrc(0, arr); 192bf215546Sopenharmony_ci if (i->tex.target.isShadow()) 193bf215546Sopenharmony_ci tex->setSrc(array + dim + indirect, shadow); 194bf215546Sopenharmony_ci } 195bf215546Sopenharmony_ci for (c = 0; c < dim; ++c) 196bf215546Sopenharmony_ci tex->setSrc(c + array, src[c]); 197bf215546Sopenharmony_ci // broadcast results from lane 0 to all lanes 198bf215546Sopenharmony_ci if (l != 0) 199bf215546Sopenharmony_ci for (c = 0; i->defExists(c); ++c) 200bf215546Sopenharmony_ci bld.mkOp3(OP_SHFL, TYPE_F32, tex->getDef(c), tex->getDef(c), bld.mkImm(0), quad); 201bf215546Sopenharmony_ci bld.mkOp1(OP_QUADPOP, TYPE_U32, NULL, bar)->fixed = 1; 202bf215546Sopenharmony_ci 203bf215546Sopenharmony_ci // save results 204bf215546Sopenharmony_ci for (c = 0; i->defExists(c); ++c) { 205bf215546Sopenharmony_ci Instruction *mov; 206bf215546Sopenharmony_ci def[c][l] = bld.getSSA(); 207bf215546Sopenharmony_ci mov = bld.mkMov(def[c][l], tex->getDef(c)); 208bf215546Sopenharmony_ci mov->fixed = 1; 209bf215546Sopenharmony_ci mov->lanes = 1 << l; 210bf215546Sopenharmony_ci } 211bf215546Sopenharmony_ci } 212bf215546Sopenharmony_ci 213bf215546Sopenharmony_ci for (c = 0; i->defExists(c); ++c) { 214bf215546Sopenharmony_ci Instruction *u = bld.mkOp(OP_UNION, TYPE_U32, i->getDef(c)); 215bf215546Sopenharmony_ci for (l = 0; l < 4; ++l) 216bf215546Sopenharmony_ci u->setSrc(l, def[c][l]); 217bf215546Sopenharmony_ci } 218bf215546Sopenharmony_ci 219bf215546Sopenharmony_ci i->bb->remove(i); 220bf215546Sopenharmony_ci return true; 221bf215546Sopenharmony_ci} 222bf215546Sopenharmony_ci 223bf215546Sopenharmony_cibool 224bf215546Sopenharmony_ciGM107LoweringPass::handleDFDX(Instruction *insn) 225bf215546Sopenharmony_ci{ 226bf215546Sopenharmony_ci Instruction *shfl; 227bf215546Sopenharmony_ci int qop = 0, xid = 0; 228bf215546Sopenharmony_ci 229bf215546Sopenharmony_ci switch (insn->op) { 230bf215546Sopenharmony_ci case OP_DFDX: 231bf215546Sopenharmony_ci qop = QUADOP(SUB, SUBR, SUB, SUBR); 232bf215546Sopenharmony_ci xid = 1; 233bf215546Sopenharmony_ci break; 234bf215546Sopenharmony_ci case OP_DFDY: 235bf215546Sopenharmony_ci qop = QUADOP(SUB, SUB, SUBR, SUBR); 236bf215546Sopenharmony_ci xid = 2; 237bf215546Sopenharmony_ci break; 238bf215546Sopenharmony_ci default: 239bf215546Sopenharmony_ci assert(!"invalid dfdx opcode"); 240bf215546Sopenharmony_ci break; 241bf215546Sopenharmony_ci } 242bf215546Sopenharmony_ci 243bf215546Sopenharmony_ci shfl = bld.mkOp3(OP_SHFL, TYPE_F32, bld.getScratch(), insn->getSrc(0), 244bf215546Sopenharmony_ci bld.mkImm(xid), bld.mkImm(SHFL_BOUND_QUAD)); 245bf215546Sopenharmony_ci shfl->subOp = NV50_IR_SUBOP_SHFL_BFLY; 246bf215546Sopenharmony_ci insn->op = OP_QUADOP; 247bf215546Sopenharmony_ci insn->subOp = qop; 248bf215546Sopenharmony_ci insn->lanes = 0; /* abused for !.ndv */ 249bf215546Sopenharmony_ci insn->setSrc(1, insn->getSrc(0)); 250bf215546Sopenharmony_ci insn->setSrc(0, shfl->getDef(0)); 251bf215546Sopenharmony_ci return true; 252bf215546Sopenharmony_ci} 253bf215546Sopenharmony_ci 254bf215546Sopenharmony_cibool 255bf215546Sopenharmony_ciGM107LoweringPass::handlePFETCH(Instruction *i) 256bf215546Sopenharmony_ci{ 257bf215546Sopenharmony_ci Value *tmp0 = bld.getScratch(); 258bf215546Sopenharmony_ci Value *tmp1 = bld.getScratch(); 259bf215546Sopenharmony_ci Value *tmp2 = bld.getScratch(); 260bf215546Sopenharmony_ci bld.mkOp1(OP_RDSV, TYPE_U32, tmp0, bld.mkSysVal(SV_INVOCATION_INFO, 0)); 261bf215546Sopenharmony_ci bld.mkOp3(OP_PERMT, TYPE_U32, tmp1, tmp0, bld.mkImm(0x4442), bld.mkImm(0)); 262bf215546Sopenharmony_ci bld.mkOp3(OP_PERMT, TYPE_U32, tmp0, tmp0, bld.mkImm(0x4440), bld.mkImm(0)); 263bf215546Sopenharmony_ci if (i->getSrc(1)) 264bf215546Sopenharmony_ci bld.mkOp2(OP_ADD , TYPE_U32, tmp2, i->getSrc(0), i->getSrc(1)); 265bf215546Sopenharmony_ci else 266bf215546Sopenharmony_ci bld.mkOp1(OP_MOV , TYPE_U32, tmp2, i->getSrc(0)); 267bf215546Sopenharmony_ci bld.mkOp3(OP_MAD , TYPE_U32, tmp0, tmp0, tmp1, tmp2); 268bf215546Sopenharmony_ci i->setSrc(0, tmp0); 269bf215546Sopenharmony_ci i->setSrc(1, NULL); 270bf215546Sopenharmony_ci return true; 271bf215546Sopenharmony_ci} 272bf215546Sopenharmony_ci 273bf215546Sopenharmony_cibool 274bf215546Sopenharmony_ciGM107LoweringPass::handlePOPCNT(Instruction *i) 275bf215546Sopenharmony_ci{ 276bf215546Sopenharmony_ci Value *tmp = bld.mkOp2v(OP_AND, i->sType, bld.getScratch(), 277bf215546Sopenharmony_ci i->getSrc(0), i->getSrc(1)); 278bf215546Sopenharmony_ci i->setSrc(0, tmp); 279bf215546Sopenharmony_ci i->setSrc(1, NULL); 280bf215546Sopenharmony_ci return true; 281bf215546Sopenharmony_ci} 282bf215546Sopenharmony_ci 283bf215546Sopenharmony_cibool 284bf215546Sopenharmony_ciGM107LoweringPass::handleSUQ(TexInstruction *suq) 285bf215546Sopenharmony_ci{ 286bf215546Sopenharmony_ci Value *ind = suq->getIndirectR(); 287bf215546Sopenharmony_ci Value *handle; 288bf215546Sopenharmony_ci const int slot = suq->tex.r; 289bf215546Sopenharmony_ci const int mask = suq->tex.mask; 290bf215546Sopenharmony_ci 291bf215546Sopenharmony_ci if (suq->tex.bindless) 292bf215546Sopenharmony_ci handle = ind; 293bf215546Sopenharmony_ci else 294bf215546Sopenharmony_ci handle = loadTexHandle(ind, slot + 32); 295bf215546Sopenharmony_ci 296bf215546Sopenharmony_ci suq->tex.r = 0xff; 297bf215546Sopenharmony_ci suq->tex.s = 0x1f; 298bf215546Sopenharmony_ci 299bf215546Sopenharmony_ci suq->setIndirectR(NULL); 300bf215546Sopenharmony_ci suq->setSrc(0, handle); 301bf215546Sopenharmony_ci suq->tex.rIndirectSrc = 0; 302bf215546Sopenharmony_ci suq->setSrc(1, bld.loadImm(NULL, 0)); 303bf215546Sopenharmony_ci suq->tex.query = TXQ_DIMS; 304bf215546Sopenharmony_ci suq->op = OP_TXQ; 305bf215546Sopenharmony_ci 306bf215546Sopenharmony_ci // We store CUBE / CUBE_ARRAY as a 2D ARRAY. Make sure that depth gets 307bf215546Sopenharmony_ci // divided by 6. 308bf215546Sopenharmony_ci if (mask & 0x4 && suq->tex.target.isCube()) { 309bf215546Sopenharmony_ci int d = util_bitcount(mask & 0x3); 310bf215546Sopenharmony_ci bld.setPosition(suq, true); 311bf215546Sopenharmony_ci bld.mkOp2(OP_DIV, TYPE_U32, suq->getDef(d), suq->getDef(d), 312bf215546Sopenharmony_ci bld.loadImm(NULL, 6)); 313bf215546Sopenharmony_ci } 314bf215546Sopenharmony_ci 315bf215546Sopenharmony_ci // Samples come from a different query. If we want both samples and dims, 316bf215546Sopenharmony_ci // create a second suq. 317bf215546Sopenharmony_ci if (mask & 0x8) { 318bf215546Sopenharmony_ci int d = util_bitcount(mask & 0x7); 319bf215546Sopenharmony_ci Value *dst = suq->getDef(d); 320bf215546Sopenharmony_ci TexInstruction *samples = suq; 321bf215546Sopenharmony_ci assert(dst); 322bf215546Sopenharmony_ci 323bf215546Sopenharmony_ci if (mask != 0x8) { 324bf215546Sopenharmony_ci suq->setDef(d, NULL); 325bf215546Sopenharmony_ci suq->tex.mask &= 0x7; 326bf215546Sopenharmony_ci samples = cloneShallow(func, suq); 327bf215546Sopenharmony_ci for (int i = 0; i < d; i++) 328bf215546Sopenharmony_ci samples->setDef(d, NULL); 329bf215546Sopenharmony_ci samples->setDef(0, dst); 330bf215546Sopenharmony_ci suq->bb->insertAfter(suq, samples); 331bf215546Sopenharmony_ci } 332bf215546Sopenharmony_ci samples->tex.mask = 0x4; 333bf215546Sopenharmony_ci samples->tex.query = TXQ_TYPE; 334bf215546Sopenharmony_ci } 335bf215546Sopenharmony_ci 336bf215546Sopenharmony_ci if (suq->tex.target.isMS()) { 337bf215546Sopenharmony_ci bld.setPosition(suq, true); 338bf215546Sopenharmony_ci 339bf215546Sopenharmony_ci if (mask & 0x1) 340bf215546Sopenharmony_ci bld.mkOp2(OP_SHR, TYPE_U32, suq->getDef(0), suq->getDef(0), 341bf215546Sopenharmony_ci loadMsAdjInfo32(suq->tex.target, 0, slot, ind, suq->tex.bindless)); 342bf215546Sopenharmony_ci if (mask & 0x2) { 343bf215546Sopenharmony_ci int d = util_bitcount(mask & 0x1); 344bf215546Sopenharmony_ci bld.mkOp2(OP_SHR, TYPE_U32, suq->getDef(d), suq->getDef(d), 345bf215546Sopenharmony_ci loadMsAdjInfo32(suq->tex.target, 1, slot, ind, suq->tex.bindless)); 346bf215546Sopenharmony_ci } 347bf215546Sopenharmony_ci } 348bf215546Sopenharmony_ci 349bf215546Sopenharmony_ci return true; 350bf215546Sopenharmony_ci} 351bf215546Sopenharmony_ci 352bf215546Sopenharmony_ci// 353bf215546Sopenharmony_ci// - add quadop dance for texturing 354bf215546Sopenharmony_ci// - put FP outputs in GPRs 355bf215546Sopenharmony_ci// - convert instruction sequences 356bf215546Sopenharmony_ci// 357bf215546Sopenharmony_cibool 358bf215546Sopenharmony_ciGM107LoweringPass::visit(Instruction *i) 359bf215546Sopenharmony_ci{ 360bf215546Sopenharmony_ci bld.setPosition(i, false); 361bf215546Sopenharmony_ci 362bf215546Sopenharmony_ci if (i->cc != CC_ALWAYS) 363bf215546Sopenharmony_ci checkPredicate(i); 364bf215546Sopenharmony_ci 365bf215546Sopenharmony_ci switch (i->op) { 366bf215546Sopenharmony_ci case OP_PFETCH: 367bf215546Sopenharmony_ci return handlePFETCH(i); 368bf215546Sopenharmony_ci case OP_DFDX: 369bf215546Sopenharmony_ci case OP_DFDY: 370bf215546Sopenharmony_ci return handleDFDX(i); 371bf215546Sopenharmony_ci case OP_POPCNT: 372bf215546Sopenharmony_ci return handlePOPCNT(i); 373bf215546Sopenharmony_ci case OP_SUQ: 374bf215546Sopenharmony_ci return handleSUQ(i->asTex()); 375bf215546Sopenharmony_ci default: 376bf215546Sopenharmony_ci return NVC0LoweringPass::visit(i); 377bf215546Sopenharmony_ci } 378bf215546Sopenharmony_ci} 379bf215546Sopenharmony_ci 380bf215546Sopenharmony_ci} // namespace nv50_ir 381