1 /* 2 * Copyright 2020 Red Hat Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 */ 22 #ifndef __NV50_IR_EMIT_GV100_H__ 23 #define __NV50_IR_EMIT_GV100_H__ 24 #include "nv50_ir_target_gv100.h" 25 26 namespace nv50_ir { 27 28 class CodeEmitterGV100 : public CodeEmitter { 29 public: 30 CodeEmitterGV100(TargetGV100 *target); 31 32 virtual bool emitInstruction(Instruction *); getMinEncodingSize(const Instruction *)33 virtual uint32_t getMinEncodingSize(const Instruction *) const { return 16; } 34 35 private: 36 const Program *prog; 37 const TargetGV100 *targ; 38 const Instruction *insn; 39 40 virtual void prepareEmission(Program *); 41 virtual void prepareEmission(Function *); 42 virtual void prepareEmission(BasicBlock *); 43 emitInsn(uint32_t op)44 inline void emitInsn(uint32_t op) { 45 code[0] = op; 46 code[1] = 0; 47 code[2] = 0; 48 code[3] = 0; 49 if (insn->predSrc >= 0) { 50 emitField(12, 3, insn->getSrc(insn->predSrc)->rep()->reg.data.id); 51 emitField(15, 1, insn->cc == CC_NOT_P); 52 } else { 53 emitField(12, 3, 7); 54 } 55 }; 56 emitField(int b,int s,uint64_t v)57 inline void emitField(int b, int s, uint64_t v) { 58 if (b >= 0) { 59 uint64_t m = ~0ULL >> (64 - s); 60 uint64_t d = v & m; 61 assert(!(v & ~m) || (v & ~m) == ~m); 62 if (b < 64 && b + s > 64) { 63 *(uint64_t *)&code[0] |= d << b; 64 *(uint64_t *)&code[2] |= d >> (64 - b); 65 } else { 66 *(uint64_t *)&code[(b/64*2)] |= d << (b & 0x3f); 67 } 68 } 69 }; 70 emitABS(int pos,int src,bool supported)71 inline void emitABS(int pos, int src, bool supported) 72 { 73 if (insn->src(src).mod.abs()) { 74 assert(supported); 75 emitField(pos, 1, 1); 76 } 77 } 78 emitABS(int pos,int src)79 inline void emitABS(int pos, int src) 80 { 81 emitABS(pos, src, true); 82 } 83 emitNEG(int pos,int src,bool supported)84 inline void emitNEG(int pos, int src, bool supported) { 85 if (insn->src(src).mod.neg()) { 86 assert(supported); 87 emitField(pos, 1, 1); 88 } 89 } 90 emitNEG(int pos,int src)91 inline void emitNEG(int pos, int src) { 92 emitNEG(pos, src, true); 93 } 94 emitNOT(int pos)95 inline void emitNOT(int pos) { 96 emitField(pos, 1, 0); 97 }; 98 emitNOT(int pos,const ValueRef & ref)99 inline void emitNOT(int pos, const ValueRef &ref) { 100 emitField(pos, 1, !!(ref.mod & Modifier(NV50_IR_MOD_NOT))); 101 } 102 emitSAT(int pos)103 inline void emitSAT(int pos) { 104 emitField(pos, 1, insn->saturate); 105 } 106 emitRND(int rmp,RoundMode rnd,int rip)107 inline void emitRND(int rmp, RoundMode rnd, int rip) { 108 int rm = 0, ri = 0; 109 switch (rnd) { 110 case ROUND_NI: ri = 1; 111 case ROUND_N : rm = 0; break; 112 case ROUND_MI: ri = 1; 113 case ROUND_M : rm = 1; break; 114 case ROUND_PI: ri = 1; 115 case ROUND_P : rm = 2; break; 116 case ROUND_ZI: ri = 1; 117 case ROUND_Z : rm = 3; break; 118 default: 119 assert(!"invalid round mode"); 120 break; 121 } 122 emitField(rip, 1, ri); 123 emitField(rmp, 2, rm); 124 } 125 emitRND(int pos)126 inline void emitRND(int pos) { 127 emitRND(pos, insn->rnd, -1); 128 } 129 emitFMZ(int pos,int len)130 inline void emitFMZ(int pos, int len) { 131 emitField(pos, len, insn->dnz << 1 | insn->ftz); 132 } 133 emitPDIV(int pos)134 inline void emitPDIV(int pos) { 135 emitField(pos, 3, insn->postFactor + 4); 136 } 137 emitO(int pos)138 inline void emitO(int pos) { 139 emitField(pos, 1, insn->getSrc(0)->reg.file == FILE_SHADER_OUTPUT); 140 } 141 emitP(int pos)142 inline void emitP(int pos) { 143 emitField(pos, 1, insn->perPatch); 144 } 145 emitCond3(int pos,CondCode code)146 inline void emitCond3(int pos, CondCode code) { 147 int data = 0; 148 149 switch (code) { 150 case CC_FL : data = 0x00; break; 151 case CC_LTU: 152 case CC_LT : data = 0x01; break; 153 case CC_EQU: 154 case CC_EQ : data = 0x02; break; 155 case CC_LEU: 156 case CC_LE : data = 0x03; break; 157 case CC_GTU: 158 case CC_GT : data = 0x04; break; 159 case CC_NEU: 160 case CC_NE : data = 0x05; break; 161 case CC_GEU: 162 case CC_GE : data = 0x06; break; 163 case CC_TR : data = 0x07; break; 164 default: 165 assert(!"invalid cond3"); 166 break; 167 } 168 169 emitField(pos, 3, data); 170 } 171 emitCond4(int pos,CondCode code)172 inline void emitCond4(int pos, CondCode code) { 173 int data = 0; 174 175 switch (code) { 176 case CC_FL: data = 0x00; break; 177 case CC_LT: data = 0x01; break; 178 case CC_EQ: data = 0x02; break; 179 case CC_LE: data = 0x03; break; 180 case CC_GT: data = 0x04; break; 181 case CC_NE: data = 0x05; break; 182 case CC_GE: data = 0x06; break; 183 // case CC_NUM: data = 0x07; break; 184 // case CC_NAN: data = 0x08; break; 185 case CC_LTU: data = 0x09; break; 186 case CC_EQU: data = 0x0a; break; 187 case CC_LEU: data = 0x0b; break; 188 case CC_GTU: data = 0x0c; break; 189 case CC_NEU: data = 0x0d; break; 190 case CC_GEU: data = 0x0e; break; 191 case CC_TR: data = 0x0f; break; 192 default: 193 assert(!"invalid cond4"); 194 break; 195 } 196 197 emitField(pos, 4, data); 198 } 199 emitSYS(int pos,const Value * val)200 inline void emitSYS(int pos, const Value *val) { 201 int id = val ? val->reg.data.id : -1; 202 203 switch (id) { 204 case SV_LANEID : id = 0x00; break; 205 case SV_VERTEX_COUNT : id = 0x10; break; 206 case SV_INVOCATION_ID : id = 0x11; break; 207 case SV_THREAD_KILL : id = 0x13; break; 208 case SV_INVOCATION_INFO: id = 0x1d; break; 209 case SV_COMBINED_TID : id = 0x20; break; 210 case SV_TID : id = 0x21 + val->reg.data.sv.index; break; 211 case SV_CTAID : id = 0x25 + val->reg.data.sv.index; break; 212 case SV_LANEMASK_EQ : id = 0x38; break; 213 case SV_LANEMASK_LT : id = 0x39; break; 214 case SV_LANEMASK_LE : id = 0x3a; break; 215 case SV_LANEMASK_GT : id = 0x3b; break; 216 case SV_LANEMASK_GE : id = 0x3c; break; 217 case SV_CLOCK : id = 0x50 + val->reg.data.sv.index; break; 218 default: 219 assert(!"invalid system value"); 220 id = 0; 221 break; 222 } 223 224 emitField(pos, 8, id); 225 } 226 emitSYS(int pos,const ValueRef & ref)227 inline void emitSYS(int pos, const ValueRef &ref) { 228 emitSYS(pos, ref.get() ? ref.rep() : (const Value *)NULL); 229 } 230 emitBTS(int pos,const Value * val)231 inline void emitBTS(int pos, const Value *val) { 232 if (val->inFile(FILE_THREAD_STATE)) { 233 TSSemantic ts = val->reg.data.ts == TS_PQUAD_MACTIVE ? TS_MACTIVE : val->reg.data.ts; 234 emitField(pos, 5, ts | 0x10); 235 } else { 236 emitField(pos, 5, val->reg.data.id); 237 } 238 } 239 emitBTS(int pos,const ValueRef & ref)240 inline void emitBTS(int pos, const ValueRef &ref) { 241 emitBTS(pos, ref.get() ? ref.rep() : (const Value *)NULL); 242 } 243 emitBTS(int pos,const ValueDef & def)244 inline void emitBTS(int pos, const ValueDef &def) { 245 emitBTS(pos, def.get() ? def.rep() : (const Value *)NULL); 246 } 247 emitGPR(int pos,const Value * val,int off)248 inline void emitGPR(int pos, const Value *val, int off) { 249 emitField(pos, 8, val && !val->inFile(FILE_FLAGS) ? 250 val->reg.data.id + off: 255); 251 } 252 emitGPR(int pos,const Value * v)253 inline void emitGPR(int pos, const Value *v) { 254 emitGPR(pos, v, 0); 255 } 256 emitGPR(int pos)257 inline void emitGPR(int pos) { 258 emitGPR(pos, (const Value *)NULL); 259 } 260 emitGPR(int pos,const ValueRef & ref)261 inline void emitGPR(int pos, const ValueRef &ref) { 262 emitGPR(pos, ref.get() ? ref.rep() : (const Value *)NULL); 263 } 264 emitGPR(int pos,const ValueRef * ref)265 inline void emitGPR(int pos, const ValueRef *ref) { 266 emitGPR(pos, ref ? ref->rep() : (const Value *)NULL); 267 } 268 emitGPR(int pos,const ValueDef & def)269 inline void emitGPR(int pos, const ValueDef &def) { 270 emitGPR(pos, def.get() ? def.rep() : (const Value *)NULL); 271 } 272 emitGPR(int pos,const ValueDef & def,int off)273 inline void emitGPR(int pos, const ValueDef &def, int off) { 274 emitGPR(pos, def.get() ? def.rep() : (const Value *)NULL, off); 275 } 276 emitPRED(int pos,const Value * val)277 inline void emitPRED(int pos, const Value *val) { 278 emitField(pos, 3, val ? val->reg.data.id : 7); 279 }; 280 emitPRED(int pos)281 inline void emitPRED(int pos) { 282 emitPRED(pos, (const Value *)NULL); 283 } 284 emitPRED(int pos,const ValueRef & ref)285 inline void emitPRED(int pos, const ValueRef &ref) { 286 emitPRED(pos, ref.get() ? ref.rep() : (const Value *)NULL); 287 } 288 emitPRED(int pos,const ValueDef & def)289 inline void emitPRED(int pos, const ValueDef &def) { 290 emitPRED(pos, def.get() ? def.rep() : (const Value *)NULL); 291 } 292 emitCBUF(int buf,int gpr,int off,int len,int align,const ValueRef & ref)293 inline void emitCBUF(int buf, int gpr, int off, int len, int align, 294 const ValueRef &ref) { 295 const Value *v = ref.get(); 296 const Symbol *s = v->asSym(); 297 298 assert(!(s->reg.data.offset & ((1 << align) - 1))); 299 300 emitField(buf, 5, v->reg.fileIndex); 301 if (gpr >= 0) 302 emitGPR(gpr, ref.getIndirect(0)); 303 emitField(off, 16, s->reg.data.offset); 304 } 305 emitIMMD(int pos,int len,const ValueRef & ref)306 inline void emitIMMD(int pos, int len, const ValueRef &ref) { 307 const ImmediateValue *imm = ref.get()->asImm(); 308 uint32_t val = imm->reg.data.u32; 309 310 if (insn->sType == TYPE_F64) { 311 assert(!(imm->reg.data.u64 & 0x00000000ffffffffULL)); 312 val = imm->reg.data.u64 >> 32; 313 } 314 315 emitField(pos, len, val); 316 } 317 emitADDR(int gpr,int off,int len,int shr,const ValueRef & ref)318 inline void emitADDR(int gpr, int off, int len, int shr, 319 const ValueRef &ref) { 320 const Value *v = ref.get(); 321 assert(!(v->reg.data.offset & ((1 << shr) - 1))); 322 if (gpr >= 0) 323 emitGPR(gpr, ref.getIndirect(0)); 324 emitField(off, len, v->reg.data.offset >> shr); 325 } 326 327 inline void emitFormA(uint16_t op, uint8_t forms, int src0, int src1, int src2); 328 inline void emitFormA_RRR(uint16_t op, int src1, int src2); 329 inline void emitFormA_RRI(uint16_t op, int src1, int src2); 330 inline void emitFormA_RRC(uint16_t op, int src1, int src2); 331 inline void emitFormA_I32(int src); 332 333 void emitBRA(); 334 void emitEXIT(); 335 void emitKILL(); 336 void emitNOP(); 337 void emitWARPSYNC(); 338 339 void emitCS2R(); 340 void emitF2F(); 341 void emitF2I(); 342 void emitFRND(); 343 void emitI2F(); 344 void emitMOV(); 345 void emitPRMT(); 346 void emitS2R(); 347 void emitSEL(); 348 void emitSHFL(); 349 350 void emitFADD(); 351 void emitFFMA(); 352 void emitFMNMX(); 353 void emitFMUL(); 354 void emitFSET_BF(); 355 void emitFSETP(); 356 void emitFSWZADD(); 357 void emitMUFU(); 358 359 void emitDADD(); 360 void emitDFMA(); 361 void emitDMUL(); 362 void emitDSETP(); 363 364 void emitBMSK(); 365 void emitBREV(); 366 void emitFLO(); 367 void emitIABS(); 368 void emitIADD3(); 369 void emitIMAD(); 370 void emitIMAD_WIDE(); 371 void emitISETP(); 372 void emitLEA(); 373 void emitLOP3_LUT(); 374 void emitPOPC(); 375 void emitSGXT(); 376 void emitSHF(); 377 378 void emitALD(); 379 void emitAST(); 380 void emitATOM(); 381 void emitATOMS(); 382 void emitIPA(); 383 void emitISBERD(); 384 void emitLDSTc(int, int); 385 void emitLDSTs(int, DataType); 386 void emitLD(); 387 void emitLDC(); 388 void emitLDL(); 389 void emitLDS(); 390 void emitOUT(); 391 void emitRED(); 392 void emitST(); 393 void emitSTL(); 394 void emitSTS(); 395 396 void emitTEXs(int); 397 void emitTEX(); 398 void emitTLD(); 399 void emitTLD4(); 400 void emitTMML(); 401 void emitTXD(); 402 void emitTXQ(); 403 404 void emitSUHandle(const int); 405 void emitSUTarget(); 406 void emitSUATOM(); 407 void emitSULD(); 408 void emitSUST(); 409 410 void emitAL2P(); 411 void emitBAR(); 412 void emitCCTL(); 413 void emitMEMBAR(); 414 void emitPIXLD(); 415 void emitPLOP3_LUT(); 416 void emitVOTE(); 417 }; 418 419 }; 420 #endif 421