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 #include "codegen/nv50_ir_target_gv100.h"
23 #include "codegen/nv50_ir_lowering_gv100.h"
24 #include "codegen/nv50_ir_emit_gv100.h"
25 
26 namespace nv50_ir {
27 
28 void
initOpInfo()29 TargetGV100::initOpInfo()
30 {
31    unsigned int i, j;
32 
33    static const operation commutative[] =
34    {
35       OP_ADD, OP_MUL, OP_MAD, OP_FMA, OP_MAX, OP_MIN,
36       OP_SET_AND, OP_SET_OR, OP_SET_XOR, OP_SET, OP_SELP, OP_SLCT
37    };
38 
39    static const operation noDest[] =
40    {
41       OP_EXIT
42    };
43 
44    static const operation noPred[] =
45    {
46    };
47 
48    for (i = 0; i < DATA_FILE_COUNT; ++i)
49       nativeFileMap[i] = (DataFile)i;
50    nativeFileMap[FILE_ADDRESS] = FILE_GPR;
51    nativeFileMap[FILE_FLAGS] = FILE_PREDICATE;
52 
53    for (i = 0; i < OP_LAST; ++i) {
54       opInfo[i].variants = NULL;
55       opInfo[i].op = (operation)i;
56       opInfo[i].srcTypes = 1 << (int)TYPE_F32;
57       opInfo[i].dstTypes = 1 << (int)TYPE_F32;
58       opInfo[i].immdBits = 0;
59       opInfo[i].srcNr = operationSrcNr[i];
60 
61       for (j = 0; j < opInfo[i].srcNr; ++j) {
62          opInfo[i].srcMods[j] = 0;
63          opInfo[i].srcFiles[j] = 1 << (int)FILE_GPR;
64       }
65       opInfo[i].dstMods = 0;
66       opInfo[i].dstFiles = 1 << (int)FILE_GPR;
67 
68       opInfo[i].hasDest = 1;
69       opInfo[i].vector = (i >= OP_TEX && i <= OP_TEXCSAA);
70       opInfo[i].commutative = false; /* set below */
71       opInfo[i].pseudo = (i < OP_MOV);
72       opInfo[i].predicate = !opInfo[i].pseudo;
73       opInfo[i].flow = (i >= OP_BRA && i <= OP_JOIN);
74       opInfo[i].minEncSize = 16;
75    }
76    for (i = 0; i < ARRAY_SIZE(commutative); ++i)
77       opInfo[commutative[i]].commutative = true;
78    for (i = 0; i < ARRAY_SIZE(noDest); ++i)
79       opInfo[noDest[i]].hasDest = 0;
80    for (i = 0; i < ARRAY_SIZE(noPred); ++i)
81       opInfo[noPred[i]].predicate = 0;
82 }
83 
84 struct opInfo {
85    struct {
86       uint8_t files;
87       uint8_t mods;
88    } src[3];
89 };
90 
91 #define SRC_NONE 0
92 #define SRC_R    (1 << FILE_GPR)
93 #define SRC_I    (1 << FILE_MEMORY_CONST)
94 #define SRC_C    (1 << FILE_IMMEDIATE)
95 #define SRC_RC   (SRC_R |         SRC_C)
96 #define SRC_RI   (SRC_R | SRC_I        )
97 #define SRC_RIC  (SRC_R | SRC_I | SRC_C)
98 
99 #define MOD_NONE 0
100 #define MOD_NEG  NV50_IR_MOD_NEG
101 #define MOD_ABS  NV50_IR_MOD_ABS
102 #define MOD_NOT  NV50_IR_MOD_NOT
103 #define MOD_NA   (MOD_NEG | MOD_ABS)
104 
105 #define OPINFO(O,SA,MA,SB,MB,SC,MC)                                            \
106 static struct opInfo                                                           \
107 opInfo_##O = {                                                                 \
108    .src = { { SRC_##SA, MOD_##MA },                                            \
109             { SRC_##SB, MOD_##MB },                                            \
110             { SRC_##SC, MOD_##MC }},                                           \
111 };
112 
113 
114 /* Handled by GV100LegalizeSSA. */
115 OPINFO(FABS     , RIC , NA  , NONE, NONE, NONE, NONE);
116 OPINFO(FCMP     , R   , NONE, RIC , NONE, RIC , NONE); //XXX: use FSEL for mods
117 OPINFO(FNEG     , RIC , NA  , NONE, NONE, NONE, NONE);
118 OPINFO(FSET     , R   , NA  , RIC , NA  , NONE, NONE);
119 OPINFO(ICMP     , R   , NONE, RIC , NONE, RIC , NONE);
120 OPINFO(IMUL     , R   , NONE, RIC , NONE, NONE, NONE);
121 OPINFO(INEG     , RIC , NEG , NONE, NONE, NONE, NONE);
122 OPINFO(ISET     , R   , NONE, RIC , NONE, NONE, NONE);
123 OPINFO(LOP2     , R   , NOT , RIC , NOT , NONE, NONE);
124 OPINFO(NOT      , RIC , NONE, NONE, NONE, NONE, NONE);
125 OPINFO(SAT      , RIC , NA  , NONE, NONE, NONE, NONE);
126 OPINFO(SHL      , RIC , NONE, RIC , NONE, NONE, NONE);
127 OPINFO(SHR      , RIC , NONE, RIC , NONE, NONE, NONE);
128 OPINFO(SUB      , R   , NONE, RIC , NEG , NONE, NONE);
129 OPINFO(IMNMX    , R   , NONE, RIC , NONE, NONE, NONE);
130 
131 /* Handled by CodeEmitterGV100. */
132 OPINFO(AL2P     , NONE, NONE, NONE, NONE, NONE, NONE);
133 OPINFO(ALD      , NONE, NONE, NONE, NONE, NONE, NONE);
134 OPINFO(AST      , NONE, NONE, NONE, NONE, NONE, NONE);
135 OPINFO(ATOM     , NONE, NONE, NONE, NONE, NONE, NONE);
136 OPINFO(ATOMS    , NONE, NONE, NONE, NONE, NONE, NONE);
137 OPINFO(BAR      , NONE, NONE, NONE, NONE, NONE, NONE);
138 OPINFO(BRA      , NONE, NONE, NONE, NONE, NONE, NONE);
139 OPINFO(BMSK     , R   , NONE, RIC , NONE, NONE, NONE);
140 OPINFO(BREV     , RIC , NONE, NONE, NONE, NONE, NONE);
141 OPINFO(CCTL     , NONE, NONE, NONE, NONE, NONE, NONE);
142 //OPINFO(CS2R     , NONE, NONE, NONE, NONE, NONE, NONE);
143 OPINFO(DADD     , R   , NA  , RIC , NA  , NONE, NONE);
144 OPINFO(DFMA     , R   , NA  , RIC , NA  , RIC , NA  );
145 OPINFO(DMUL     , R   , NA  , RIC , NA  , NONE, NONE);
146 OPINFO(DSETP    , R   , NA  , RIC , NA  , NONE, NONE);
147 OPINFO(EXIT     , NONE, NONE, NONE, NONE, NONE, NONE);
148 OPINFO(F2F      , RIC , NA  , NONE, NONE, NONE, NONE);
149 OPINFO(F2I      , RIC , NA  , NONE, NONE, NONE, NONE);
150 OPINFO(FADD     , R   , NA  , RIC , NA  , NONE, NONE);
151 OPINFO(FFMA     , R   , NA  , RIC , NA  , RIC , NA  );
152 OPINFO(FLO      , RIC , NOT , NONE, NONE, NONE, NONE);
153 OPINFO(FMNMX    , R   , NA  , RIC , NA  , NONE, NONE);
154 OPINFO(FMUL     , R   , NA  , RIC , NA  , NONE, NONE);
155 OPINFO(FRND     , RIC , NA  , NONE, NONE, NONE, NONE);
156 OPINFO(FSET_BF  , R   , NA  , RIC , NA  , NONE, NONE);
157 OPINFO(FSETP    , R   , NA  , RIC , NA  , NONE, NONE);
158 OPINFO(FSWZADD  , R   , NONE, R   , NONE, NONE, NONE);
159 OPINFO(I2F      , RIC , NONE, NONE, NONE, NONE, NONE);
160 OPINFO(IABS     , RIC , NONE, NONE, NONE, NONE, NONE);
161 OPINFO(IADD3    , R   , NEG , RIC , NEG , R   , NEG );
162 OPINFO(IMAD     , R   , NONE, RIC , NONE, RIC , NEG );
163 OPINFO(IMAD_WIDE, R   , NONE, RIC , NONE, RC  , NEG );
164 OPINFO(IPA      , NONE, NONE, NONE, NONE, NONE, NONE);
165 OPINFO(ISBERD   , NONE, NONE, NONE, NONE, NONE, NONE);
166 OPINFO(ISETP    , R   , NONE, RIC , NONE, NONE, NONE);
167 OPINFO(KILL     , NONE, NONE, NONE, NONE, NONE, NONE);
168 OPINFO(LD       , NONE, NONE, NONE, NONE, NONE, NONE);
169 OPINFO(LDC      , NONE, NONE, NONE, NONE, NONE, NONE);
170 OPINFO(LDL      , NONE, NONE, NONE, NONE, NONE, NONE);
171 OPINFO(LDS      , NONE, NONE, NONE, NONE, NONE, NONE);
172 OPINFO(LEA      , R   , NEG , I   , NONE, RIC , NEG );
173 OPINFO(LOP3_LUT , R   , NONE, RIC , NONE, R   , NONE);
174 OPINFO(MEMBAR   , NONE, NONE, NONE, NONE, NONE, NONE);
175 OPINFO(MOV      , RIC , NONE, NONE, NONE, NONE, NONE);
176 OPINFO(MUFU     , RIC , NA  , NONE, NONE, NONE, NONE);
177 OPINFO(NOP      , NONE, NONE, NONE, NONE, NONE, NONE);
178 OPINFO(OUT      , R   , NONE, RI  , NONE, NONE, NONE);
179 OPINFO(PIXLD    , NONE, NONE, NONE, NONE, NONE, NONE);
180 OPINFO(PLOP3_LUT, NONE, NONE, NONE, NONE, NONE, NONE);
181 OPINFO(POPC     , RIC , NOT , NONE, NONE, NONE, NONE);
182 OPINFO(PRMT     , R   , NONE, RIC , NONE, RIC , NONE);
183 OPINFO(RED      , NONE, NONE, NONE, NONE, NONE, NONE);
184 OPINFO(SGXT     , R   , NONE, RIC , NONE, NONE, NONE);
185 OPINFO(S2R      , NONE, NONE, NONE, NONE, NONE, NONE);
186 OPINFO(SEL      , R   , NONE, RIC , NONE, NONE, NONE);
187 OPINFO(SHF      , R   , NONE, RIC , NONE, RIC , NONE);
188 OPINFO(SHFL     , R   , NONE, R   , NONE, R   , NONE);
189 OPINFO(ST       , NONE, NONE, NONE, NONE, NONE, NONE);
190 OPINFO(STL      , NONE, NONE, NONE, NONE, NONE, NONE);
191 OPINFO(STS      , NONE, NONE, NONE, NONE, NONE, NONE);
192 OPINFO(SUATOM   , NONE, NONE, NONE, NONE, NONE, NONE);
193 OPINFO(SULD     , NONE, NONE, NONE, NONE, NONE, NONE);
194 OPINFO(SUST     , NONE, NONE, NONE, NONE, NONE, NONE);
195 OPINFO(TEX      , NONE, NONE, NONE, NONE, NONE, NONE);
196 OPINFO(TLD      , NONE, NONE, NONE, NONE, NONE, NONE);
197 OPINFO(TLD4     , NONE, NONE, NONE, NONE, NONE, NONE);
198 OPINFO(TMML     , NONE, NONE, NONE, NONE, NONE, NONE);
199 OPINFO(TXD      , NONE, NONE, NONE, NONE, NONE, NONE);
200 OPINFO(TXQ      , NONE, NONE, NONE, NONE, NONE, NONE);
201 OPINFO(VOTE     , NONE, NONE, NONE, NONE, NONE, NONE);
202 OPINFO(WARPSYNC , R   , NONE, NONE, NONE, NONE, NONE);
203 
204 static const struct opInfo *
getOpInfo(const Instruction * i)205 getOpInfo(const Instruction *i)
206 {
207    switch (i->op) {
208    case OP_ABS:
209       if (isFloatType(i->dType))
210          return &opInfo_FABS;
211       return &opInfo_IABS;
212    case OP_ADD:
213       if (isFloatType(i->dType)) {
214          if (i->dType == TYPE_F32)
215             return &opInfo_FADD;
216          else
217             return &opInfo_DADD;
218       } else {
219          return &opInfo_IADD3;
220       }
221       break;
222    case OP_AFETCH: return &opInfo_AL2P;
223    case OP_AND:
224    case OP_OR:
225    case OP_XOR:
226       if (i->def(0).getFile() == FILE_PREDICATE)
227          return &opInfo_PLOP3_LUT;
228       return &opInfo_LOP2;
229    case OP_ATOM:
230       if (i->src(0).getFile() == FILE_MEMORY_SHARED)
231          return &opInfo_ATOMS;
232       else
233          if (!i->defExists(0) && i->subOp < NV50_IR_SUBOP_ATOM_CAS)
234             return &opInfo_RED;
235          else
236             return &opInfo_ATOM;
237       break;
238    case OP_BAR: return &opInfo_BAR;
239    case OP_BFIND: return &opInfo_FLO;
240    case OP_BMSK: return &opInfo_BMSK;
241    case OP_BREV: return &opInfo_BREV;
242    case OP_BRA:
243    case OP_JOIN: return &opInfo_BRA; //XXX
244    case OP_CCTL: return &opInfo_CCTL;
245    case OP_CEIL:
246    case OP_CVT:
247    case OP_FLOOR:
248    case OP_TRUNC:
249       if (i->op == OP_CVT && (i->def(0).getFile() == FILE_PREDICATE ||
250                                  i->src(0).getFile() == FILE_PREDICATE)) {
251          return &opInfo_MOV;
252       } else if (isFloatType(i->dType)) {
253          if (isFloatType(i->sType)) {
254             if (i->sType == i->dType)
255                return &opInfo_FRND;
256             else
257                return &opInfo_F2F;
258          } else {
259             return &opInfo_I2F;
260          }
261       } else {
262          if (isFloatType(i->sType))
263             return &opInfo_F2I;
264       }
265       break;
266    case OP_COS:
267    case OP_EX2:
268    case OP_LG2:
269    case OP_RCP:
270    case OP_RSQ:
271    case OP_SIN:
272    case OP_SQRT: return &opInfo_MUFU;
273    case OP_DISCARD: return &opInfo_KILL;
274    case OP_EMIT:
275    case OP_FINAL:
276    case OP_RESTART: return &opInfo_OUT;
277    case OP_EXIT: return &opInfo_EXIT;
278    case OP_EXPORT: return &opInfo_AST;
279    case OP_FMA:
280    case OP_MAD:
281       if (isFloatType(i->dType)) {
282          if (i->dType == TYPE_F32)
283             return &opInfo_FFMA;
284          else
285             return &opInfo_DFMA;
286       } else {
287          if (typeSizeof(i->dType) != 8)
288             return &opInfo_IMAD;
289          else
290             return &opInfo_IMAD_WIDE;
291       }
292       break;
293    case OP_JOINAT: return &opInfo_NOP; //XXX
294    case OP_LINTERP: return &opInfo_IPA;
295    case OP_LOAD:
296       switch (i->src(0).getFile()) {
297       case FILE_MEMORY_CONST : return &opInfo_LDC;
298       case FILE_MEMORY_LOCAL : return &opInfo_LDL;
299       case FILE_MEMORY_SHARED: return &opInfo_LDS;
300       case FILE_MEMORY_GLOBAL: return &opInfo_LD;
301       default:
302          break;
303       }
304       break;
305    case OP_LOP3_LUT: return &opInfo_LOP3_LUT;
306    case OP_MAX:
307    case OP_MIN:
308       if (isFloatType(i->dType)) {
309          if (i->dType == TYPE_F32)
310             return &opInfo_FMNMX;
311       } else {
312          return &opInfo_IMNMX;
313       }
314       break;
315    case OP_MEMBAR: return &opInfo_MEMBAR;
316    case OP_MOV: return &opInfo_MOV;
317    case OP_MUL:
318       if (isFloatType(i->dType)) {
319          if (i->dType == TYPE_F32)
320             return &opInfo_FMUL;
321          else
322             return &opInfo_DMUL;
323       }
324       return &opInfo_IMUL;
325    case OP_NEG:
326       if (isFloatType(i->dType))
327          return &opInfo_FNEG;
328       return &opInfo_INEG;
329    case OP_NOT: return &opInfo_NOT;
330    case OP_PERMT: return &opInfo_PRMT;
331    case OP_PFETCH: return &opInfo_ISBERD;
332    case OP_PIXLD: return &opInfo_PIXLD;
333    case OP_POPCNT: return &opInfo_POPC;
334    case OP_QUADOP: return &opInfo_FSWZADD;
335    case OP_RDSV:
336 #if 0
337       if (targ->isCS2RSV(i->getSrc(0)->reg.data.sv.sv))
338          return &opInfo_CS2R;
339 #endif
340       return &opInfo_S2R;
341    case OP_SAT: return &opInfo_SAT;
342    case OP_SELP: return &opInfo_SEL;
343    case OP_SET:
344    case OP_SET_AND:
345    case OP_SET_OR:
346    case OP_SET_XOR:
347       if (i->def(0).getFile() != FILE_PREDICATE) {
348          if (isFloatType(i->dType)) {
349             if (i->dType == TYPE_F32)
350                return &opInfo_FSET_BF;
351          } else {
352             if (isFloatType(i->sType))
353                   return &opInfo_FSET;
354             return &opInfo_ISET;
355          }
356       } else {
357          if (isFloatType(i->sType))
358             if (i->sType == TYPE_F64)
359                return &opInfo_DSETP;
360             else
361                return &opInfo_FSETP;
362          else
363             return &opInfo_ISETP;
364       }
365       break;
366    case OP_SGXT: return &opInfo_SGXT;
367    case OP_SHF: return &opInfo_SHF;
368    case OP_SHFL: return &opInfo_SHFL;
369    case OP_SHL: return &opInfo_SHL;
370    case OP_SHLADD: return &opInfo_LEA;
371    case OP_SHR: return &opInfo_SHR;
372    case OP_SLCT:
373       if (isFloatType(i->sType))
374          return &opInfo_FCMP;
375       return &opInfo_ICMP;
376    case OP_STORE:
377       switch (i->src(0).getFile()) {
378       case FILE_MEMORY_LOCAL : return &opInfo_STL;
379       case FILE_MEMORY_SHARED: return &opInfo_STS;
380       case FILE_MEMORY_GLOBAL: return &opInfo_ST;
381       default:
382          break;
383       }
384       break;
385    case OP_SUB: return &opInfo_SUB;
386    case OP_SULDB:
387    case OP_SULDP: return &opInfo_SULD;
388    case OP_SUREDB:
389    case OP_SUREDP: return &opInfo_SUATOM;
390    case OP_SUSTB:
391    case OP_SUSTP: return &opInfo_SUST;
392    case OP_TEX:
393    case OP_TXB:
394    case OP_TXL: return &opInfo_TEX;
395    case OP_TXD: return &opInfo_TXD;
396    case OP_TXF: return &opInfo_TLD;
397    case OP_TXG: return &opInfo_TLD4;
398    case OP_TXLQ: return &opInfo_TMML;
399    case OP_TXQ: return &opInfo_TXQ;
400    case OP_VFETCH: return &opInfo_ALD;
401    case OP_VOTE: return &opInfo_VOTE;
402    case OP_WARPSYNC: return &opInfo_WARPSYNC;
403    default:
404       break;
405    }
406    return NULL;
407 }
408 
409 bool
isSatSupported(const Instruction * i) const410 TargetGV100::isSatSupported(const Instruction *i) const
411 {
412    switch (i->dType) {
413    case TYPE_F32:
414       switch (i->op) {
415       case OP_ADD:
416       case OP_FMA:
417       case OP_MAD:
418       case OP_MUL: return true;
419       default:
420          break;
421       }
422       break;
423    default:
424       break;
425    }
426    return false;
427 }
428 
429 bool
isModSupported(const Instruction * i,int s,Modifier mod) const430 TargetGV100::isModSupported(const Instruction *i, int s, Modifier mod) const
431 {
432    const struct opInfo *info = nv50_ir::getOpInfo(i);
433    uint8_t mods = 0;
434    if (info && s < (int)ARRAY_SIZE(info->src))
435       mods = info->src[s].mods;
436    return (mod & Modifier(mods)) == mod;
437 }
438 
439 bool
isOpSupported(operation op,DataType ty) const440 TargetGV100::isOpSupported(operation op, DataType ty) const
441 {
442    if (op == OP_MAD || op == OP_FMA)
443       return true;
444    if (ty == TYPE_F32) {
445       if (op == OP_MAX)
446          return true;
447    }
448    if (op == OP_RSQ)
449       return true;
450    if (op == OP_SET ||
451        op == OP_SET_AND ||
452        op == OP_SET_OR ||
453        op == OP_SET_XOR)
454       return true;
455    if (op == OP_SHLADD)
456       return true;
457    return false;
458 }
459 
460 bool
isBarrierRequired(const Instruction * i) const461 TargetGV100::isBarrierRequired(const Instruction *i) const
462 {
463    switch (i->op) {
464    case OP_BREV:
465       return true;
466    default:
467       break;
468    }
469 
470    return TargetGM107::isBarrierRequired(i);
471 }
472 
473 bool
insnCanLoad(const Instruction * i,int s,const Instruction * ld) const474 TargetGV100::insnCanLoad(const Instruction *i, int s,
475                          const Instruction *ld) const
476 {
477    const struct opInfo *info = nv50_ir::getOpInfo(i);
478    uint16_t files = 0;
479 
480    if (ld->src(0).getFile() == FILE_IMMEDIATE && ld->getSrc(0)->reg.data.u64 == 0)
481       return (!i->isPseudo() &&
482               !i->asTex() &&
483               i->op != OP_EXPORT && i->op != OP_STORE);
484 
485    if (ld->src(0).isIndirect(0))
486       return false;
487 
488    if (info && s < (int)ARRAY_SIZE(info->src)) {
489       files = info->src[s].files;
490       if ((s == 1 && i->srcExists(2) && i->src(2).getFile() != FILE_GPR) ||
491           (s == 2 && i->srcExists(1) && i->src(1).getFile() != FILE_GPR)) {
492          files &= ~(1 << FILE_MEMORY_CONST);
493          files &= ~(1 << FILE_IMMEDIATE);
494       } else
495       if ((i->op == OP_SHL || i->op == OP_SHR) &&
496           ((s == 0 && i->srcExists(1) && i->src(1).getFile() != FILE_GPR) ||
497            (s == 1 && i->srcExists(0) && i->src(0).getFile() != FILE_GPR))) {
498          files &= ~(1 << FILE_MEMORY_CONST);
499          files &= ~(1 << FILE_IMMEDIATE);
500       }
501    }
502 
503    if (ld->src(0).getFile() == FILE_IMMEDIATE) {
504       if (i->sType == TYPE_F64) {
505          if (ld->getSrc(0)->asImm()->reg.data.u64 & 0x00000000ffffffff)
506             return false;
507       }
508    }
509 
510    return (files & (1 << ld->src(0).getFile()));
511 }
512 
513 void
getBuiltinCode(const uint32_t ** code,uint32_t * size) const514 TargetGV100::getBuiltinCode(const uint32_t **code, uint32_t *size) const
515 {
516    //XXX: find out why gv100 (tu1xx is fine) hangs without this
517    static uint32_t builtin[] = {
518       0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
519       0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
520       0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
521       0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
522       0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
523       0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
524       0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
525       0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
526       0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
527       0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
528       0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
529       0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
530       0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
531       0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
532       0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
533       0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
534       0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
535       0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
536       0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
537       0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
538       0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
539       0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
540       0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
541       0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
542       0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
543       0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
544       0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
545    };
546    *code = builtin;
547    *size = sizeof(builtin);
548 }
549 
550 uint32_t
getBuiltinOffset(int builtin) const551 TargetGV100::getBuiltinOffset(int builtin) const
552 {
553    return 0;
554 }
555 
556 bool
runLegalizePass(Program * prog,CGStage stage) const557 TargetGV100::runLegalizePass(Program *prog, CGStage stage) const
558 {
559    if (stage == CG_STAGE_PRE_SSA) {
560       GM107LoweringPass pass1(prog);
561       GV100LoweringPass pass2(prog);
562       pass1.run(prog, false, true);
563       pass2.run(prog, false, true);
564       return true;
565    } else
566    if (stage == CG_STAGE_SSA) {
567       GV100LegalizeSSA pass(prog);
568       return pass.run(prog, false, true);
569    } else
570    if (stage == CG_STAGE_POST_RA) {
571       NVC0LegalizePostRA pass(prog);
572       return pass.run(prog, false, true);
573    }
574    return false;
575 }
576 
577 CodeEmitter *
getCodeEmitter(Program::Type type)578 TargetGV100::getCodeEmitter(Program::Type type)
579 {
580    return new CodeEmitterGV100(this);
581 }
582 
TargetGV100(unsigned int chipset)583 TargetGV100::TargetGV100(unsigned int chipset)
584    : TargetGM107(chipset)
585 {
586    initOpInfo();
587 };
588 
getTargetGV100(unsigned int chipset)589 Target *getTargetGV100(unsigned int chipset)
590 {
591    return new TargetGV100(chipset);
592 }
593 
594 };
595