• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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