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 "codegen/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 emitGPR(int pos,const Value * val,int off)231 inline void emitGPR(int pos, const Value *val, int off) { 232 emitField(pos, 8, val && !val->inFile(FILE_FLAGS) ? 233 val->reg.data.id + off: 255); 234 } 235 emitGPR(int pos,const Value * v)236 inline void emitGPR(int pos, const Value *v) { 237 emitGPR(pos, v, 0); 238 } 239 emitGPR(int pos)240 inline void emitGPR(int pos) { 241 emitGPR(pos, (const Value *)NULL); 242 } 243 emitGPR(int pos,const ValueRef & ref)244 inline void emitGPR(int pos, const ValueRef &ref) { 245 emitGPR(pos, ref.get() ? ref.rep() : (const Value *)NULL); 246 } 247 emitGPR(int pos,const ValueRef * ref)248 inline void emitGPR(int pos, const ValueRef *ref) { 249 emitGPR(pos, ref ? ref->rep() : (const Value *)NULL); 250 } 251 emitGPR(int pos,const ValueDef & def)252 inline void emitGPR(int pos, const ValueDef &def) { 253 emitGPR(pos, def.get() ? def.rep() : (const Value *)NULL); 254 } 255 emitGPR(int pos,const ValueDef & def,int off)256 inline void emitGPR(int pos, const ValueDef &def, int off) { 257 emitGPR(pos, def.get() ? def.rep() : (const Value *)NULL, off); 258 } 259 emitPRED(int pos,const Value * val)260 inline void emitPRED(int pos, const Value *val) { 261 emitField(pos, 3, val ? val->reg.data.id : 7); 262 }; 263 emitPRED(int pos)264 inline void emitPRED(int pos) { 265 emitPRED(pos, (const Value *)NULL); 266 } 267 emitPRED(int pos,const ValueRef & ref)268 inline void emitPRED(int pos, const ValueRef &ref) { 269 emitPRED(pos, ref.get() ? ref.rep() : (const Value *)NULL); 270 } 271 emitPRED(int pos,const ValueDef & def)272 inline void emitPRED(int pos, const ValueDef &def) { 273 emitPRED(pos, def.get() ? def.rep() : (const Value *)NULL); 274 } 275 emitCBUF(int buf,int gpr,int off,int len,int align,const ValueRef & ref)276 inline void emitCBUF(int buf, int gpr, int off, int len, int align, 277 const ValueRef &ref) { 278 const Value *v = ref.get(); 279 const Symbol *s = v->asSym(); 280 281 assert(!(s->reg.data.offset & ((1 << align) - 1))); 282 283 emitField(buf, 5, v->reg.fileIndex); 284 if (gpr >= 0) 285 emitGPR(gpr, ref.getIndirect(0)); 286 emitField(off, 16, s->reg.data.offset); 287 } 288 emitIMMD(int pos,int len,const ValueRef & ref)289 inline void emitIMMD(int pos, int len, const ValueRef &ref) { 290 const ImmediateValue *imm = ref.get()->asImm(); 291 uint32_t val = imm->reg.data.u32; 292 293 if (insn->sType == TYPE_F64) { 294 assert(!(imm->reg.data.u64 & 0x00000000ffffffffULL)); 295 val = imm->reg.data.u64 >> 32; 296 } 297 298 emitField(pos, len, val); 299 } 300 emitADDR(int gpr,int off,int len,int shr,const ValueRef & ref)301 inline void emitADDR(int gpr, int off, int len, int shr, 302 const ValueRef &ref) { 303 const Value *v = ref.get(); 304 assert(!(v->reg.data.offset & ((1 << shr) - 1))); 305 if (gpr >= 0) 306 emitGPR(gpr, ref.getIndirect(0)); 307 emitField(off, len, v->reg.data.offset >> shr); 308 } 309 310 inline void emitFormA(uint16_t op, uint8_t forms, int src0, int src1, int src2); 311 inline void emitFormA_RRR(uint16_t op, int src1, int src2); 312 inline void emitFormA_RRI(uint16_t op, int src1, int src2); 313 inline void emitFormA_RRC(uint16_t op, int src1, int src2); 314 inline void emitFormA_I32(int src); 315 316 void emitBRA(); 317 void emitEXIT(); 318 void emitKILL(); 319 void emitNOP(); 320 void emitWARPSYNC(); 321 322 void emitCS2R(); 323 void emitF2F(); 324 void emitF2I(); 325 void emitFRND(); 326 void emitI2F(); 327 void emitMOV(); 328 void emitPRMT(); 329 void emitS2R(); 330 void emitSEL(); 331 void emitSHFL(); 332 333 void emitFADD(); 334 void emitFFMA(); 335 void emitFMNMX(); 336 void emitFMUL(); 337 void emitFSET_BF(); 338 void emitFSETP(); 339 void emitFSWZADD(); 340 void emitMUFU(); 341 342 void emitDADD(); 343 void emitDFMA(); 344 void emitDMUL(); 345 void emitDSETP(); 346 347 void emitBMSK(); 348 void emitBREV(); 349 void emitFLO(); 350 void emitIABS(); 351 void emitIADD3(); 352 void emitIMAD(); 353 void emitIMAD_WIDE(); 354 void emitISETP(); 355 void emitLEA(); 356 void emitLOP3_LUT(); 357 void emitPOPC(); 358 void emitSGXT(); 359 void emitSHF(); 360 361 void emitALD(); 362 void emitAST(); 363 void emitATOM(); 364 void emitATOMS(); 365 void emitIPA(); 366 void emitISBERD(); 367 void emitLDSTc(int, int); 368 void emitLDSTs(int, DataType); 369 void emitLD(); 370 void emitLDC(); 371 void emitLDL(); 372 void emitLDS(); 373 void emitOUT(); 374 void emitRED(); 375 void emitST(); 376 void emitSTL(); 377 void emitSTS(); 378 379 void emitTEXs(int); 380 void emitTEX(); 381 void emitTLD(); 382 void emitTLD4(); 383 void emitTMML(); 384 void emitTXD(); 385 void emitTXQ(); 386 387 void emitSUHandle(const int); 388 void emitSUTarget(); 389 void emitSUATOM(); 390 void emitSULD(); 391 void emitSUST(); 392 393 void emitAL2P(); 394 void emitBAR(); 395 void emitCCTL(); 396 void emitMEMBAR(); 397 void emitPIXLD(); 398 void emitPLOP3_LUT(); 399 void emitVOTE(); 400 }; 401 402 }; 403 #endif 404