6903132efa71ac08a0634161a627d002a473b58d
[mesa.git] / src / gallium / drivers / nouveau / codegen / nv50_ir_emit_gm107.cpp
1 /*
2 * Copyright 2014 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 * Authors: Ben Skeggs <bskeggs@redhat.com>
23 */
24
25 #include "codegen/nv50_ir_target_gm107.h"
26
27 //#define GM107_DEBUG_SCHED_DATA
28
29 namespace nv50_ir {
30
31 class CodeEmitterGM107 : public CodeEmitter
32 {
33 public:
34 CodeEmitterGM107(const TargetGM107 *);
35
36 virtual bool emitInstruction(Instruction *);
37 virtual uint32_t getMinEncodingSize(const Instruction *) const;
38
39 virtual void prepareEmission(Program *);
40 virtual void prepareEmission(Function *);
41
42 inline void setProgramType(Program::Type pType) { progType = pType; }
43
44 private:
45 const TargetGM107 *targGM107;
46
47 Program::Type progType;
48
49 const Instruction *insn;
50 const bool writeIssueDelays;
51 uint32_t *data;
52
53 private:
54 inline void emitField(uint32_t *, int, int, uint32_t);
55 inline void emitField(int b, int s, uint32_t v) { emitField(code, b, s, v); }
56
57 inline void emitInsn(uint32_t, bool);
58 inline void emitInsn(uint32_t o) { emitInsn(o, true); }
59 inline void emitPred();
60 inline void emitGPR(int, const Value *);
61 inline void emitGPR(int pos) {
62 emitGPR(pos, (const Value *)NULL);
63 }
64 inline void emitGPR(int pos, const ValueRef &ref) {
65 emitGPR(pos, ref.get() ? ref.rep() : (const Value *)NULL);
66 }
67 inline void emitGPR(int pos, const ValueRef *ref) {
68 emitGPR(pos, ref ? ref->rep() : (const Value *)NULL);
69 }
70 inline void emitGPR(int pos, const ValueDef &def) {
71 emitGPR(pos, def.get() ? def.rep() : (const Value *)NULL);
72 }
73 inline void emitSYS(int, const Value *);
74 inline void emitSYS(int pos, const ValueRef &ref) {
75 emitSYS(pos, ref.get() ? ref.rep() : (const Value *)NULL);
76 }
77 inline void emitPRED(int, const Value *);
78 inline void emitPRED(int pos) {
79 emitPRED(pos, (const Value *)NULL);
80 }
81 inline void emitPRED(int pos, const ValueRef &ref) {
82 emitPRED(pos, ref.get() ? ref.rep() : (const Value *)NULL);
83 }
84 inline void emitPRED(int pos, const ValueDef &def) {
85 emitPRED(pos, def.get() ? def.rep() : (const Value *)NULL);
86 }
87 inline void emitADDR(int, int, int, int, const ValueRef &);
88 inline void emitCBUF(int, int, int, int, int, const ValueRef &);
89 inline bool longIMMD(const ValueRef &);
90 inline void emitIMMD(int, int, const ValueRef &);
91
92 void emitCond3(int, CondCode);
93 void emitCond4(int, CondCode);
94 void emitCond5(int pos, CondCode cc) { emitCond4(pos, cc); }
95 inline void emitO(int);
96 inline void emitP(int);
97 inline void emitSAT(int);
98 inline void emitCC(int);
99 inline void emitX(int);
100 inline void emitABS(int, const ValueRef &);
101 inline void emitNEG(int, const ValueRef &);
102 inline void emitNEG2(int, const ValueRef &, const ValueRef &);
103 inline void emitFMZ(int, int);
104 inline void emitRND(int, RoundMode, int);
105 inline void emitRND(int pos) {
106 emitRND(pos, insn->rnd, -1);
107 }
108 inline void emitPDIV(int);
109 inline void emitINV(int, const ValueRef &);
110
111 void emitEXIT();
112 void emitBRA();
113 void emitCAL();
114 void emitPCNT();
115 void emitCONT();
116 void emitPBK();
117 void emitBRK();
118 void emitPRET();
119 void emitRET();
120 void emitSSY();
121 void emitSYNC();
122 void emitSAM();
123 void emitRAM();
124
125 void emitMOV();
126 void emitS2R();
127 void emitF2F();
128 void emitF2I();
129 void emitI2F();
130 void emitI2I();
131 void emitSEL();
132 void emitSHFL();
133
134 void emitDADD();
135 void emitDMUL();
136 void emitDFMA();
137 void emitDMNMX();
138 void emitDSET();
139 void emitDSETP();
140
141 void emitFADD();
142 void emitFMUL();
143 void emitFFMA();
144 void emitMUFU();
145 void emitFMNMX();
146 void emitRRO();
147 void emitFCMP();
148 void emitFSET();
149 void emitFSETP();
150 void emitFSWZADD();
151
152 void emitLOP();
153 void emitNOT();
154 void emitIADD();
155 void emitIMUL();
156 void emitIMAD();
157 void emitISCADD();
158 void emitIMNMX();
159 void emitICMP();
160 void emitISET();
161 void emitISETP();
162 void emitSHL();
163 void emitSHR();
164 void emitSHF();
165 void emitPOPC();
166 void emitBFI();
167 void emitBFE();
168 void emitFLO();
169
170 void emitLDSTs(int, DataType);
171 void emitLDSTc(int);
172 void emitLDC();
173 void emitLDL();
174 void emitLDS();
175 void emitLD();
176 void emitSTL();
177 void emitSTS();
178 void emitST();
179 void emitALD();
180 void emitAST();
181 void emitISBERD();
182 void emitAL2P();
183 void emitIPA();
184 void emitATOM();
185 void emitATOMS();
186 void emitRED();
187 void emitCCTL();
188
189 void emitPIXLD();
190
191 void emitTEXs(int);
192 void emitTEX();
193 void emitTLD();
194 void emitTLD4();
195 void emitTXD();
196 void emitTXQ();
197 void emitTMML();
198 void emitDEPBAR();
199
200 void emitNOP();
201 void emitKIL();
202 void emitOUT();
203
204 void emitBAR();
205 void emitMEMBAR();
206
207 void emitVOTE();
208
209 void emitSUTarget();
210 void emitSUHandle(const int s);
211 void emitSUSTx();
212 void emitSULDx();
213 void emitSUREDx();
214 };
215
216 /*******************************************************************************
217 * general instruction layout/fields
218 ******************************************************************************/
219
220 void
221 CodeEmitterGM107::emitField(uint32_t *data, int b, int s, uint32_t v)
222 {
223 if (b >= 0) {
224 uint32_t m = ((1ULL << s) - 1);
225 uint64_t d = (uint64_t)(v & m) << b;
226 assert(!(v & ~m) || (v & ~m) == ~m);
227 data[1] |= d >> 32;
228 data[0] |= d;
229 }
230 }
231
232 void
233 CodeEmitterGM107::emitPred()
234 {
235 if (insn->predSrc >= 0) {
236 emitField(16, 3, insn->getSrc(insn->predSrc)->rep()->reg.data.id);
237 emitField(19, 1, insn->cc == CC_NOT_P);
238 } else {
239 emitField(16, 3, 7);
240 }
241 }
242
243 void
244 CodeEmitterGM107::emitInsn(uint32_t hi, bool pred)
245 {
246 code[0] = 0x00000000;
247 code[1] = hi;
248 if (pred)
249 emitPred();
250 }
251
252 void
253 CodeEmitterGM107::emitGPR(int pos, const Value *val)
254 {
255 emitField(pos, 8, val && !val->inFile(FILE_FLAGS) ?
256 val->reg.data.id : 255);
257 }
258
259 void
260 CodeEmitterGM107::emitSYS(int pos, const Value *val)
261 {
262 int id = val ? val->reg.data.id : -1;
263
264 switch (id) {
265 case SV_LANEID : id = 0x00; break;
266 case SV_VERTEX_COUNT : id = 0x10; break;
267 case SV_INVOCATION_ID : id = 0x11; break;
268 case SV_THREAD_KILL : id = 0x13; break;
269 case SV_INVOCATION_INFO: id = 0x1d; break;
270 case SV_TID : id = 0x21 + val->reg.data.sv.index; break;
271 case SV_CTAID : id = 0x25 + val->reg.data.sv.index; break;
272 default:
273 assert(!"invalid system value");
274 id = 0;
275 break;
276 }
277
278 emitField(pos, 8, id);
279 }
280
281 void
282 CodeEmitterGM107::emitPRED(int pos, const Value *val)
283 {
284 emitField(pos, 3, val ? val->reg.data.id : 7);
285 }
286
287 void
288 CodeEmitterGM107::emitADDR(int gpr, int off, int len, int shr,
289 const ValueRef &ref)
290 {
291 const Value *v = ref.get();
292 assert(!(v->reg.data.offset & ((1 << shr) - 1)));
293 if (gpr >= 0)
294 emitGPR(gpr, ref.getIndirect(0));
295 emitField(off, len, v->reg.data.offset >> shr);
296 }
297
298 void
299 CodeEmitterGM107::emitCBUF(int buf, int gpr, int off, int len, int shr,
300 const ValueRef &ref)
301 {
302 const Value *v = ref.get();
303 const Symbol *s = v->asSym();
304
305 assert(!(s->reg.data.offset & ((1 << shr) - 1)));
306
307 emitField(buf, 5, v->reg.fileIndex);
308 if (gpr >= 0)
309 emitGPR(gpr, ref.getIndirect(0));
310 emitField(off, 16, s->reg.data.offset >> shr);
311 }
312
313 bool
314 CodeEmitterGM107::longIMMD(const ValueRef &ref)
315 {
316 if (ref.getFile() == FILE_IMMEDIATE) {
317 const ImmediateValue *imm = ref.get()->asImm();
318 if (isFloatType(insn->sType)) {
319 if ((imm->reg.data.u32 & 0x00000fff) != 0x00000000)
320 return true;
321 } else {
322 if ((imm->reg.data.u32 & 0xfff00000) != 0x00000000 &&
323 (imm->reg.data.u32 & 0xfff00000) != 0xfff00000)
324 return true;
325 }
326 }
327 return false;
328 }
329
330 void
331 CodeEmitterGM107::emitIMMD(int pos, int len, const ValueRef &ref)
332 {
333 const ImmediateValue *imm = ref.get()->asImm();
334 uint32_t val = imm->reg.data.u32;
335
336 if (len == 19) {
337 if (insn->sType == TYPE_F32 || insn->sType == TYPE_F16) {
338 assert(!(val & 0x00000fff));
339 val >>= 12;
340 } else if (insn->sType == TYPE_F64) {
341 assert(!(imm->reg.data.u64 & 0x00000fffffffffffULL));
342 val = imm->reg.data.u64 >> 44;
343 }
344 assert(!(val & 0xfff00000) || (val & 0xfff00000) == 0xfff00000);
345 emitField( 56, 1, (val & 0x80000) >> 19);
346 emitField(pos, len, (val & 0x7ffff));
347 } else {
348 emitField(pos, len, val);
349 }
350 }
351
352 /*******************************************************************************
353 * modifiers
354 ******************************************************************************/
355
356 void
357 CodeEmitterGM107::emitCond3(int pos, CondCode code)
358 {
359 int data = 0;
360
361 switch (code) {
362 case CC_FL : data = 0x00; break;
363 case CC_LTU:
364 case CC_LT : data = 0x01; break;
365 case CC_EQU:
366 case CC_EQ : data = 0x02; break;
367 case CC_LEU:
368 case CC_LE : data = 0x03; break;
369 case CC_GTU:
370 case CC_GT : data = 0x04; break;
371 case CC_NEU:
372 case CC_NE : data = 0x05; break;
373 case CC_GEU:
374 case CC_GE : data = 0x06; break;
375 case CC_TR : data = 0x07; break;
376 default:
377 assert(!"invalid cond3");
378 break;
379 }
380
381 emitField(pos, 3, data);
382 }
383
384 void
385 CodeEmitterGM107::emitCond4(int pos, CondCode code)
386 {
387 int data = 0;
388
389 switch (code) {
390 case CC_FL: data = 0x00; break;
391 case CC_LT: data = 0x01; break;
392 case CC_EQ: data = 0x02; break;
393 case CC_LE: data = 0x03; break;
394 case CC_GT: data = 0x04; break;
395 case CC_NE: data = 0x05; break;
396 case CC_GE: data = 0x06; break;
397 // case CC_NUM: data = 0x07; break;
398 // case CC_NAN: data = 0x08; break;
399 case CC_LTU: data = 0x09; break;
400 case CC_EQU: data = 0x0a; break;
401 case CC_LEU: data = 0x0b; break;
402 case CC_GTU: data = 0x0c; break;
403 case CC_NEU: data = 0x0d; break;
404 case CC_GEU: data = 0x0e; break;
405 case CC_TR: data = 0x0f; break;
406 default:
407 assert(!"invalid cond4");
408 break;
409 }
410
411 emitField(pos, 4, data);
412 }
413
414 void
415 CodeEmitterGM107::emitO(int pos)
416 {
417 emitField(pos, 1, insn->getSrc(0)->reg.file == FILE_SHADER_OUTPUT);
418 }
419
420 void
421 CodeEmitterGM107::emitP(int pos)
422 {
423 emitField(pos, 1, insn->perPatch);
424 }
425
426 void
427 CodeEmitterGM107::emitSAT(int pos)
428 {
429 emitField(pos, 1, insn->saturate);
430 }
431
432 void
433 CodeEmitterGM107::emitCC(int pos)
434 {
435 emitField(pos, 1, insn->flagsDef >= 0);
436 }
437
438 void
439 CodeEmitterGM107::emitX(int pos)
440 {
441 emitField(pos, 1, insn->flagsSrc >= 0);
442 }
443
444 void
445 CodeEmitterGM107::emitABS(int pos, const ValueRef &ref)
446 {
447 emitField(pos, 1, ref.mod.abs());
448 }
449
450 void
451 CodeEmitterGM107::emitNEG(int pos, const ValueRef &ref)
452 {
453 emitField(pos, 1, ref.mod.neg());
454 }
455
456 void
457 CodeEmitterGM107::emitNEG2(int pos, const ValueRef &a, const ValueRef &b)
458 {
459 emitField(pos, 1, a.mod.neg() ^ b.mod.neg());
460 }
461
462 void
463 CodeEmitterGM107::emitFMZ(int pos, int len)
464 {
465 emitField(pos, len, insn->dnz << 1 | insn->ftz);
466 }
467
468 void
469 CodeEmitterGM107::emitRND(int rmp, RoundMode rnd, int rip)
470 {
471 int rm = 0, ri = 0;
472 switch (rnd) {
473 case ROUND_NI: ri = 1;
474 case ROUND_N : rm = 0; break;
475 case ROUND_MI: ri = 1;
476 case ROUND_M : rm = 1; break;
477 case ROUND_PI: ri = 1;
478 case ROUND_P : rm = 2; break;
479 case ROUND_ZI: ri = 1;
480 case ROUND_Z : rm = 3; break;
481 default:
482 assert(!"invalid round mode");
483 break;
484 }
485 emitField(rip, 1, ri);
486 emitField(rmp, 2, rm);
487 }
488
489 void
490 CodeEmitterGM107::emitPDIV(int pos)
491 {
492 assert(insn->postFactor >= -3 && insn->postFactor <= 3);
493 if (insn->postFactor > 0)
494 emitField(pos, 3, 7 - insn->postFactor);
495 else
496 emitField(pos, 3, 0 - insn->postFactor);
497 }
498
499 void
500 CodeEmitterGM107::emitINV(int pos, const ValueRef &ref)
501 {
502 emitField(pos, 1, !!(ref.mod & Modifier(NV50_IR_MOD_NOT)));
503 }
504
505 /*******************************************************************************
506 * control flow
507 ******************************************************************************/
508
509 void
510 CodeEmitterGM107::emitEXIT()
511 {
512 emitInsn (0xe3000000);
513 emitCond5(0x00, CC_TR);
514 }
515
516 void
517 CodeEmitterGM107::emitBRA()
518 {
519 const FlowInstruction *insn = this->insn->asFlow();
520 int gpr = -1;
521
522 if (insn->indirect) {
523 if (insn->absolute)
524 emitInsn(0xe2000000); // JMX
525 else
526 emitInsn(0xe2500000); // BRX
527 gpr = 0x08;
528 } else {
529 if (insn->absolute)
530 emitInsn(0xe2100000); // JMP
531 else
532 emitInsn(0xe2400000); // BRA
533 emitField(0x07, 1, insn->allWarp);
534 }
535
536 emitField(0x06, 1, insn->limit);
537 emitCond5(0x00, CC_TR);
538
539 if (!insn->srcExists(0) || insn->src(0).getFile() != FILE_MEMORY_CONST) {
540 int32_t pos = insn->target.bb->binPos;
541 if (writeIssueDelays && !(pos & 0x1f))
542 pos += 8;
543 if (!insn->absolute)
544 emitField(0x14, 24, pos - (codeSize + 8));
545 else
546 emitField(0x14, 32, pos);
547 } else {
548 emitCBUF (0x24, gpr, 20, 16, 0, insn->src(0));
549 emitField(0x05, 1, 1);
550 }
551 }
552
553 void
554 CodeEmitterGM107::emitCAL()
555 {
556 const FlowInstruction *insn = this->insn->asFlow();
557
558 if (insn->absolute) {
559 emitInsn(0xe2200000, 0); // JCAL
560 } else {
561 emitInsn(0xe2600000, 0); // CAL
562 }
563
564 if (!insn->srcExists(0) || insn->src(0).getFile() != FILE_MEMORY_CONST) {
565 if (!insn->absolute)
566 emitField(0x14, 24, insn->target.bb->binPos - (codeSize + 8));
567 else {
568 if (insn->builtin) {
569 int pcAbs = targGM107->getBuiltinOffset(insn->target.builtin);
570 addReloc(RelocEntry::TYPE_BUILTIN, 0, pcAbs, 0xfff00000, 20);
571 addReloc(RelocEntry::TYPE_BUILTIN, 1, pcAbs, 0x000fffff, -12);
572 } else {
573 emitField(0x14, 32, insn->target.bb->binPos);
574 }
575 }
576 } else {
577 emitCBUF (0x24, -1, 20, 16, 0, insn->src(0));
578 emitField(0x05, 1, 1);
579 }
580 }
581
582 void
583 CodeEmitterGM107::emitPCNT()
584 {
585 const FlowInstruction *insn = this->insn->asFlow();
586
587 emitInsn(0xe2b00000, 0);
588
589 if (!insn->srcExists(0) || insn->src(0).getFile() != FILE_MEMORY_CONST) {
590 emitField(0x14, 24, insn->target.bb->binPos - (codeSize + 8));
591 } else {
592 emitCBUF (0x24, -1, 20, 16, 0, insn->src(0));
593 emitField(0x05, 1, 1);
594 }
595 }
596
597 void
598 CodeEmitterGM107::emitCONT()
599 {
600 emitInsn (0xe3500000);
601 emitCond5(0x00, CC_TR);
602 }
603
604 void
605 CodeEmitterGM107::emitPBK()
606 {
607 const FlowInstruction *insn = this->insn->asFlow();
608
609 emitInsn(0xe2a00000, 0);
610
611 if (!insn->srcExists(0) || insn->src(0).getFile() != FILE_MEMORY_CONST) {
612 emitField(0x14, 24, insn->target.bb->binPos - (codeSize + 8));
613 } else {
614 emitCBUF (0x24, -1, 20, 16, 0, insn->src(0));
615 emitField(0x05, 1, 1);
616 }
617 }
618
619 void
620 CodeEmitterGM107::emitBRK()
621 {
622 emitInsn (0xe3400000);
623 emitCond5(0x00, CC_TR);
624 }
625
626 void
627 CodeEmitterGM107::emitPRET()
628 {
629 const FlowInstruction *insn = this->insn->asFlow();
630
631 emitInsn(0xe2700000, 0);
632
633 if (!insn->srcExists(0) || insn->src(0).getFile() != FILE_MEMORY_CONST) {
634 emitField(0x14, 24, insn->target.bb->binPos - (codeSize + 8));
635 } else {
636 emitCBUF (0x24, -1, 20, 16, 0, insn->src(0));
637 emitField(0x05, 1, 1);
638 }
639 }
640
641 void
642 CodeEmitterGM107::emitRET()
643 {
644 emitInsn (0xe3200000);
645 emitCond5(0x00, CC_TR);
646 }
647
648 void
649 CodeEmitterGM107::emitSSY()
650 {
651 const FlowInstruction *insn = this->insn->asFlow();
652
653 emitInsn(0xe2900000, 0);
654
655 if (!insn->srcExists(0) || insn->src(0).getFile() != FILE_MEMORY_CONST) {
656 emitField(0x14, 24, insn->target.bb->binPos - (codeSize + 8));
657 } else {
658 emitCBUF (0x24, -1, 20, 16, 0, insn->src(0));
659 emitField(0x05, 1, 1);
660 }
661 }
662
663 void
664 CodeEmitterGM107::emitSYNC()
665 {
666 emitInsn (0xf0f80000);
667 emitCond5(0x00, CC_TR);
668 }
669
670 void
671 CodeEmitterGM107::emitSAM()
672 {
673 emitInsn(0xe3700000, 0);
674 }
675
676 void
677 CodeEmitterGM107::emitRAM()
678 {
679 emitInsn(0xe3800000, 0);
680 }
681
682 /*******************************************************************************
683 * predicate/cc
684 ******************************************************************************/
685
686 /*******************************************************************************
687 * movement / conversion
688 ******************************************************************************/
689
690 void
691 CodeEmitterGM107::emitMOV()
692 {
693 if (insn->src(0).getFile() != FILE_IMMEDIATE) {
694 switch (insn->src(0).getFile()) {
695 case FILE_GPR:
696 if (insn->def(0).getFile() == FILE_PREDICATE) {
697 emitInsn(0x5b6a0000);
698 emitGPR (0x08);
699 } else {
700 emitInsn(0x5c980000);
701 }
702 emitGPR (0x14, insn->src(0));
703 break;
704 case FILE_MEMORY_CONST:
705 emitInsn(0x4c980000);
706 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
707 break;
708 case FILE_IMMEDIATE:
709 emitInsn(0x38980000);
710 emitIMMD(0x14, 19, insn->src(0));
711 break;
712 case FILE_PREDICATE:
713 emitInsn(0x50880000);
714 emitPRED(0x0c, insn->src(0));
715 emitPRED(0x1d);
716 emitPRED(0x27);
717 break;
718 default:
719 assert(!"bad src file");
720 break;
721 }
722 if (insn->def(0).getFile() != FILE_PREDICATE &&
723 insn->src(0).getFile() != FILE_PREDICATE)
724 emitField(0x27, 4, insn->lanes);
725 } else {
726 emitInsn (0x01000000);
727 emitIMMD (0x14, 32, insn->src(0));
728 emitField(0x0c, 4, insn->lanes);
729 }
730
731 if (insn->def(0).getFile() == FILE_PREDICATE) {
732 emitPRED(0x27);
733 emitPRED(0x03, insn->def(0));
734 emitPRED(0x00);
735 } else {
736 emitGPR(0x00, insn->def(0));
737 }
738 }
739
740 void
741 CodeEmitterGM107::emitS2R()
742 {
743 emitInsn(0xf0c80000);
744 emitSYS (0x14, insn->src(0));
745 emitGPR (0x00, insn->def(0));
746 }
747
748 void
749 CodeEmitterGM107::emitF2F()
750 {
751 RoundMode rnd = insn->rnd;
752
753 switch (insn->op) {
754 case OP_FLOOR: rnd = ROUND_MI; break;
755 case OP_CEIL : rnd = ROUND_PI; break;
756 case OP_TRUNC: rnd = ROUND_ZI; break;
757 default:
758 break;
759 }
760
761 switch (insn->src(0).getFile()) {
762 case FILE_GPR:
763 emitInsn(0x5ca80000);
764 emitGPR (0x14, insn->src(0));
765 break;
766 case FILE_MEMORY_CONST:
767 emitInsn(0x4ca80000);
768 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
769 break;
770 case FILE_IMMEDIATE:
771 emitInsn(0x38a80000);
772 emitIMMD(0x14, 19, insn->src(0));
773 break;
774 default:
775 assert(!"bad src0 file");
776 break;
777 }
778
779 emitField(0x32, 1, (insn->op == OP_SAT) || insn->saturate);
780 emitField(0x31, 1, (insn->op == OP_ABS) || insn->src(0).mod.abs());
781 emitCC (0x2f);
782 emitField(0x2d, 1, (insn->op == OP_NEG) || insn->src(0).mod.neg());
783 emitFMZ (0x2c, 1);
784 emitField(0x29, 1, insn->subOp);
785 emitRND (0x27, rnd, 0x2a);
786 emitField(0x0a, 2, util_logbase2(typeSizeof(insn->sType)));
787 emitField(0x08, 2, util_logbase2(typeSizeof(insn->dType)));
788 emitGPR (0x00, insn->def(0));
789 }
790
791 void
792 CodeEmitterGM107::emitF2I()
793 {
794 RoundMode rnd = insn->rnd;
795
796 switch (insn->op) {
797 case OP_FLOOR: rnd = ROUND_M; break;
798 case OP_CEIL : rnd = ROUND_P; break;
799 case OP_TRUNC: rnd = ROUND_Z; break;
800 default:
801 break;
802 }
803
804 switch (insn->src(0).getFile()) {
805 case FILE_GPR:
806 emitInsn(0x5cb00000);
807 emitGPR (0x14, insn->src(0));
808 break;
809 case FILE_MEMORY_CONST:
810 emitInsn(0x4cb00000);
811 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
812 break;
813 case FILE_IMMEDIATE:
814 emitInsn(0x38b00000);
815 emitIMMD(0x14, 19, insn->src(0));
816 break;
817 default:
818 assert(!"bad src0 file");
819 break;
820 }
821
822 emitField(0x31, 1, (insn->op == OP_ABS) || insn->src(0).mod.abs());
823 emitCC (0x2f);
824 emitField(0x2d, 1, (insn->op == OP_NEG) || insn->src(0).mod.neg());
825 emitFMZ (0x2c, 1);
826 emitRND (0x27, rnd, 0x2a);
827 emitField(0x0c, 1, isSignedType(insn->dType));
828 emitField(0x0a, 2, util_logbase2(typeSizeof(insn->sType)));
829 emitField(0x08, 2, util_logbase2(typeSizeof(insn->dType)));
830 emitGPR (0x00, insn->def(0));
831 }
832
833 void
834 CodeEmitterGM107::emitI2F()
835 {
836 RoundMode rnd = insn->rnd;
837
838 switch (insn->op) {
839 case OP_FLOOR: rnd = ROUND_M; break;
840 case OP_CEIL : rnd = ROUND_P; break;
841 case OP_TRUNC: rnd = ROUND_Z; break;
842 default:
843 break;
844 }
845
846 switch (insn->src(0).getFile()) {
847 case FILE_GPR:
848 emitInsn(0x5cb80000);
849 emitGPR (0x14, insn->src(0));
850 break;
851 case FILE_MEMORY_CONST:
852 emitInsn(0x4cb80000);
853 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
854 break;
855 case FILE_IMMEDIATE:
856 emitInsn(0x38b80000);
857 emitIMMD(0x14, 19, insn->src(0));
858 break;
859 default:
860 assert(!"bad src0 file");
861 break;
862 }
863
864 emitField(0x31, 1, (insn->op == OP_ABS) || insn->src(0).mod.abs());
865 emitCC (0x2f);
866 emitField(0x2d, 1, (insn->op == OP_NEG) || insn->src(0).mod.neg());
867 emitField(0x29, 2, insn->subOp);
868 emitRND (0x27, rnd, -1);
869 emitField(0x0d, 1, isSignedType(insn->sType));
870 emitField(0x0a, 2, util_logbase2(typeSizeof(insn->sType)));
871 emitField(0x08, 2, util_logbase2(typeSizeof(insn->dType)));
872 emitGPR (0x00, insn->def(0));
873 }
874
875 void
876 CodeEmitterGM107::emitI2I()
877 {
878 switch (insn->src(0).getFile()) {
879 case FILE_GPR:
880 emitInsn(0x5ce00000);
881 emitGPR (0x14, insn->src(0));
882 break;
883 case FILE_MEMORY_CONST:
884 emitInsn(0x4ce00000);
885 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
886 break;
887 case FILE_IMMEDIATE:
888 emitInsn(0x38e00000);
889 emitIMMD(0x14, 19, insn->src(0));
890 break;
891 default:
892 assert(!"bad src0 file");
893 break;
894 }
895
896 emitSAT (0x32);
897 emitField(0x31, 1, (insn->op == OP_ABS) || insn->src(0).mod.abs());
898 emitCC (0x2f);
899 emitField(0x2d, 1, (insn->op == OP_NEG) || insn->src(0).mod.neg());
900 emitField(0x29, 2, insn->subOp);
901 emitField(0x0d, 1, isSignedType(insn->sType));
902 emitField(0x0c, 1, isSignedType(insn->dType));
903 emitField(0x0a, 2, util_logbase2(typeSizeof(insn->sType)));
904 emitField(0x08, 2, util_logbase2(typeSizeof(insn->dType)));
905 emitGPR (0x00, insn->def(0));
906 }
907
908 static void
909 selpFlip(const FixupEntry *entry, uint32_t *code, const FixupData& data)
910 {
911 int loc = entry->loc;
912 if (data.force_persample_interp)
913 code[loc + 1] |= 1 << 10;
914 else
915 code[loc + 1] &= ~(1 << 10);
916 }
917
918 void
919 CodeEmitterGM107::emitSEL()
920 {
921 switch (insn->src(1).getFile()) {
922 case FILE_GPR:
923 emitInsn(0x5ca00000);
924 emitGPR (0x14, insn->src(1));
925 break;
926 case FILE_MEMORY_CONST:
927 emitInsn(0x4ca00000);
928 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
929 break;
930 case FILE_IMMEDIATE:
931 emitInsn(0x38a00000);
932 emitIMMD(0x14, 19, insn->src(1));
933 break;
934 default:
935 assert(!"bad src1 file");
936 break;
937 }
938
939 emitINV (0x2a, insn->src(2));
940 emitPRED(0x27, insn->src(2));
941 emitGPR (0x08, insn->src(0));
942 emitGPR (0x00, insn->def(0));
943
944 if (insn->subOp == 1) {
945 addInterp(0, 0, selpFlip);
946 }
947 }
948
949 void
950 CodeEmitterGM107::emitSHFL()
951 {
952 int type = 0;
953
954 emitInsn (0xef100000);
955
956 switch (insn->src(1).getFile()) {
957 case FILE_GPR:
958 emitGPR(0x14, insn->src(1));
959 break;
960 case FILE_IMMEDIATE:
961 emitIMMD(0x14, 5, insn->src(1));
962 type |= 1;
963 break;
964 default:
965 assert(!"invalid src1 file");
966 break;
967 }
968
969 /*XXX: what is this arg? hardcode immediate for now */
970 emitField(0x22, 13, 0x1c03);
971 type |= 2;
972
973 emitPRED (0x30);
974 emitField(0x1e, 2, insn->subOp);
975 emitField(0x1c, 2, type);
976 emitGPR (0x08, insn->src(0));
977 emitGPR (0x00, insn->def(0));
978 }
979
980 /*******************************************************************************
981 * double
982 ******************************************************************************/
983
984 void
985 CodeEmitterGM107::emitDADD()
986 {
987 switch (insn->src(1).getFile()) {
988 case FILE_GPR:
989 emitInsn(0x5c700000);
990 emitGPR (0x14, insn->src(1));
991 break;
992 case FILE_MEMORY_CONST:
993 emitInsn(0x4c700000);
994 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
995 break;
996 case FILE_IMMEDIATE:
997 emitInsn(0x38700000);
998 emitIMMD(0x14, 19, insn->src(1));
999 break;
1000 default:
1001 assert(!"bad src1 file");
1002 break;
1003 }
1004 emitABS(0x31, insn->src(1));
1005 emitNEG(0x30, insn->src(0));
1006 emitCC (0x2f);
1007 emitABS(0x2e, insn->src(0));
1008 emitNEG(0x2d, insn->src(1));
1009
1010 if (insn->op == OP_SUB)
1011 code[1] ^= 0x00002000;
1012
1013 emitGPR(0x08, insn->src(0));
1014 emitGPR(0x00, insn->def(0));
1015 }
1016
1017 void
1018 CodeEmitterGM107::emitDMUL()
1019 {
1020 switch (insn->src(1).getFile()) {
1021 case FILE_GPR:
1022 emitInsn(0x5c800000);
1023 emitGPR (0x14, insn->src(1));
1024 break;
1025 case FILE_MEMORY_CONST:
1026 emitInsn(0x4c800000);
1027 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1028 break;
1029 case FILE_IMMEDIATE:
1030 emitInsn(0x38800000);
1031 emitIMMD(0x14, 19, insn->src(1));
1032 break;
1033 default:
1034 assert(!"bad src1 file");
1035 break;
1036 }
1037
1038 emitNEG2(0x30, insn->src(0), insn->src(1));
1039 emitCC (0x2f);
1040 emitRND (0x27);
1041 emitGPR (0x08, insn->src(0));
1042 emitGPR (0x00, insn->def(0));
1043 }
1044
1045 void
1046 CodeEmitterGM107::emitDFMA()
1047 {
1048 switch(insn->src(2).getFile()) {
1049 case FILE_GPR:
1050 switch (insn->src(1).getFile()) {
1051 case FILE_GPR:
1052 emitInsn(0x5b700000);
1053 emitGPR (0x14, insn->src(1));
1054 break;
1055 case FILE_MEMORY_CONST:
1056 emitInsn(0x4b700000);
1057 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1058 break;
1059 case FILE_IMMEDIATE:
1060 emitInsn(0x36700000);
1061 emitIMMD(0x14, 19, insn->src(1));
1062 break;
1063 default:
1064 assert(!"bad src1 file");
1065 break;
1066 }
1067 emitGPR (0x27, insn->src(2));
1068 break;
1069 case FILE_MEMORY_CONST:
1070 emitInsn(0x53700000);
1071 emitGPR (0x27, insn->src(1));
1072 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(2));
1073 break;
1074 default:
1075 assert(!"bad src2 file");
1076 break;
1077 }
1078
1079 emitRND (0x32);
1080 emitNEG (0x31, insn->src(2));
1081 emitNEG2(0x30, insn->src(0), insn->src(1));
1082 emitCC (0x2f);
1083 emitGPR (0x08, insn->src(0));
1084 emitGPR (0x00, insn->def(0));
1085 }
1086
1087 void
1088 CodeEmitterGM107::emitDMNMX()
1089 {
1090 switch (insn->src(1).getFile()) {
1091 case FILE_GPR:
1092 emitInsn(0x5c500000);
1093 emitGPR (0x14, insn->src(1));
1094 break;
1095 case FILE_MEMORY_CONST:
1096 emitInsn(0x4c500000);
1097 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1098 break;
1099 case FILE_IMMEDIATE:
1100 emitInsn(0x38500000);
1101 emitIMMD(0x14, 19, insn->src(1));
1102 break;
1103 default:
1104 assert(!"bad src1 file");
1105 break;
1106 }
1107
1108 emitABS (0x31, insn->src(1));
1109 emitNEG (0x30, insn->src(0));
1110 emitCC (0x2f);
1111 emitABS (0x2e, insn->src(0));
1112 emitNEG (0x2d, insn->src(1));
1113 emitField(0x2a, 1, insn->op == OP_MAX);
1114 emitPRED (0x27);
1115 emitGPR (0x08, insn->src(0));
1116 emitGPR (0x00, insn->def(0));
1117 }
1118
1119 void
1120 CodeEmitterGM107::emitDSET()
1121 {
1122 const CmpInstruction *insn = this->insn->asCmp();
1123
1124 switch (insn->src(1).getFile()) {
1125 case FILE_GPR:
1126 emitInsn(0x59000000);
1127 emitGPR (0x14, insn->src(1));
1128 break;
1129 case FILE_MEMORY_CONST:
1130 emitInsn(0x49000000);
1131 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1132 break;
1133 case FILE_IMMEDIATE:
1134 emitInsn(0x32000000);
1135 emitIMMD(0x14, 19, insn->src(1));
1136 break;
1137 default:
1138 assert(!"bad src1 file");
1139 break;
1140 }
1141
1142 if (insn->op != OP_SET) {
1143 switch (insn->op) {
1144 case OP_SET_AND: emitField(0x2d, 2, 0); break;
1145 case OP_SET_OR : emitField(0x2d, 2, 1); break;
1146 case OP_SET_XOR: emitField(0x2d, 2, 2); break;
1147 default:
1148 assert(!"invalid set op");
1149 break;
1150 }
1151 emitPRED(0x27, insn->src(2));
1152 } else {
1153 emitPRED(0x27);
1154 }
1155
1156 emitABS (0x36, insn->src(0));
1157 emitNEG (0x35, insn->src(1));
1158 emitField(0x34, 1, insn->dType == TYPE_F32);
1159 emitCond4(0x30, insn->setCond);
1160 emitCC (0x2f);
1161 emitABS (0x2c, insn->src(1));
1162 emitNEG (0x2b, insn->src(0));
1163 emitGPR (0x08, insn->src(0));
1164 emitGPR (0x00, insn->def(0));
1165 }
1166
1167 void
1168 CodeEmitterGM107::emitDSETP()
1169 {
1170 const CmpInstruction *insn = this->insn->asCmp();
1171
1172 switch (insn->src(1).getFile()) {
1173 case FILE_GPR:
1174 emitInsn(0x5b800000);
1175 emitGPR (0x14, insn->src(1));
1176 break;
1177 case FILE_MEMORY_CONST:
1178 emitInsn(0x4b800000);
1179 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1180 break;
1181 case FILE_IMMEDIATE:
1182 emitInsn(0x36800000);
1183 emitIMMD(0x14, 19, insn->src(1));
1184 break;
1185 default:
1186 assert(!"bad src1 file");
1187 break;
1188 }
1189
1190 if (insn->op != OP_SET) {
1191 switch (insn->op) {
1192 case OP_SET_AND: emitField(0x2d, 2, 0); break;
1193 case OP_SET_OR : emitField(0x2d, 2, 1); break;
1194 case OP_SET_XOR: emitField(0x2d, 2, 2); break;
1195 default:
1196 assert(!"invalid set op");
1197 break;
1198 }
1199 emitPRED(0x27, insn->src(2));
1200 } else {
1201 emitPRED(0x27);
1202 }
1203
1204 emitCond4(0x30, insn->setCond);
1205 emitABS (0x2c, insn->src(1));
1206 emitNEG (0x2b, insn->src(0));
1207 emitGPR (0x08, insn->src(0));
1208 emitABS (0x07, insn->src(0));
1209 emitNEG (0x06, insn->src(1));
1210 emitPRED (0x03, insn->def(0));
1211 if (insn->defExists(1))
1212 emitPRED(0x00, insn->def(1));
1213 else
1214 emitPRED(0x00);
1215 }
1216
1217 /*******************************************************************************
1218 * float
1219 ******************************************************************************/
1220
1221 void
1222 CodeEmitterGM107::emitFADD()
1223 {
1224 if (!longIMMD(insn->src(1))) {
1225 switch (insn->src(1).getFile()) {
1226 case FILE_GPR:
1227 emitInsn(0x5c580000);
1228 emitGPR (0x14, insn->src(1));
1229 break;
1230 case FILE_MEMORY_CONST:
1231 emitInsn(0x4c580000);
1232 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1233 break;
1234 case FILE_IMMEDIATE:
1235 emitInsn(0x38580000);
1236 emitIMMD(0x14, 19, insn->src(1));
1237 break;
1238 default:
1239 assert(!"bad src1 file");
1240 break;
1241 }
1242 emitSAT(0x32);
1243 emitABS(0x31, insn->src(1));
1244 emitNEG(0x30, insn->src(0));
1245 emitCC (0x2f);
1246 emitABS(0x2e, insn->src(0));
1247 emitNEG(0x2d, insn->src(1));
1248 emitFMZ(0x2c, 1);
1249
1250 if (insn->op == OP_SUB)
1251 code[1] ^= 0x00002000;
1252 } else {
1253 emitInsn(0x08000000);
1254 emitABS(0x39, insn->src(1));
1255 emitNEG(0x38, insn->src(0));
1256 emitFMZ(0x37, 1);
1257 emitABS(0x36, insn->src(0));
1258 emitNEG(0x35, insn->src(1));
1259 emitCC (0x34);
1260 emitIMMD(0x14, 32, insn->src(1));
1261
1262 if (insn->op == OP_SUB)
1263 code[1] ^= 0x00080000;
1264 }
1265
1266 emitGPR(0x08, insn->src(0));
1267 emitGPR(0x00, insn->def(0));
1268 }
1269
1270 void
1271 CodeEmitterGM107::emitFMUL()
1272 {
1273 if (!longIMMD(insn->src(1))) {
1274 switch (insn->src(1).getFile()) {
1275 case FILE_GPR:
1276 emitInsn(0x5c680000);
1277 emitGPR (0x14, insn->src(1));
1278 break;
1279 case FILE_MEMORY_CONST:
1280 emitInsn(0x4c680000);
1281 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1282 break;
1283 case FILE_IMMEDIATE:
1284 emitInsn(0x38680000);
1285 emitIMMD(0x14, 19, insn->src(1));
1286 break;
1287 default:
1288 assert(!"bad src1 file");
1289 break;
1290 }
1291 emitSAT (0x32);
1292 emitNEG2(0x30, insn->src(0), insn->src(1));
1293 emitCC (0x2f);
1294 emitFMZ (0x2c, 2);
1295 emitPDIV(0x29);
1296 emitRND (0x27);
1297 } else {
1298 emitInsn(0x1e000000);
1299 emitSAT (0x37);
1300 emitFMZ (0x35, 2);
1301 emitCC (0x34);
1302 emitIMMD(0x14, 32, insn->src(1));
1303 if (insn->src(0).mod.neg() ^ insn->src(1).mod.neg())
1304 code[1] ^= 0x00080000; /* flip immd sign bit */
1305 }
1306
1307 emitGPR(0x08, insn->src(0));
1308 emitGPR(0x00, insn->def(0));
1309 }
1310
1311 void
1312 CodeEmitterGM107::emitFFMA()
1313 {
1314 bool isLongIMMD = false;
1315 switch(insn->src(2).getFile()) {
1316 case FILE_GPR:
1317 switch (insn->src(1).getFile()) {
1318 case FILE_GPR:
1319 emitInsn(0x59800000);
1320 emitGPR (0x14, insn->src(1));
1321 break;
1322 case FILE_MEMORY_CONST:
1323 emitInsn(0x49800000);
1324 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1325 break;
1326 case FILE_IMMEDIATE:
1327 if (longIMMD(insn->getSrc(1))) {
1328 assert(insn->getDef(0)->reg.data.id == insn->getSrc(2)->reg.data.id);
1329 isLongIMMD = true;
1330 emitInsn(0x0c000000);
1331 emitIMMD(0x14, 32, insn->src(1));
1332 } else {
1333 emitInsn(0x32800000);
1334 emitIMMD(0x14, 19, insn->src(1));
1335 }
1336 break;
1337 default:
1338 assert(!"bad src1 file");
1339 break;
1340 }
1341 if (!isLongIMMD)
1342 emitGPR (0x27, insn->src(2));
1343 break;
1344 case FILE_MEMORY_CONST:
1345 emitInsn(0x51800000);
1346 emitGPR (0x27, insn->src(1));
1347 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(2));
1348 break;
1349 default:
1350 assert(!"bad src2 file");
1351 break;
1352 }
1353
1354 if (isLongIMMD) {
1355 emitNEG (0x39, insn->src(2));
1356 emitNEG2(0x38, insn->src(0), insn->src(1));
1357 emitSAT (0x37);
1358 emitCC (0x34);
1359 } else {
1360 emitRND (0x33);
1361 emitSAT (0x32);
1362 emitNEG (0x31, insn->src(2));
1363 emitNEG2(0x30, insn->src(0), insn->src(1));
1364 emitCC (0x2f);
1365 }
1366
1367 emitFMZ(0x35, 2);
1368 emitGPR(0x08, insn->src(0));
1369 emitGPR(0x00, insn->def(0));
1370 }
1371
1372 void
1373 CodeEmitterGM107::emitMUFU()
1374 {
1375 int mufu = 0;
1376
1377 switch (insn->op) {
1378 case OP_COS: mufu = 0; break;
1379 case OP_SIN: mufu = 1; break;
1380 case OP_EX2: mufu = 2; break;
1381 case OP_LG2: mufu = 3; break;
1382 case OP_RCP: mufu = 4 + 2 * insn->subOp; break;
1383 case OP_RSQ: mufu = 5 + 2 * insn->subOp; break;
1384 default:
1385 assert(!"invalid mufu");
1386 break;
1387 }
1388
1389 emitInsn (0x50800000);
1390 emitSAT (0x32);
1391 emitNEG (0x30, insn->src(0));
1392 emitABS (0x2e, insn->src(0));
1393 emitField(0x14, 3, mufu);
1394 emitGPR (0x08, insn->src(0));
1395 emitGPR (0x00, insn->def(0));
1396 }
1397
1398 void
1399 CodeEmitterGM107::emitFMNMX()
1400 {
1401 switch (insn->src(1).getFile()) {
1402 case FILE_GPR:
1403 emitInsn(0x5c600000);
1404 emitGPR (0x14, insn->src(1));
1405 break;
1406 case FILE_MEMORY_CONST:
1407 emitInsn(0x4c600000);
1408 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1409 break;
1410 case FILE_IMMEDIATE:
1411 emitInsn(0x38600000);
1412 emitIMMD(0x14, 19, insn->src(1));
1413 break;
1414 default:
1415 assert(!"bad src1 file");
1416 break;
1417 }
1418
1419 emitField(0x2a, 1, insn->op == OP_MAX);
1420 emitPRED (0x27);
1421
1422 emitABS(0x31, insn->src(1));
1423 emitNEG(0x30, insn->src(0));
1424 emitCC (0x2f);
1425 emitABS(0x2e, insn->src(0));
1426 emitNEG(0x2d, insn->src(1));
1427 emitFMZ(0x2c, 1);
1428 emitGPR(0x08, insn->src(0));
1429 emitGPR(0x00, insn->def(0));
1430 }
1431
1432 void
1433 CodeEmitterGM107::emitRRO()
1434 {
1435 switch (insn->src(0).getFile()) {
1436 case FILE_GPR:
1437 emitInsn(0x5c900000);
1438 emitGPR (0x14, insn->src(0));
1439 break;
1440 case FILE_MEMORY_CONST:
1441 emitInsn(0x4c900000);
1442 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
1443 break;
1444 case FILE_IMMEDIATE:
1445 emitInsn(0x38900000);
1446 emitIMMD(0x14, 19, insn->src(0));
1447 break;
1448 default:
1449 assert(!"bad src file");
1450 break;
1451 }
1452
1453 emitABS (0x31, insn->src(0));
1454 emitNEG (0x2d, insn->src(0));
1455 emitField(0x27, 1, insn->op == OP_PREEX2);
1456 emitGPR (0x00, insn->def(0));
1457 }
1458
1459 void
1460 CodeEmitterGM107::emitFCMP()
1461 {
1462 const CmpInstruction *insn = this->insn->asCmp();
1463 CondCode cc = insn->setCond;
1464
1465 if (insn->src(2).mod.neg())
1466 cc = reverseCondCode(cc);
1467
1468 switch(insn->src(2).getFile()) {
1469 case FILE_GPR:
1470 switch (insn->src(1).getFile()) {
1471 case FILE_GPR:
1472 emitInsn(0x5ba00000);
1473 emitGPR (0x14, insn->src(1));
1474 break;
1475 case FILE_MEMORY_CONST:
1476 emitInsn(0x4ba00000);
1477 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1478 break;
1479 case FILE_IMMEDIATE:
1480 emitInsn(0x36a00000);
1481 emitIMMD(0x14, 19, insn->src(1));
1482 break;
1483 default:
1484 assert(!"bad src1 file");
1485 break;
1486 }
1487 emitGPR (0x27, insn->src(2));
1488 break;
1489 case FILE_MEMORY_CONST:
1490 emitInsn(0x53a00000);
1491 emitGPR (0x27, insn->src(1));
1492 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(2));
1493 break;
1494 default:
1495 assert(!"bad src2 file");
1496 break;
1497 }
1498
1499 emitCond4(0x30, cc);
1500 emitFMZ (0x2f, 1);
1501 emitGPR (0x08, insn->src(0));
1502 emitGPR (0x00, insn->def(0));
1503 }
1504
1505 void
1506 CodeEmitterGM107::emitFSET()
1507 {
1508 const CmpInstruction *insn = this->insn->asCmp();
1509
1510 switch (insn->src(1).getFile()) {
1511 case FILE_GPR:
1512 emitInsn(0x58000000);
1513 emitGPR (0x14, insn->src(1));
1514 break;
1515 case FILE_MEMORY_CONST:
1516 emitInsn(0x48000000);
1517 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1518 break;
1519 case FILE_IMMEDIATE:
1520 emitInsn(0x30000000);
1521 emitIMMD(0x14, 19, insn->src(1));
1522 break;
1523 default:
1524 assert(!"bad src1 file");
1525 break;
1526 }
1527
1528 if (insn->op != OP_SET) {
1529 switch (insn->op) {
1530 case OP_SET_AND: emitField(0x2d, 2, 0); break;
1531 case OP_SET_OR : emitField(0x2d, 2, 1); break;
1532 case OP_SET_XOR: emitField(0x2d, 2, 2); break;
1533 default:
1534 assert(!"invalid set op");
1535 break;
1536 }
1537 emitPRED(0x27, insn->src(2));
1538 } else {
1539 emitPRED(0x27);
1540 }
1541
1542 emitFMZ (0x37, 1);
1543 emitABS (0x36, insn->src(0));
1544 emitNEG (0x35, insn->src(1));
1545 emitField(0x34, 1, insn->dType == TYPE_F32);
1546 emitCond4(0x30, insn->setCond);
1547 emitCC (0x2f);
1548 emitABS (0x2c, insn->src(1));
1549 emitNEG (0x2b, insn->src(0));
1550 emitGPR (0x08, insn->src(0));
1551 emitGPR (0x00, insn->def(0));
1552 }
1553
1554 void
1555 CodeEmitterGM107::emitFSETP()
1556 {
1557 const CmpInstruction *insn = this->insn->asCmp();
1558
1559 switch (insn->src(1).getFile()) {
1560 case FILE_GPR:
1561 emitInsn(0x5bb00000);
1562 emitGPR (0x14, insn->src(1));
1563 break;
1564 case FILE_MEMORY_CONST:
1565 emitInsn(0x4bb00000);
1566 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1567 break;
1568 case FILE_IMMEDIATE:
1569 emitInsn(0x36b00000);
1570 emitIMMD(0x14, 19, insn->src(1));
1571 break;
1572 default:
1573 assert(!"bad src1 file");
1574 break;
1575 }
1576
1577 if (insn->op != OP_SET) {
1578 switch (insn->op) {
1579 case OP_SET_AND: emitField(0x2d, 2, 0); break;
1580 case OP_SET_OR : emitField(0x2d, 2, 1); break;
1581 case OP_SET_XOR: emitField(0x2d, 2, 2); break;
1582 default:
1583 assert(!"invalid set op");
1584 break;
1585 }
1586 emitPRED(0x27, insn->src(2));
1587 } else {
1588 emitPRED(0x27);
1589 }
1590
1591 emitCond4(0x30, insn->setCond);
1592 emitFMZ (0x2f, 1);
1593 emitABS (0x2c, insn->src(1));
1594 emitNEG (0x2b, insn->src(0));
1595 emitGPR (0x08, insn->src(0));
1596 emitABS (0x07, insn->src(0));
1597 emitNEG (0x06, insn->src(1));
1598 emitPRED (0x03, insn->def(0));
1599 if (insn->defExists(1))
1600 emitPRED(0x00, insn->def(1));
1601 else
1602 emitPRED(0x00);
1603 }
1604
1605 void
1606 CodeEmitterGM107::emitFSWZADD()
1607 {
1608 emitInsn (0x50f80000);
1609 emitCC (0x2f);
1610 emitFMZ (0x2c, 1);
1611 emitRND (0x27);
1612 emitField(0x26, 1, insn->lanes); /* abused for .ndv */
1613 emitField(0x1c, 8, insn->subOp);
1614 if (insn->predSrc != 1)
1615 emitGPR (0x14, insn->src(1));
1616 else
1617 emitGPR (0x14);
1618 emitGPR (0x08, insn->src(0));
1619 emitGPR (0x00, insn->def(0));
1620 }
1621
1622 /*******************************************************************************
1623 * integer
1624 ******************************************************************************/
1625
1626 void
1627 CodeEmitterGM107::emitLOP()
1628 {
1629 int lop = 0;
1630
1631 switch (insn->op) {
1632 case OP_AND: lop = 0; break;
1633 case OP_OR : lop = 1; break;
1634 case OP_XOR: lop = 2; break;
1635 default:
1636 assert(!"invalid lop");
1637 break;
1638 }
1639
1640 if (insn->src(1).getFile() != FILE_IMMEDIATE) {
1641 switch (insn->src(1).getFile()) {
1642 case FILE_GPR:
1643 emitInsn(0x5c400000);
1644 emitGPR (0x14, insn->src(1));
1645 break;
1646 case FILE_MEMORY_CONST:
1647 emitInsn(0x4c400000);
1648 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1649 break;
1650 case FILE_IMMEDIATE:
1651 emitInsn(0x38400000);
1652 emitIMMD(0x14, 19, insn->src(1));
1653 break;
1654 default:
1655 assert(!"bad src1 file");
1656 break;
1657 }
1658 emitPRED (0x30);
1659 emitCC (0x2f);
1660 emitX (0x2b);
1661 emitField(0x29, 2, lop);
1662 emitINV (0x28, insn->src(1));
1663 emitINV (0x27, insn->src(0));
1664 } else {
1665 emitInsn (0x04000000);
1666 emitX (0x39);
1667 emitINV (0x38, insn->src(1));
1668 emitINV (0x37, insn->src(0));
1669 emitField(0x35, 2, lop);
1670 emitCC (0x34);
1671 emitIMMD (0x14, 32, insn->src(1));
1672 }
1673
1674 emitGPR (0x08, insn->src(0));
1675 emitGPR (0x00, insn->def(0));
1676 }
1677
1678 /* special-case of emitLOP(): lop pass_b dst 0 ~src */
1679 void
1680 CodeEmitterGM107::emitNOT()
1681 {
1682 if (!longIMMD(insn->src(0))) {
1683 switch (insn->src(0).getFile()) {
1684 case FILE_GPR:
1685 emitInsn(0x5c400700);
1686 emitGPR (0x14, insn->src(0));
1687 break;
1688 case FILE_MEMORY_CONST:
1689 emitInsn(0x4c400700);
1690 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
1691 break;
1692 case FILE_IMMEDIATE:
1693 emitInsn(0x38400700);
1694 emitIMMD(0x14, 19, insn->src(0));
1695 break;
1696 default:
1697 assert(!"bad src1 file");
1698 break;
1699 }
1700 emitPRED (0x30);
1701 } else {
1702 emitInsn (0x05600000);
1703 emitIMMD (0x14, 32, insn->src(1));
1704 }
1705
1706 emitGPR(0x08);
1707 emitGPR(0x00, insn->def(0));
1708 }
1709
1710 void
1711 CodeEmitterGM107::emitIADD()
1712 {
1713 if (insn->src(1).getFile() != FILE_IMMEDIATE) {
1714 switch (insn->src(1).getFile()) {
1715 case FILE_GPR:
1716 emitInsn(0x5c100000);
1717 emitGPR (0x14, insn->src(1));
1718 break;
1719 case FILE_MEMORY_CONST:
1720 emitInsn(0x4c100000);
1721 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1722 break;
1723 case FILE_IMMEDIATE:
1724 emitInsn(0x38100000);
1725 emitIMMD(0x14, 19, insn->src(1));
1726 break;
1727 default:
1728 assert(!"bad src1 file");
1729 break;
1730 }
1731 emitSAT(0x32);
1732 emitNEG(0x31, insn->src(0));
1733 emitNEG(0x30, insn->src(1));
1734 emitCC (0x2f);
1735 emitX (0x2b);
1736 } else {
1737 emitInsn(0x1c000000);
1738 emitNEG (0x38, insn->src(0));
1739 emitSAT (0x36);
1740 emitX (0x35);
1741 emitCC (0x34);
1742 emitIMMD(0x14, 32, insn->src(1));
1743 }
1744
1745 if (insn->op == OP_SUB)
1746 code[1] ^= 0x00010000;
1747
1748 emitGPR(0x08, insn->src(0));
1749 emitGPR(0x00, insn->def(0));
1750 }
1751
1752 void
1753 CodeEmitterGM107::emitIMUL()
1754 {
1755 if (insn->src(1).getFile() != FILE_IMMEDIATE) {
1756 switch (insn->src(1).getFile()) {
1757 case FILE_GPR:
1758 emitInsn(0x5c380000);
1759 emitGPR (0x14, insn->src(1));
1760 break;
1761 case FILE_MEMORY_CONST:
1762 emitInsn(0x4c380000);
1763 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1764 break;
1765 case FILE_IMMEDIATE:
1766 emitInsn(0x38380000);
1767 emitIMMD(0x14, 19, insn->src(1));
1768 break;
1769 default:
1770 assert(!"bad src1 file");
1771 break;
1772 }
1773 emitCC (0x2f);
1774 emitField(0x29, 1, isSignedType(insn->sType));
1775 emitField(0x28, 1, isSignedType(insn->dType));
1776 emitField(0x27, 1, insn->subOp == NV50_IR_SUBOP_MUL_HIGH);
1777 } else {
1778 emitInsn (0x1f000000);
1779 emitField(0x37, 1, isSignedType(insn->sType));
1780 emitField(0x36, 1, isSignedType(insn->dType));
1781 emitField(0x35, 1, insn->subOp == NV50_IR_SUBOP_MUL_HIGH);
1782 emitCC (0x34);
1783 emitIMMD (0x14, 32, insn->src(1));
1784 }
1785
1786 emitGPR(0x08, insn->src(0));
1787 emitGPR(0x00, insn->def(0));
1788 }
1789
1790 void
1791 CodeEmitterGM107::emitIMAD()
1792 {
1793 /*XXX: imad32i exists, but not using it as third src overlaps dst */
1794 switch(insn->src(2).getFile()) {
1795 case FILE_GPR:
1796 switch (insn->src(1).getFile()) {
1797 case FILE_GPR:
1798 emitInsn(0x5a000000);
1799 emitGPR (0x14, insn->src(1));
1800 break;
1801 case FILE_MEMORY_CONST:
1802 emitInsn(0x4a000000);
1803 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1804 break;
1805 case FILE_IMMEDIATE:
1806 emitInsn(0x34000000);
1807 emitIMMD(0x14, 19, insn->src(1));
1808 break;
1809 default:
1810 assert(!"bad src1 file");
1811 break;
1812 }
1813 emitGPR (0x27, insn->src(2));
1814 break;
1815 case FILE_MEMORY_CONST:
1816 emitInsn(0x52000000);
1817 emitGPR (0x27, insn->src(1));
1818 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(2));
1819 break;
1820 default:
1821 assert(!"bad src2 file");
1822 break;
1823 }
1824
1825 emitField(0x36, 1, insn->subOp == NV50_IR_SUBOP_MUL_HIGH);
1826 emitField(0x35, 1, isSignedType(insn->sType));
1827 emitNEG (0x34, insn->src(2));
1828 emitNEG2 (0x33, insn->src(0), insn->src(1));
1829 emitSAT (0x32);
1830 emitX (0x31);
1831 emitField(0x30, 1, isSignedType(insn->dType));
1832 emitCC (0x2f);
1833 emitGPR (0x08, insn->src(0));
1834 emitGPR (0x00, insn->def(0));
1835 }
1836
1837 void
1838 CodeEmitterGM107::emitISCADD()
1839 {
1840 switch (insn->src(2).getFile()) {
1841 case FILE_GPR:
1842 emitInsn(0x5c180000);
1843 emitGPR (0x14, insn->src(2));
1844 break;
1845 case FILE_MEMORY_CONST:
1846 emitInsn(0x4c180000);
1847 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(2));
1848 break;
1849 case FILE_IMMEDIATE:
1850 emitInsn(0x38180000);
1851 emitIMMD(0x14, 19, insn->src(2));
1852 break;
1853 default:
1854 assert(!"bad src1 file");
1855 break;
1856 }
1857 emitNEG (0x31, insn->src(0));
1858 emitNEG (0x30, insn->src(2));
1859 emitCC (0x2f);
1860 emitIMMD(0x27, 5, insn->src(1));
1861 emitGPR (0x08, insn->src(0));
1862 emitGPR (0x00, insn->def(0));
1863 }
1864
1865 void
1866 CodeEmitterGM107::emitIMNMX()
1867 {
1868 switch (insn->src(1).getFile()) {
1869 case FILE_GPR:
1870 emitInsn(0x5c200000);
1871 emitGPR (0x14, insn->src(1));
1872 break;
1873 case FILE_MEMORY_CONST:
1874 emitInsn(0x4c200000);
1875 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1876 break;
1877 case FILE_IMMEDIATE:
1878 emitInsn(0x38200000);
1879 emitIMMD(0x14, 19, insn->src(1));
1880 break;
1881 default:
1882 assert(!"bad src1 file");
1883 break;
1884 }
1885
1886 emitField(0x30, 1, isSignedType(insn->dType));
1887 emitCC (0x2f);
1888 emitField(0x2b, 2, insn->subOp);
1889 emitField(0x2a, 1, insn->op == OP_MAX);
1890 emitPRED (0x27);
1891 emitGPR (0x08, insn->src(0));
1892 emitGPR (0x00, insn->def(0));
1893 }
1894
1895 void
1896 CodeEmitterGM107::emitICMP()
1897 {
1898 const CmpInstruction *insn = this->insn->asCmp();
1899 CondCode cc = insn->setCond;
1900
1901 if (insn->src(2).mod.neg())
1902 cc = reverseCondCode(cc);
1903
1904 switch(insn->src(2).getFile()) {
1905 case FILE_GPR:
1906 switch (insn->src(1).getFile()) {
1907 case FILE_GPR:
1908 emitInsn(0x5b400000);
1909 emitGPR (0x14, insn->src(1));
1910 break;
1911 case FILE_MEMORY_CONST:
1912 emitInsn(0x4b400000);
1913 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1914 break;
1915 case FILE_IMMEDIATE:
1916 emitInsn(0x36400000);
1917 emitIMMD(0x14, 19, insn->src(1));
1918 break;
1919 default:
1920 assert(!"bad src1 file");
1921 break;
1922 }
1923 emitGPR (0x27, insn->src(2));
1924 break;
1925 case FILE_MEMORY_CONST:
1926 emitInsn(0x53400000);
1927 emitGPR (0x27, insn->src(1));
1928 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(2));
1929 break;
1930 default:
1931 assert(!"bad src2 file");
1932 break;
1933 }
1934
1935 emitCond3(0x31, cc);
1936 emitField(0x30, 1, isSignedType(insn->sType));
1937 emitGPR (0x08, insn->src(0));
1938 emitGPR (0x00, insn->def(0));
1939 }
1940
1941 void
1942 CodeEmitterGM107::emitISET()
1943 {
1944 const CmpInstruction *insn = this->insn->asCmp();
1945
1946 switch (insn->src(1).getFile()) {
1947 case FILE_GPR:
1948 emitInsn(0x5b500000);
1949 emitGPR (0x14, insn->src(1));
1950 break;
1951 case FILE_MEMORY_CONST:
1952 emitInsn(0x4b500000);
1953 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1954 break;
1955 case FILE_IMMEDIATE:
1956 emitInsn(0x36500000);
1957 emitIMMD(0x14, 19, insn->src(1));
1958 break;
1959 default:
1960 assert(!"bad src1 file");
1961 break;
1962 }
1963
1964 if (insn->op != OP_SET) {
1965 switch (insn->op) {
1966 case OP_SET_AND: emitField(0x2d, 2, 0); break;
1967 case OP_SET_OR : emitField(0x2d, 2, 1); break;
1968 case OP_SET_XOR: emitField(0x2d, 2, 2); break;
1969 default:
1970 assert(!"invalid set op");
1971 break;
1972 }
1973 emitPRED(0x27, insn->src(2));
1974 } else {
1975 emitPRED(0x27);
1976 }
1977
1978 emitCond3(0x31, insn->setCond);
1979 emitField(0x30, 1, isSignedType(insn->sType));
1980 emitCC (0x2f);
1981 emitField(0x2c, 1, insn->dType == TYPE_F32);
1982 emitX (0x2b);
1983 emitGPR (0x08, insn->src(0));
1984 emitGPR (0x00, insn->def(0));
1985 }
1986
1987 void
1988 CodeEmitterGM107::emitISETP()
1989 {
1990 const CmpInstruction *insn = this->insn->asCmp();
1991
1992 switch (insn->src(1).getFile()) {
1993 case FILE_GPR:
1994 emitInsn(0x5b600000);
1995 emitGPR (0x14, insn->src(1));
1996 break;
1997 case FILE_MEMORY_CONST:
1998 emitInsn(0x4b600000);
1999 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
2000 break;
2001 case FILE_IMMEDIATE:
2002 emitInsn(0x36600000);
2003 emitIMMD(0x14, 19, insn->src(1));
2004 break;
2005 default:
2006 assert(!"bad src1 file");
2007 break;
2008 }
2009
2010 if (insn->op != OP_SET) {
2011 switch (insn->op) {
2012 case OP_SET_AND: emitField(0x2d, 2, 0); break;
2013 case OP_SET_OR : emitField(0x2d, 2, 1); break;
2014 case OP_SET_XOR: emitField(0x2d, 2, 2); break;
2015 default:
2016 assert(!"invalid set op");
2017 break;
2018 }
2019 emitPRED(0x27, insn->src(2));
2020 } else {
2021 emitPRED(0x27);
2022 }
2023
2024 emitCond3(0x31, insn->setCond);
2025 emitField(0x30, 1, isSignedType(insn->sType));
2026 emitX (0x2b);
2027 emitGPR (0x08, insn->src(0));
2028 emitPRED (0x03, insn->def(0));
2029 if (insn->defExists(1))
2030 emitPRED(0x00, insn->def(1));
2031 else
2032 emitPRED(0x00);
2033 }
2034
2035 void
2036 CodeEmitterGM107::emitSHL()
2037 {
2038 switch (insn->src(1).getFile()) {
2039 case FILE_GPR:
2040 emitInsn(0x5c480000);
2041 emitGPR (0x14, insn->src(1));
2042 break;
2043 case FILE_MEMORY_CONST:
2044 emitInsn(0x4c480000);
2045 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
2046 break;
2047 case FILE_IMMEDIATE:
2048 emitInsn(0x38480000);
2049 emitIMMD(0x14, 19, insn->src(1));
2050 break;
2051 default:
2052 assert(!"bad src1 file");
2053 break;
2054 }
2055
2056 emitCC (0x2f);
2057 emitX (0x2b);
2058 emitField(0x27, 1, insn->subOp == NV50_IR_SUBOP_SHIFT_WRAP);
2059 emitGPR (0x08, insn->src(0));
2060 emitGPR (0x00, insn->def(0));
2061 }
2062
2063 void
2064 CodeEmitterGM107::emitSHR()
2065 {
2066 switch (insn->src(1).getFile()) {
2067 case FILE_GPR:
2068 emitInsn(0x5c280000);
2069 emitGPR (0x14, insn->src(1));
2070 break;
2071 case FILE_MEMORY_CONST:
2072 emitInsn(0x4c280000);
2073 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
2074 break;
2075 case FILE_IMMEDIATE:
2076 emitInsn(0x38280000);
2077 emitIMMD(0x14, 19, insn->src(1));
2078 break;
2079 default:
2080 assert(!"bad src1 file");
2081 break;
2082 }
2083
2084 emitField(0x30, 1, isSignedType(insn->dType));
2085 emitCC (0x2f);
2086 emitX (0x2c);
2087 emitField(0x27, 1, insn->subOp == NV50_IR_SUBOP_SHIFT_WRAP);
2088 emitGPR (0x08, insn->src(0));
2089 emitGPR (0x00, insn->def(0));
2090 }
2091
2092 void
2093 CodeEmitterGM107::emitSHF()
2094 {
2095 unsigned type;
2096
2097 switch (insn->src(1).getFile()) {
2098 case FILE_GPR:
2099 emitInsn(insn->op == OP_SHL ? 0x5bf80000 : 0x5cf80000);
2100 emitGPR(0x14, insn->src(1));
2101 break;
2102 case FILE_IMMEDIATE:
2103 emitInsn(insn->op == OP_SHL ? 0x36f80000 : 0x38f80000);
2104 emitIMMD(0x14, 19, insn->src(1));
2105 break;
2106 default:
2107 assert(!"bad src1 file");
2108 break;
2109 }
2110
2111 switch (insn->sType) {
2112 case TYPE_U64:
2113 type = 2;
2114 break;
2115 case TYPE_S64:
2116 type = 3;
2117 break;
2118 default:
2119 type = 0;
2120 break;
2121 }
2122
2123 emitField(0x32, 1, !!(insn->subOp & NV50_IR_SUBOP_SHIFT_WRAP));
2124 emitX (0x31);
2125 emitField(0x30, 1, !!(insn->subOp & NV50_IR_SUBOP_SHIFT_HIGH));
2126 emitCC (0x2f);
2127 emitGPR (0x27, insn->src(2));
2128 emitField(0x25, 2, type);
2129 emitGPR (0x08, insn->src(0));
2130 emitGPR (0x00, insn->def(0));
2131 }
2132
2133 void
2134 CodeEmitterGM107::emitPOPC()
2135 {
2136 switch (insn->src(0).getFile()) {
2137 case FILE_GPR:
2138 emitInsn(0x5c080000);
2139 emitGPR (0x14, insn->src(0));
2140 break;
2141 case FILE_MEMORY_CONST:
2142 emitInsn(0x4c080000);
2143 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
2144 break;
2145 case FILE_IMMEDIATE:
2146 emitInsn(0x38080000);
2147 emitIMMD(0x14, 19, insn->src(0));
2148 break;
2149 default:
2150 assert(!"bad src1 file");
2151 break;
2152 }
2153
2154 emitINV(0x28, insn->src(0));
2155 emitGPR(0x00, insn->def(0));
2156 }
2157
2158 void
2159 CodeEmitterGM107::emitBFI()
2160 {
2161 switch(insn->src(2).getFile()) {
2162 case FILE_GPR:
2163 switch (insn->src(1).getFile()) {
2164 case FILE_GPR:
2165 emitInsn(0x5bf00000);
2166 emitGPR (0x14, insn->src(1));
2167 break;
2168 case FILE_MEMORY_CONST:
2169 emitInsn(0x4bf00000);
2170 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
2171 break;
2172 case FILE_IMMEDIATE:
2173 emitInsn(0x36f00000);
2174 emitIMMD(0x14, 19, insn->src(1));
2175 break;
2176 default:
2177 assert(!"bad src1 file");
2178 break;
2179 }
2180 emitGPR (0x27, insn->src(2));
2181 break;
2182 case FILE_MEMORY_CONST:
2183 emitInsn(0x53f00000);
2184 emitGPR (0x27, insn->src(1));
2185 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(2));
2186 break;
2187 default:
2188 assert(!"bad src2 file");
2189 break;
2190 }
2191
2192 emitCC (0x2f);
2193 emitGPR (0x08, insn->src(0));
2194 emitGPR (0x00, insn->def(0));
2195 }
2196
2197 void
2198 CodeEmitterGM107::emitBFE()
2199 {
2200 switch (insn->src(1).getFile()) {
2201 case FILE_GPR:
2202 emitInsn(0x5c000000);
2203 emitGPR (0x14, insn->src(1));
2204 break;
2205 case FILE_MEMORY_CONST:
2206 emitInsn(0x4c000000);
2207 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
2208 break;
2209 case FILE_IMMEDIATE:
2210 emitInsn(0x38000000);
2211 emitIMMD(0x14, 19, insn->src(1));
2212 break;
2213 default:
2214 assert(!"bad src1 file");
2215 break;
2216 }
2217
2218 emitField(0x30, 1, isSignedType(insn->dType));
2219 emitCC (0x2f);
2220 emitField(0x28, 1, insn->subOp == NV50_IR_SUBOP_EXTBF_REV);
2221 emitGPR (0x08, insn->src(0));
2222 emitGPR (0x00, insn->def(0));
2223 }
2224
2225 void
2226 CodeEmitterGM107::emitFLO()
2227 {
2228 switch (insn->src(0).getFile()) {
2229 case FILE_GPR:
2230 emitInsn(0x5c300000);
2231 emitGPR (0x14, insn->src(0));
2232 break;
2233 case FILE_MEMORY_CONST:
2234 emitInsn(0x4c300000);
2235 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
2236 break;
2237 case FILE_IMMEDIATE:
2238 emitInsn(0x38300000);
2239 emitIMMD(0x14, 19, insn->src(0));
2240 break;
2241 default:
2242 assert(!"bad src1 file");
2243 break;
2244 }
2245
2246 emitField(0x30, 1, isSignedType(insn->dType));
2247 emitCC (0x2f);
2248 emitField(0x29, 1, insn->subOp == NV50_IR_SUBOP_BFIND_SAMT);
2249 emitINV (0x28, insn->src(0));
2250 emitGPR (0x00, insn->def(0));
2251 }
2252
2253 /*******************************************************************************
2254 * memory
2255 ******************************************************************************/
2256
2257 void
2258 CodeEmitterGM107::emitLDSTs(int pos, DataType type)
2259 {
2260 int data = 0;
2261
2262 switch (typeSizeof(type)) {
2263 case 1: data = isSignedType(type) ? 1 : 0; break;
2264 case 2: data = isSignedType(type) ? 3 : 2; break;
2265 case 4: data = 4; break;
2266 case 8: data = 5; break;
2267 case 16: data = 6; break;
2268 default:
2269 assert(!"bad type");
2270 break;
2271 }
2272
2273 emitField(pos, 3, data);
2274 }
2275
2276 void
2277 CodeEmitterGM107::emitLDSTc(int pos)
2278 {
2279 int mode = 0;
2280
2281 switch (insn->cache) {
2282 case CACHE_CA: mode = 0; break;
2283 case CACHE_CG: mode = 1; break;
2284 case CACHE_CS: mode = 2; break;
2285 case CACHE_CV: mode = 3; break;
2286 default:
2287 assert(!"invalid caching mode");
2288 break;
2289 }
2290
2291 emitField(pos, 2, mode);
2292 }
2293
2294 void
2295 CodeEmitterGM107::emitLDC()
2296 {
2297 emitInsn (0xef900000);
2298 emitLDSTs(0x30, insn->dType);
2299 emitField(0x2c, 2, insn->subOp);
2300 emitCBUF (0x24, 0x08, 0x14, 16, 0, insn->src(0));
2301 emitGPR (0x00, insn->def(0));
2302 }
2303
2304 void
2305 CodeEmitterGM107::emitLDL()
2306 {
2307 emitInsn (0xef400000);
2308 emitLDSTs(0x30, insn->dType);
2309 emitLDSTc(0x2c);
2310 emitADDR (0x08, 0x14, 24, 0, insn->src(0));
2311 emitGPR (0x00, insn->def(0));
2312 }
2313
2314 void
2315 CodeEmitterGM107::emitLDS()
2316 {
2317 emitInsn (0xef480000);
2318 emitLDSTs(0x30, insn->dType);
2319 emitADDR (0x08, 0x14, 24, 0, insn->src(0));
2320 emitGPR (0x00, insn->def(0));
2321 }
2322
2323 void
2324 CodeEmitterGM107::emitLD()
2325 {
2326 emitInsn (0x80000000);
2327 emitPRED (0x3a);
2328 emitLDSTc(0x38);
2329 emitLDSTs(0x35, insn->dType);
2330 emitField(0x34, 1, insn->src(0).getIndirect(0)->getSize() == 8);
2331 emitADDR (0x08, 0x14, 32, 0, insn->src(0));
2332 emitGPR (0x00, insn->def(0));
2333 }
2334
2335 void
2336 CodeEmitterGM107::emitSTL()
2337 {
2338 emitInsn (0xef500000);
2339 emitLDSTs(0x30, insn->dType);
2340 emitLDSTc(0x2c);
2341 emitADDR (0x08, 0x14, 24, 0, insn->src(0));
2342 emitGPR (0x00, insn->src(1));
2343 }
2344
2345 void
2346 CodeEmitterGM107::emitSTS()
2347 {
2348 emitInsn (0xef580000);
2349 emitLDSTs(0x30, insn->dType);
2350 emitADDR (0x08, 0x14, 24, 0, insn->src(0));
2351 emitGPR (0x00, insn->src(1));
2352 }
2353
2354 void
2355 CodeEmitterGM107::emitST()
2356 {
2357 emitInsn (0xa0000000);
2358 emitPRED (0x3a);
2359 emitLDSTc(0x38);
2360 emitLDSTs(0x35, insn->dType);
2361 emitField(0x34, 1, insn->src(0).getIndirect(0)->getSize() == 8);
2362 emitADDR (0x08, 0x14, 32, 0, insn->src(0));
2363 emitGPR (0x00, insn->src(1));
2364 }
2365
2366 void
2367 CodeEmitterGM107::emitALD()
2368 {
2369 emitInsn (0xefd80000);
2370 emitField(0x2f, 2, (insn->getDef(0)->reg.size / 4) - 1);
2371 emitGPR (0x27, insn->src(0).getIndirect(1));
2372 emitO (0x20);
2373 emitP (0x1f);
2374 emitADDR (0x08, 20, 10, 0, insn->src(0));
2375 emitGPR (0x00, insn->def(0));
2376 }
2377
2378 void
2379 CodeEmitterGM107::emitAST()
2380 {
2381 emitInsn (0xeff00000);
2382 emitField(0x2f, 2, (typeSizeof(insn->dType) / 4) - 1);
2383 emitGPR (0x27, insn->src(0).getIndirect(1));
2384 emitP (0x1f);
2385 emitADDR (0x08, 20, 10, 0, insn->src(0));
2386 emitGPR (0x00, insn->src(1));
2387 }
2388
2389 void
2390 CodeEmitterGM107::emitISBERD()
2391 {
2392 emitInsn(0xefd00000);
2393 emitGPR (0x08, insn->src(0));
2394 emitGPR (0x00, insn->def(0));
2395 }
2396
2397 void
2398 CodeEmitterGM107::emitAL2P()
2399 {
2400 emitInsn (0xefa00000);
2401 emitField(0x2f, 2, (insn->getDef(0)->reg.size / 4) - 1);
2402 emitPRED (0x2c);
2403 emitO (0x20);
2404 emitField(0x14, 11, insn->src(0).get()->reg.data.offset);
2405 emitGPR (0x08, insn->src(0).getIndirect(0));
2406 emitGPR (0x00, insn->def(0));
2407 }
2408
2409 static void
2410 interpApply(const FixupEntry *entry, uint32_t *code, const FixupData& data)
2411 {
2412 int ipa = entry->ipa;
2413 int reg = entry->reg;
2414 int loc = entry->loc;
2415
2416 if (data.flatshade &&
2417 (ipa & NV50_IR_INTERP_MODE_MASK) == NV50_IR_INTERP_SC) {
2418 ipa = NV50_IR_INTERP_FLAT;
2419 reg = 0xff;
2420 } else if (data.force_persample_interp &&
2421 (ipa & NV50_IR_INTERP_SAMPLE_MASK) == NV50_IR_INTERP_DEFAULT &&
2422 (ipa & NV50_IR_INTERP_MODE_MASK) != NV50_IR_INTERP_FLAT) {
2423 ipa |= NV50_IR_INTERP_CENTROID;
2424 }
2425 code[loc + 1] &= ~(0xf << 0x14);
2426 code[loc + 1] |= (ipa & 0x3) << 0x16;
2427 code[loc + 1] |= (ipa & 0xc) << (0x14 - 2);
2428 code[loc + 0] &= ~(0xff << 0x14);
2429 code[loc + 0] |= reg << 0x14;
2430 }
2431
2432 void
2433 CodeEmitterGM107::emitIPA()
2434 {
2435 int ipam = 0, ipas = 0;
2436
2437 switch (insn->getInterpMode()) {
2438 case NV50_IR_INTERP_LINEAR : ipam = 0; break;
2439 case NV50_IR_INTERP_PERSPECTIVE: ipam = 1; break;
2440 case NV50_IR_INTERP_FLAT : ipam = 2; break;
2441 case NV50_IR_INTERP_SC : ipam = 3; break;
2442 default:
2443 assert(!"invalid ipa mode");
2444 break;
2445 }
2446
2447 switch (insn->getSampleMode()) {
2448 case NV50_IR_INTERP_DEFAULT : ipas = 0; break;
2449 case NV50_IR_INTERP_CENTROID: ipas = 1; break;
2450 case NV50_IR_INTERP_OFFSET : ipas = 2; break;
2451 default:
2452 assert(!"invalid ipa sample mode");
2453 break;
2454 }
2455
2456 emitInsn (0xe0000000);
2457 emitField(0x36, 2, ipam);
2458 emitField(0x34, 2, ipas);
2459 emitSAT (0x33);
2460 emitField(0x2f, 3, 7);
2461 emitADDR (0x08, 0x1c, 10, 0, insn->src(0));
2462 if ((code[0] & 0x0000ff00) != 0x0000ff00)
2463 code[1] |= 0x00000040; /* .idx */
2464 emitGPR(0x00, insn->def(0));
2465
2466 if (insn->op == OP_PINTERP) {
2467 emitGPR(0x14, insn->src(1));
2468 if (insn->getSampleMode() == NV50_IR_INTERP_OFFSET)
2469 emitGPR(0x27, insn->src(2));
2470 addInterp(insn->ipa, insn->getSrc(1)->reg.data.id, interpApply);
2471 } else {
2472 if (insn->getSampleMode() == NV50_IR_INTERP_OFFSET)
2473 emitGPR(0x27, insn->src(1));
2474 emitGPR(0x14);
2475 addInterp(insn->ipa, 0xff, interpApply);
2476 }
2477
2478 if (insn->getSampleMode() != NV50_IR_INTERP_OFFSET)
2479 emitGPR(0x27);
2480 }
2481
2482 void
2483 CodeEmitterGM107::emitATOM()
2484 {
2485 unsigned dType, subOp;
2486
2487 if (insn->subOp == NV50_IR_SUBOP_ATOM_CAS) {
2488 switch (insn->dType) {
2489 case TYPE_U32: dType = 0; break;
2490 case TYPE_U64: dType = 1; break;
2491 default: assert(!"unexpected dType"); dType = 0; break;
2492 }
2493 subOp = 15;
2494
2495 emitInsn (0xee000000);
2496 } else {
2497 switch (insn->dType) {
2498 case TYPE_U32: dType = 0; break;
2499 case TYPE_S32: dType = 1; break;
2500 case TYPE_U64: dType = 2; break;
2501 case TYPE_F32: dType = 3; break;
2502 case TYPE_B128: dType = 4; break;
2503 case TYPE_S64: dType = 5; break;
2504 default: assert(!"unexpected dType"); dType = 0; break;
2505 }
2506 if (insn->subOp == NV50_IR_SUBOP_ATOM_EXCH)
2507 subOp = 8;
2508 else
2509 subOp = insn->subOp;
2510
2511 emitInsn (0xed000000);
2512 }
2513
2514 emitField(0x34, 4, subOp);
2515 emitField(0x31, 3, dType);
2516 emitField(0x30, 1, insn->src(0).getIndirect(0)->getSize() == 8);
2517 emitGPR (0x14, insn->src(1));
2518 emitADDR (0x08, 0x1c, 20, 0, insn->src(0));
2519 emitGPR (0x00, insn->def(0));
2520 }
2521
2522 void
2523 CodeEmitterGM107::emitATOMS()
2524 {
2525 unsigned dType, subOp;
2526
2527 if (insn->subOp == NV50_IR_SUBOP_ATOM_CAS) {
2528 switch (insn->dType) {
2529 case TYPE_U32: dType = 0; break;
2530 case TYPE_U64: dType = 1; break;
2531 default: assert(!"unexpected dType"); dType = 0; break;
2532 }
2533 subOp = 4;
2534
2535 emitInsn (0xee000000);
2536 emitField(0x34, 1, dType);
2537 } else {
2538 switch (insn->dType) {
2539 case TYPE_U32: dType = 0; break;
2540 case TYPE_S32: dType = 1; break;
2541 case TYPE_U64: dType = 2; break;
2542 case TYPE_S64: dType = 3; break;
2543 default: assert(!"unexpected dType"); dType = 0; break;
2544 }
2545
2546 if (insn->subOp == NV50_IR_SUBOP_ATOM_EXCH)
2547 subOp = 8;
2548 else
2549 subOp = insn->subOp;
2550
2551 emitInsn (0xec000000);
2552 emitField(0x1c, 3, dType);
2553 }
2554
2555 emitField(0x34, 4, subOp);
2556 emitGPR (0x14, insn->src(1));
2557 emitADDR (0x08, 0x1e, 22, 2, insn->src(0));
2558 emitGPR (0x00, insn->def(0));
2559 }
2560
2561 void
2562 CodeEmitterGM107::emitRED()
2563 {
2564 unsigned dType;
2565
2566 switch (insn->dType) {
2567 case TYPE_U32: dType = 0; break;
2568 case TYPE_S32: dType = 1; break;
2569 case TYPE_U64: dType = 2; break;
2570 case TYPE_F32: dType = 3; break;
2571 case TYPE_B128: dType = 4; break;
2572 case TYPE_S64: dType = 5; break;
2573 default: assert(!"unexpected dType"); dType = 0; break;
2574 }
2575
2576 emitInsn (0xebf80000);
2577 emitField(0x30, 1, insn->src(0).getIndirect(0)->getSize() == 8);
2578 emitField(0x17, 3, insn->subOp);
2579 emitField(0x14, 3, dType);
2580 emitADDR (0x08, 0x1c, 20, 0, insn->src(0));
2581 emitGPR (0x00, insn->src(1));
2582 }
2583
2584 void
2585 CodeEmitterGM107::emitCCTL()
2586 {
2587 unsigned width;
2588 if (insn->src(0).getFile() == FILE_MEMORY_GLOBAL) {
2589 emitInsn(0xef600000);
2590 width = 30;
2591 } else {
2592 emitInsn(0xef800000);
2593 width = 22;
2594 }
2595 emitField(0x34, 1, insn->src(0).getIndirect(0)->getSize() == 8);
2596 emitADDR (0x08, 0x16, width, 2, insn->src(0));
2597 emitField(0x00, 4, insn->subOp);
2598 }
2599
2600 /*******************************************************************************
2601 * surface
2602 ******************************************************************************/
2603
2604 void
2605 CodeEmitterGM107::emitPIXLD()
2606 {
2607 emitInsn (0xefe80000);
2608 emitPRED (0x2d);
2609 emitField(0x1f, 3, insn->subOp);
2610 emitGPR (0x08, insn->src(0));
2611 emitGPR (0x00, insn->def(0));
2612 }
2613
2614 /*******************************************************************************
2615 * texture
2616 ******************************************************************************/
2617
2618 void
2619 CodeEmitterGM107::emitTEXs(int pos)
2620 {
2621 int src1 = insn->predSrc == 1 ? 2 : 1;
2622 if (insn->srcExists(src1))
2623 emitGPR(pos, insn->src(src1));
2624 else
2625 emitGPR(pos);
2626 }
2627
2628 void
2629 CodeEmitterGM107::emitTEX()
2630 {
2631 const TexInstruction *insn = this->insn->asTex();
2632 int lodm = 0;
2633
2634 if (!insn->tex.levelZero) {
2635 switch (insn->op) {
2636 case OP_TEX: lodm = 0; break;
2637 case OP_TXB: lodm = 2; break;
2638 case OP_TXL: lodm = 3; break;
2639 default:
2640 assert(!"invalid tex op");
2641 break;
2642 }
2643 } else {
2644 lodm = 1;
2645 }
2646
2647 if (insn->tex.rIndirectSrc >= 0) {
2648 emitInsn (0xdeb80000);
2649 emitField(0x25, 2, lodm);
2650 emitField(0x24, 1, insn->tex.useOffsets == 1);
2651 } else {
2652 emitInsn (0xc0380000);
2653 emitField(0x37, 2, lodm);
2654 emitField(0x36, 1, insn->tex.useOffsets == 1);
2655 emitField(0x24, 13, insn->tex.r);
2656 }
2657
2658 emitField(0x32, 1, insn->tex.target.isShadow());
2659 emitField(0x31, 1, insn->tex.liveOnly);
2660 emitField(0x23, 1, insn->tex.derivAll);
2661 emitField(0x1f, 4, insn->tex.mask);
2662 emitField(0x1d, 2, insn->tex.target.isCube() ? 3 :
2663 insn->tex.target.getDim() - 1);
2664 emitField(0x1c, 1, insn->tex.target.isArray());
2665 emitTEXs (0x14);
2666 emitGPR (0x08, insn->src(0));
2667 emitGPR (0x00, insn->def(0));
2668 }
2669
2670 void
2671 CodeEmitterGM107::emitTLD()
2672 {
2673 const TexInstruction *insn = this->insn->asTex();
2674
2675 if (insn->tex.rIndirectSrc >= 0) {
2676 emitInsn (0xdd380000);
2677 } else {
2678 emitInsn (0xdc380000);
2679 emitField(0x24, 13, insn->tex.r);
2680 }
2681
2682 emitField(0x37, 1, insn->tex.levelZero == 0);
2683 emitField(0x32, 1, insn->tex.target.isMS());
2684 emitField(0x31, 1, insn->tex.liveOnly);
2685 emitField(0x23, 1, insn->tex.useOffsets == 1);
2686 emitField(0x1f, 4, insn->tex.mask);
2687 emitField(0x1d, 2, insn->tex.target.isCube() ? 3 :
2688 insn->tex.target.getDim() - 1);
2689 emitField(0x1c, 1, insn->tex.target.isArray());
2690 emitTEXs (0x14);
2691 emitGPR (0x08, insn->src(0));
2692 emitGPR (0x00, insn->def(0));
2693 }
2694
2695 void
2696 CodeEmitterGM107::emitTLD4()
2697 {
2698 const TexInstruction *insn = this->insn->asTex();
2699
2700 if (insn->tex.rIndirectSrc >= 0) {
2701 emitInsn (0xdef80000);
2702 emitField(0x26, 2, insn->tex.gatherComp);
2703 emitField(0x25, 2, insn->tex.useOffsets == 4);
2704 emitField(0x24, 2, insn->tex.useOffsets == 1);
2705 } else {
2706 emitInsn (0xc8380000);
2707 emitField(0x38, 2, insn->tex.gatherComp);
2708 emitField(0x37, 2, insn->tex.useOffsets == 4);
2709 emitField(0x36, 2, insn->tex.useOffsets == 1);
2710 emitField(0x24, 13, insn->tex.r);
2711 }
2712
2713 emitField(0x32, 1, insn->tex.target.isShadow());
2714 emitField(0x31, 1, insn->tex.liveOnly);
2715 emitField(0x23, 1, insn->tex.derivAll);
2716 emitField(0x1f, 4, insn->tex.mask);
2717 emitField(0x1d, 2, insn->tex.target.isCube() ? 3 :
2718 insn->tex.target.getDim() - 1);
2719 emitField(0x1c, 1, insn->tex.target.isArray());
2720 emitTEXs (0x14);
2721 emitGPR (0x08, insn->src(0));
2722 emitGPR (0x00, insn->def(0));
2723 }
2724
2725 void
2726 CodeEmitterGM107::emitTXD()
2727 {
2728 const TexInstruction *insn = this->insn->asTex();
2729
2730 if (insn->tex.rIndirectSrc >= 0) {
2731 emitInsn (0xde780000);
2732 } else {
2733 emitInsn (0xde380000);
2734 emitField(0x24, 13, insn->tex.r);
2735 }
2736
2737 emitField(0x31, 1, insn->tex.liveOnly);
2738 emitField(0x23, 1, insn->tex.useOffsets == 1);
2739 emitField(0x1f, 4, insn->tex.mask);
2740 emitField(0x1d, 2, insn->tex.target.isCube() ? 3 :
2741 insn->tex.target.getDim() - 1);
2742 emitField(0x1c, 1, insn->tex.target.isArray());
2743 emitTEXs (0x14);
2744 emitGPR (0x08, insn->src(0));
2745 emitGPR (0x00, insn->def(0));
2746 }
2747
2748 void
2749 CodeEmitterGM107::emitTMML()
2750 {
2751 const TexInstruction *insn = this->insn->asTex();
2752
2753 if (insn->tex.rIndirectSrc >= 0) {
2754 emitInsn (0xdf600000);
2755 } else {
2756 emitInsn (0xdf580000);
2757 emitField(0x24, 13, insn->tex.r);
2758 }
2759
2760 emitField(0x31, 1, insn->tex.liveOnly);
2761 emitField(0x23, 1, insn->tex.derivAll);
2762 emitField(0x1f, 4, insn->tex.mask);
2763 emitField(0x1d, 2, insn->tex.target.isCube() ? 3 :
2764 insn->tex.target.getDim() - 1);
2765 emitField(0x1c, 1, insn->tex.target.isArray());
2766 emitTEXs (0x14);
2767 emitGPR (0x08, insn->src(0));
2768 emitGPR (0x00, insn->def(0));
2769 }
2770
2771 void
2772 CodeEmitterGM107::emitTXQ()
2773 {
2774 const TexInstruction *insn = this->insn->asTex();
2775 int type = 0;
2776
2777 switch (insn->tex.query) {
2778 case TXQ_DIMS : type = 0x01; break;
2779 case TXQ_TYPE : type = 0x02; break;
2780 case TXQ_SAMPLE_POSITION: type = 0x05; break;
2781 case TXQ_FILTER : type = 0x10; break;
2782 case TXQ_LOD : type = 0x12; break;
2783 case TXQ_WRAP : type = 0x14; break;
2784 case TXQ_BORDER_COLOUR : type = 0x16; break;
2785 default:
2786 assert(!"invalid txq query");
2787 break;
2788 }
2789
2790 if (insn->tex.rIndirectSrc >= 0) {
2791 emitInsn (0xdf500000);
2792 } else {
2793 emitInsn (0xdf480000);
2794 emitField(0x24, 13, insn->tex.r);
2795 }
2796
2797 emitField(0x31, 1, insn->tex.liveOnly);
2798 emitField(0x1f, 4, insn->tex.mask);
2799 emitField(0x16, 6, type);
2800 emitGPR (0x08, insn->src(0));
2801 emitGPR (0x00, insn->def(0));
2802 }
2803
2804 void
2805 CodeEmitterGM107::emitDEPBAR()
2806 {
2807 emitInsn (0xf0f00000);
2808 emitField(0x1d, 1, 1); /* le */
2809 emitField(0x1a, 3, 5);
2810 emitField(0x14, 6, insn->subOp);
2811 emitField(0x00, 6, insn->subOp);
2812 }
2813
2814 /*******************************************************************************
2815 * misc
2816 ******************************************************************************/
2817
2818 void
2819 CodeEmitterGM107::emitNOP()
2820 {
2821 emitInsn(0x50b00000);
2822 }
2823
2824 void
2825 CodeEmitterGM107::emitKIL()
2826 {
2827 emitInsn (0xe3300000);
2828 emitCond5(0x00, CC_TR);
2829 }
2830
2831 void
2832 CodeEmitterGM107::emitOUT()
2833 {
2834 const int cut = insn->op == OP_RESTART || insn->subOp;
2835 const int emit = insn->op == OP_EMIT;
2836
2837 switch (insn->src(1).getFile()) {
2838 case FILE_GPR:
2839 emitInsn(0xfbe00000);
2840 emitGPR (0x14, insn->src(1));
2841 break;
2842 case FILE_IMMEDIATE:
2843 emitInsn(0xf6e00000);
2844 emitIMMD(0x14, 19, insn->src(1));
2845 break;
2846 case FILE_MEMORY_CONST:
2847 emitInsn(0xebe00000);
2848 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
2849 break;
2850 default:
2851 assert(!"bad src1 file");
2852 break;
2853 }
2854
2855 emitField(0x27, 2, (cut << 1) | emit);
2856 emitGPR (0x08, insn->src(0));
2857 emitGPR (0x00, insn->def(0));
2858 }
2859
2860 void
2861 CodeEmitterGM107::emitBAR()
2862 {
2863 uint8_t subop;
2864
2865 emitInsn (0xf0a80000);
2866
2867 switch (insn->subOp) {
2868 case NV50_IR_SUBOP_BAR_RED_POPC: subop = 0x02; break;
2869 case NV50_IR_SUBOP_BAR_RED_AND: subop = 0x0a; break;
2870 case NV50_IR_SUBOP_BAR_RED_OR: subop = 0x12; break;
2871 case NV50_IR_SUBOP_BAR_ARRIVE: subop = 0x81; break;
2872 default:
2873 subop = 0x80;
2874 assert(insn->subOp == NV50_IR_SUBOP_BAR_SYNC);
2875 break;
2876 }
2877
2878 emitField(0x20, 8, subop);
2879
2880 // barrier id
2881 if (insn->src(0).getFile() == FILE_GPR) {
2882 emitGPR(0x08, insn->src(0));
2883 } else {
2884 ImmediateValue *imm = insn->getSrc(0)->asImm();
2885 assert(imm);
2886 emitField(0x08, 8, imm->reg.data.u32);
2887 emitField(0x2b, 1, 1);
2888 }
2889
2890 // thread count
2891 if (insn->src(1).getFile() == FILE_GPR) {
2892 emitGPR(0x14, insn->src(1));
2893 } else {
2894 ImmediateValue *imm = insn->getSrc(0)->asImm();
2895 assert(imm);
2896 emitField(0x14, 12, imm->reg.data.u32);
2897 emitField(0x2c, 1, 1);
2898 }
2899
2900 if (insn->srcExists(2) && (insn->predSrc != 2)) {
2901 emitPRED (0x27, insn->src(2));
2902 emitField(0x2a, 1, insn->src(2).mod == Modifier(NV50_IR_MOD_NOT));
2903 } else {
2904 emitField(0x27, 3, 7);
2905 }
2906 }
2907
2908 void
2909 CodeEmitterGM107::emitMEMBAR()
2910 {
2911 emitInsn (0xef980000);
2912 emitField(0x08, 2, insn->subOp >> 2);
2913 }
2914
2915 void
2916 CodeEmitterGM107::emitVOTE()
2917 {
2918 assert(insn->src(0).getFile() == FILE_PREDICATE);
2919
2920 int r = -1, p = -1;
2921 for (int i = 0; insn->defExists(i); i++) {
2922 if (insn->def(i).getFile() == FILE_GPR)
2923 r = i;
2924 else if (insn->def(i).getFile() == FILE_PREDICATE)
2925 p = i;
2926 }
2927
2928 emitInsn (0x50d80000);
2929 emitField(0x30, 2, insn->subOp);
2930 if (r >= 0)
2931 emitGPR (0x00, insn->def(r));
2932 else
2933 emitGPR (0x00);
2934 if (p >= 0)
2935 emitPRED (0x2d, insn->def(p));
2936 else
2937 emitPRED (0x2d);
2938 emitField(0x2a, 1, insn->src(0).mod == Modifier(NV50_IR_MOD_NOT));
2939 emitPRED (0x27, insn->src(0));
2940 }
2941
2942 void
2943 CodeEmitterGM107::emitSUTarget()
2944 {
2945 const TexInstruction *insn = this->insn->asTex();
2946 int target = 0;
2947
2948 assert(insn->op >= OP_SULDB && insn->op <= OP_SUREDP);
2949
2950 if (insn->tex.target == TEX_TARGET_BUFFER) {
2951 target = 2;
2952 } else if (insn->tex.target == TEX_TARGET_1D_ARRAY) {
2953 target = 4;
2954 } else if (insn->tex.target == TEX_TARGET_2D ||
2955 insn->tex.target == TEX_TARGET_RECT) {
2956 target = 6;
2957 } else if (insn->tex.target == TEX_TARGET_2D_ARRAY ||
2958 insn->tex.target == TEX_TARGET_CUBE ||
2959 insn->tex.target == TEX_TARGET_CUBE_ARRAY) {
2960 target = 8;
2961 } else if (insn->tex.target == TEX_TARGET_3D) {
2962 target = 10;
2963 } else {
2964 assert(insn->tex.target == TEX_TARGET_1D);
2965 }
2966 emitField(0x20, 4, target);
2967 }
2968
2969 void
2970 CodeEmitterGM107::emitSUHandle(const int s)
2971 {
2972 const TexInstruction *insn = this->insn->asTex();
2973
2974 assert(insn->op >= OP_SULDB && insn->op <= OP_SUREDP);
2975
2976 if (insn->src(s).getFile() == FILE_GPR) {
2977 emitGPR(0x27, insn->src(s));
2978 } else {
2979 ImmediateValue *imm = insn->getSrc(s)->asImm();
2980 assert(imm);
2981 emitField(0x33, 1, 1);
2982 emitField(0x24, 13, imm->reg.data.u32);
2983 }
2984 }
2985
2986 void
2987 CodeEmitterGM107::emitSUSTx()
2988 {
2989 const TexInstruction *insn = this->insn->asTex();
2990
2991 emitInsn(0xeb200000);
2992 if (insn->op == OP_SUSTB)
2993 emitField(0x34, 1, 1);
2994 emitSUTarget();
2995
2996 emitLDSTc(0x18);
2997 emitField(0x14, 4, 0xf); // rgba
2998 emitGPR (0x08, insn->src(0));
2999 emitGPR (0x00, insn->src(1));
3000
3001 emitSUHandle(2);
3002 }
3003
3004 void
3005 CodeEmitterGM107::emitSULDx()
3006 {
3007 const TexInstruction *insn = this->insn->asTex();
3008 int type = 0;
3009
3010 emitInsn(0xeb000000);
3011 if (insn->op == OP_SULDB)
3012 emitField(0x34, 1, 1);
3013 emitSUTarget();
3014
3015 switch (insn->dType) {
3016 case TYPE_S8: type = 1; break;
3017 case TYPE_U16: type = 2; break;
3018 case TYPE_S16: type = 3; break;
3019 case TYPE_U32: type = 4; break;
3020 case TYPE_U64: type = 5; break;
3021 case TYPE_B128: type = 6; break;
3022 default:
3023 assert(insn->dType == TYPE_U8);
3024 break;
3025 }
3026 emitLDSTc(0x18);
3027 emitField(0x14, 3, type);
3028 emitGPR (0x00, insn->def(0));
3029 emitGPR (0x08, insn->src(0));
3030
3031 emitSUHandle(1);
3032 }
3033
3034 void
3035 CodeEmitterGM107::emitSUREDx()
3036 {
3037 const TexInstruction *insn = this->insn->asTex();
3038 uint8_t type = 0, subOp;
3039
3040 if (insn->subOp == NV50_IR_SUBOP_ATOM_CAS)
3041 emitInsn(0xeac00000);
3042 else
3043 emitInsn(0xea600000);
3044
3045 if (insn->op == OP_SUREDB)
3046 emitField(0x34, 1, 1);
3047 emitSUTarget();
3048
3049 // destination type
3050 switch (insn->dType) {
3051 case TYPE_S32: type = 1; break;
3052 case TYPE_U64: type = 2; break;
3053 case TYPE_F32: type = 3; break;
3054 case TYPE_S64: type = 5; break;
3055 default:
3056 assert(insn->dType == TYPE_U32);
3057 break;
3058 }
3059
3060 // atomic operation
3061 if (insn->subOp == NV50_IR_SUBOP_ATOM_CAS) {
3062 subOp = 0;
3063 } else if (insn->subOp == NV50_IR_SUBOP_ATOM_EXCH) {
3064 subOp = 8;
3065 } else {
3066 subOp = insn->subOp;
3067 }
3068
3069 emitField(0x24, 3, type);
3070 emitField(0x1d, 4, subOp);
3071 emitGPR (0x14, insn->src(1));
3072 emitGPR (0x08, insn->src(0));
3073 emitGPR (0x00, insn->def(0));
3074
3075 emitSUHandle(2);
3076 }
3077
3078 /*******************************************************************************
3079 * assembler front-end
3080 ******************************************************************************/
3081
3082 bool
3083 CodeEmitterGM107::emitInstruction(Instruction *i)
3084 {
3085 const unsigned int size = (writeIssueDelays && !(codeSize & 0x1f)) ? 16 : 8;
3086 bool ret = true;
3087
3088 insn = i;
3089
3090 if (insn->encSize != 8) {
3091 ERROR("skipping undecodable instruction: "); insn->print();
3092 return false;
3093 } else
3094 if (codeSize + size > codeSizeLimit) {
3095 ERROR("code emitter output buffer too small\n");
3096 return false;
3097 }
3098
3099 if (writeIssueDelays) {
3100 int n = ((codeSize & 0x1f) / 8) - 1;
3101 if (n < 0) {
3102 data = code;
3103 data[0] = 0x00000000;
3104 data[1] = 0x00000000;
3105 code += 2;
3106 codeSize += 8;
3107 n++;
3108 }
3109
3110 emitField(data, n * 21, 21, insn->sched);
3111 }
3112
3113 switch (insn->op) {
3114 case OP_EXIT:
3115 emitEXIT();
3116 break;
3117 case OP_BRA:
3118 emitBRA();
3119 break;
3120 case OP_CALL:
3121 emitCAL();
3122 break;
3123 case OP_PRECONT:
3124 emitPCNT();
3125 break;
3126 case OP_CONT:
3127 emitCONT();
3128 break;
3129 case OP_PREBREAK:
3130 emitPBK();
3131 break;
3132 case OP_BREAK:
3133 emitBRK();
3134 break;
3135 case OP_PRERET:
3136 emitPRET();
3137 break;
3138 case OP_RET:
3139 emitRET();
3140 break;
3141 case OP_JOINAT:
3142 emitSSY();
3143 break;
3144 case OP_JOIN:
3145 emitSYNC();
3146 break;
3147 case OP_QUADON:
3148 emitSAM();
3149 break;
3150 case OP_QUADPOP:
3151 emitRAM();
3152 break;
3153 case OP_MOV:
3154 emitMOV();
3155 break;
3156 case OP_RDSV:
3157 emitS2R();
3158 break;
3159 case OP_ABS:
3160 case OP_NEG:
3161 case OP_SAT:
3162 case OP_FLOOR:
3163 case OP_CEIL:
3164 case OP_TRUNC:
3165 case OP_CVT:
3166 if (insn->op == OP_CVT && (insn->def(0).getFile() == FILE_PREDICATE ||
3167 insn->src(0).getFile() == FILE_PREDICATE)) {
3168 emitMOV();
3169 } else if (isFloatType(insn->dType)) {
3170 if (isFloatType(insn->sType))
3171 emitF2F();
3172 else
3173 emitI2F();
3174 } else {
3175 if (isFloatType(insn->sType))
3176 emitF2I();
3177 else
3178 emitI2I();
3179 }
3180 break;
3181 case OP_SHFL:
3182 emitSHFL();
3183 break;
3184 case OP_ADD:
3185 case OP_SUB:
3186 if (isFloatType(insn->dType)) {
3187 if (insn->dType == TYPE_F64)
3188 emitDADD();
3189 else
3190 emitFADD();
3191 } else {
3192 emitIADD();
3193 }
3194 break;
3195 case OP_MUL:
3196 if (isFloatType(insn->dType)) {
3197 if (insn->dType == TYPE_F64)
3198 emitDMUL();
3199 else
3200 emitFMUL();
3201 } else {
3202 emitIMUL();
3203 }
3204 break;
3205 case OP_MAD:
3206 case OP_FMA:
3207 if (isFloatType(insn->dType)) {
3208 if (insn->dType == TYPE_F64)
3209 emitDFMA();
3210 else
3211 emitFFMA();
3212 } else {
3213 emitIMAD();
3214 }
3215 break;
3216 case OP_SHLADD:
3217 emitISCADD();
3218 break;
3219 case OP_MIN:
3220 case OP_MAX:
3221 if (isFloatType(insn->dType)) {
3222 if (insn->dType == TYPE_F64)
3223 emitDMNMX();
3224 else
3225 emitFMNMX();
3226 } else {
3227 emitIMNMX();
3228 }
3229 break;
3230 case OP_SHL:
3231 if (typeSizeof(insn->sType) == 8)
3232 emitSHF();
3233 else
3234 emitSHL();
3235 break;
3236 case OP_SHR:
3237 if (typeSizeof(insn->sType) == 8)
3238 emitSHF();
3239 else
3240 emitSHR();
3241 break;
3242 case OP_POPCNT:
3243 emitPOPC();
3244 break;
3245 case OP_INSBF:
3246 emitBFI();
3247 break;
3248 case OP_EXTBF:
3249 emitBFE();
3250 break;
3251 case OP_BFIND:
3252 emitFLO();
3253 break;
3254 case OP_SLCT:
3255 if (isFloatType(insn->dType))
3256 emitFCMP();
3257 else
3258 emitICMP();
3259 break;
3260 case OP_SET:
3261 case OP_SET_AND:
3262 case OP_SET_OR:
3263 case OP_SET_XOR:
3264 if (insn->def(0).getFile() != FILE_PREDICATE) {
3265 if (isFloatType(insn->sType))
3266 if (insn->sType == TYPE_F64)
3267 emitDSET();
3268 else
3269 emitFSET();
3270 else
3271 emitISET();
3272 } else {
3273 if (isFloatType(insn->sType))
3274 if (insn->sType == TYPE_F64)
3275 emitDSETP();
3276 else
3277 emitFSETP();
3278 else
3279 emitISETP();
3280 }
3281 break;
3282 case OP_SELP:
3283 emitSEL();
3284 break;
3285 case OP_PRESIN:
3286 case OP_PREEX2:
3287 emitRRO();
3288 break;
3289 case OP_COS:
3290 case OP_SIN:
3291 case OP_EX2:
3292 case OP_LG2:
3293 case OP_RCP:
3294 case OP_RSQ:
3295 emitMUFU();
3296 break;
3297 case OP_AND:
3298 case OP_OR:
3299 case OP_XOR:
3300 emitLOP();
3301 break;
3302 case OP_NOT:
3303 emitNOT();
3304 break;
3305 case OP_LOAD:
3306 switch (insn->src(0).getFile()) {
3307 case FILE_MEMORY_CONST : emitLDC(); break;
3308 case FILE_MEMORY_LOCAL : emitLDL(); break;
3309 case FILE_MEMORY_SHARED: emitLDS(); break;
3310 case FILE_MEMORY_GLOBAL: emitLD(); break;
3311 default:
3312 assert(!"invalid load");
3313 emitNOP();
3314 break;
3315 }
3316 break;
3317 case OP_STORE:
3318 switch (insn->src(0).getFile()) {
3319 case FILE_MEMORY_LOCAL : emitSTL(); break;
3320 case FILE_MEMORY_SHARED: emitSTS(); break;
3321 case FILE_MEMORY_GLOBAL: emitST(); break;
3322 default:
3323 assert(!"invalid store");
3324 emitNOP();
3325 break;
3326 }
3327 break;
3328 case OP_ATOM:
3329 if (insn->src(0).getFile() == FILE_MEMORY_SHARED)
3330 emitATOMS();
3331 else
3332 if (!insn->defExists(0) && insn->subOp < NV50_IR_SUBOP_ATOM_CAS)
3333 emitRED();
3334 else
3335 emitATOM();
3336 break;
3337 case OP_CCTL:
3338 emitCCTL();
3339 break;
3340 case OP_VFETCH:
3341 emitALD();
3342 break;
3343 case OP_EXPORT:
3344 emitAST();
3345 break;
3346 case OP_PFETCH:
3347 emitISBERD();
3348 break;
3349 case OP_AFETCH:
3350 emitAL2P();
3351 break;
3352 case OP_LINTERP:
3353 case OP_PINTERP:
3354 emitIPA();
3355 break;
3356 case OP_PIXLD:
3357 emitPIXLD();
3358 break;
3359 case OP_TEX:
3360 case OP_TXB:
3361 case OP_TXL:
3362 emitTEX();
3363 break;
3364 case OP_TXF:
3365 emitTLD();
3366 break;
3367 case OP_TXG:
3368 emitTLD4();
3369 break;
3370 case OP_TXD:
3371 emitTXD();
3372 break;
3373 case OP_TXQ:
3374 emitTXQ();
3375 break;
3376 case OP_TXLQ:
3377 emitTMML();
3378 break;
3379 case OP_TEXBAR:
3380 emitDEPBAR();
3381 break;
3382 case OP_QUADOP:
3383 emitFSWZADD();
3384 break;
3385 case OP_NOP:
3386 emitNOP();
3387 break;
3388 case OP_DISCARD:
3389 emitKIL();
3390 break;
3391 case OP_EMIT:
3392 case OP_RESTART:
3393 emitOUT();
3394 break;
3395 case OP_BAR:
3396 emitBAR();
3397 break;
3398 case OP_MEMBAR:
3399 emitMEMBAR();
3400 break;
3401 case OP_VOTE:
3402 emitVOTE();
3403 break;
3404 case OP_SUSTB:
3405 case OP_SUSTP:
3406 emitSUSTx();
3407 break;
3408 case OP_SULDB:
3409 case OP_SULDP:
3410 emitSULDx();
3411 break;
3412 case OP_SUREDB:
3413 case OP_SUREDP:
3414 emitSUREDx();
3415 break;
3416 default:
3417 assert(!"invalid opcode");
3418 emitNOP();
3419 ret = false;
3420 break;
3421 }
3422
3423 if (insn->join) {
3424 /*XXX*/
3425 }
3426
3427 code += 2;
3428 codeSize += 8;
3429 return ret;
3430 }
3431
3432 uint32_t
3433 CodeEmitterGM107::getMinEncodingSize(const Instruction *i) const
3434 {
3435 return 8;
3436 }
3437
3438 /*******************************************************************************
3439 * sched data calculator
3440 ******************************************************************************/
3441
3442 class SchedDataCalculatorGM107 : public Pass
3443 {
3444 public:
3445 SchedDataCalculatorGM107(const TargetGM107 *targ) : targ(targ) {}
3446
3447 private:
3448 struct RegScores
3449 {
3450 struct ScoreData {
3451 int r[256];
3452 int p[8];
3453 int c;
3454 } rd, wr;
3455 int base;
3456
3457 void rebase(const int base)
3458 {
3459 const int delta = this->base - base;
3460 if (!delta)
3461 return;
3462 this->base = 0;
3463
3464 for (int i = 0; i < 256; ++i) {
3465 rd.r[i] += delta;
3466 wr.r[i] += delta;
3467 }
3468 for (int i = 0; i < 8; ++i) {
3469 rd.p[i] += delta;
3470 wr.p[i] += delta;
3471 }
3472 rd.c += delta;
3473 wr.c += delta;
3474 }
3475 void wipe()
3476 {
3477 memset(&rd, 0, sizeof(rd));
3478 memset(&wr, 0, sizeof(wr));
3479 }
3480 int getLatest(const ScoreData& d) const
3481 {
3482 int max = 0;
3483 for (int i = 0; i < 256; ++i)
3484 if (d.r[i] > max)
3485 max = d.r[i];
3486 for (int i = 0; i < 8; ++i)
3487 if (d.p[i] > max)
3488 max = d.p[i];
3489 if (d.c > max)
3490 max = d.c;
3491 return max;
3492 }
3493 inline int getLatestRd() const
3494 {
3495 return getLatest(rd);
3496 }
3497 inline int getLatestWr() const
3498 {
3499 return getLatest(wr);
3500 }
3501 inline int getLatest() const
3502 {
3503 return MAX2(getLatestRd(), getLatestWr());
3504 }
3505 void setMax(const RegScores *that)
3506 {
3507 for (int i = 0; i < 256; ++i) {
3508 rd.r[i] = MAX2(rd.r[i], that->rd.r[i]);
3509 wr.r[i] = MAX2(wr.r[i], that->wr.r[i]);
3510 }
3511 for (int i = 0; i < 8; ++i) {
3512 rd.p[i] = MAX2(rd.p[i], that->rd.p[i]);
3513 wr.p[i] = MAX2(wr.p[i], that->wr.p[i]);
3514 }
3515 rd.c = MAX2(rd.c, that->rd.c);
3516 wr.c = MAX2(wr.c, that->wr.c);
3517 }
3518 void print(int cycle)
3519 {
3520 for (int i = 0; i < 256; ++i) {
3521 if (rd.r[i] > cycle)
3522 INFO("rd $r%i @ %i\n", i, rd.r[i]);
3523 if (wr.r[i] > cycle)
3524 INFO("wr $r%i @ %i\n", i, wr.r[i]);
3525 }
3526 for (int i = 0; i < 8; ++i) {
3527 if (rd.p[i] > cycle)
3528 INFO("rd $p%i @ %i\n", i, rd.p[i]);
3529 if (wr.p[i] > cycle)
3530 INFO("wr $p%i @ %i\n", i, wr.p[i]);
3531 }
3532 if (rd.c > cycle)
3533 INFO("rd $c @ %i\n", rd.c);
3534 if (wr.c > cycle)
3535 INFO("wr $c @ %i\n", wr.c);
3536 }
3537 };
3538
3539 RegScores *score; // for current BB
3540 std::vector<RegScores> scoreBoards;
3541
3542 const TargetGM107 *targ;
3543 bool visit(Function *);
3544 bool visit(BasicBlock *);
3545
3546 void commitInsn(const Instruction *, int);
3547 int calcDelay(const Instruction *, int) const;
3548 void setDelay(Instruction *, int, const Instruction *);
3549 void recordWr(const Value *, int, int);
3550 void checkRd(const Value *, int, int&) const;
3551
3552 inline void emitYield(Instruction *);
3553 inline void emitStall(Instruction *, uint8_t);
3554 inline void emitReuse(Instruction *, uint8_t);
3555 inline void emitWrDepBar(Instruction *, uint8_t);
3556 inline void emitRdDepBar(Instruction *, uint8_t);
3557 inline void emitWtDepBar(Instruction *, uint8_t);
3558
3559 inline int getStall(const Instruction *) const;
3560 inline int getWrDepBar(const Instruction *) const;
3561 inline int getRdDepBar(const Instruction *) const;
3562 inline int getWtDepBar(const Instruction *) const;
3563
3564 void setReuseFlag(Instruction *);
3565
3566 inline void printSchedInfo(int, const Instruction *) const;
3567
3568 struct LiveBarUse {
3569 LiveBarUse(Instruction *insn, Instruction *usei)
3570 : insn(insn), usei(usei) { }
3571 Instruction *insn;
3572 Instruction *usei;
3573 };
3574
3575 struct LiveBarDef {
3576 LiveBarDef(Instruction *insn, Instruction *defi)
3577 : insn(insn), defi(defi) { }
3578 Instruction *insn;
3579 Instruction *defi;
3580 };
3581
3582 bool insertBarriers(BasicBlock *);
3583
3584 Instruction *findFirstUse(const Instruction *) const;
3585 Instruction *findFirstDef(const Instruction *) const;
3586
3587 bool needRdDepBar(const Instruction *) const;
3588 bool needWrDepBar(const Instruction *) const;
3589 };
3590
3591 inline void
3592 SchedDataCalculatorGM107::emitStall(Instruction *insn, uint8_t cnt)
3593 {
3594 assert(cnt < 16);
3595 insn->sched |= cnt;
3596 }
3597
3598 inline void
3599 SchedDataCalculatorGM107::emitYield(Instruction *insn)
3600 {
3601 insn->sched |= 1 << 4;
3602 }
3603
3604 inline void
3605 SchedDataCalculatorGM107::emitWrDepBar(Instruction *insn, uint8_t id)
3606 {
3607 assert(id < 6);
3608 if ((insn->sched & 0xe0) == 0xe0)
3609 insn->sched ^= 0xe0;
3610 insn->sched |= id << 5;
3611 }
3612
3613 inline void
3614 SchedDataCalculatorGM107::emitRdDepBar(Instruction *insn, uint8_t id)
3615 {
3616 assert(id < 6);
3617 if ((insn->sched & 0x700) == 0x700)
3618 insn->sched ^= 0x700;
3619 insn->sched |= id << 8;
3620 }
3621
3622 inline void
3623 SchedDataCalculatorGM107::emitWtDepBar(Instruction *insn, uint8_t id)
3624 {
3625 assert(id < 6);
3626 insn->sched |= 1 << (11 + id);
3627 }
3628
3629 inline void
3630 SchedDataCalculatorGM107::emitReuse(Instruction *insn, uint8_t id)
3631 {
3632 assert(id < 4);
3633 insn->sched |= 1 << (17 + id);
3634 }
3635
3636 inline void
3637 SchedDataCalculatorGM107::printSchedInfo(int cycle,
3638 const Instruction *insn) const
3639 {
3640 uint8_t st, yl, wr, rd, wt, ru;
3641
3642 st = (insn->sched & 0x00000f) >> 0;
3643 yl = (insn->sched & 0x000010) >> 4;
3644 wr = (insn->sched & 0x0000e0) >> 5;
3645 rd = (insn->sched & 0x000700) >> 8;
3646 wt = (insn->sched & 0x01f800) >> 11;
3647 ru = (insn->sched & 0x1e0000) >> 17;
3648
3649 INFO("cycle %i, (st 0x%x, yl 0x%x, wr 0x%x, rd 0x%x, wt 0x%x, ru 0x%x)\n",
3650 cycle, st, yl, wr, rd, wt, ru);
3651 }
3652
3653 inline int
3654 SchedDataCalculatorGM107::getStall(const Instruction *insn) const
3655 {
3656 return insn->sched & 0xf;
3657 }
3658
3659 inline int
3660 SchedDataCalculatorGM107::getWrDepBar(const Instruction *insn) const
3661 {
3662 return (insn->sched & 0x0000e0) >> 5;
3663 }
3664
3665 inline int
3666 SchedDataCalculatorGM107::getRdDepBar(const Instruction *insn) const
3667 {
3668 return (insn->sched & 0x000700) >> 8;
3669 }
3670
3671 inline int
3672 SchedDataCalculatorGM107::getWtDepBar(const Instruction *insn) const
3673 {
3674 return (insn->sched & 0x01f800) >> 11;
3675 }
3676
3677 // Emit the reuse flag which allows to make use of the new memory hierarchy
3678 // introduced since Maxwell, the operand reuse cache.
3679 //
3680 // It allows to reduce bank conflicts by caching operands. Each time you issue
3681 // an instruction, that flag can tell the hw which operands are going to be
3682 // re-used by the next instruction. Note that the next instruction has to use
3683 // the same GPR id in the same operand slot.
3684 void
3685 SchedDataCalculatorGM107::setReuseFlag(Instruction *insn)
3686 {
3687 Instruction *next = insn->next;
3688 BitSet defs(255, 1);
3689
3690 if (!targ->isReuseSupported(insn))
3691 return;
3692
3693 for (int d = 0; insn->defExists(d); ++d) {
3694 const Value *def = insn->def(d).rep();
3695 if (insn->def(d).getFile() != FILE_GPR)
3696 continue;
3697 if (typeSizeof(insn->dType) != 4 || def->reg.data.id == 255)
3698 continue;
3699 defs.set(def->reg.data.id);
3700 }
3701
3702 for (int s = 0; insn->srcExists(s); s++) {
3703 const Value *src = insn->src(s).rep();
3704 if (insn->src(s).getFile() != FILE_GPR)
3705 continue;
3706 if (typeSizeof(insn->sType) != 4 || src->reg.data.id == 255)
3707 continue;
3708 if (defs.test(src->reg.data.id))
3709 continue;
3710 if (!next->srcExists(s) || next->src(s).getFile() != FILE_GPR)
3711 continue;
3712 if (src->reg.data.id != next->getSrc(s)->reg.data.id)
3713 continue;
3714 assert(s < 4);
3715 emitReuse(insn, s);
3716 }
3717 }
3718
3719 void
3720 SchedDataCalculatorGM107::recordWr(const Value *v, int cycle, int ready)
3721 {
3722 int a = v->reg.data.id, b;
3723
3724 switch (v->reg.file) {
3725 case FILE_GPR:
3726 b = a + v->reg.size / 4;
3727 for (int r = a; r < b; ++r)
3728 score->rd.r[r] = ready;
3729 break;
3730 case FILE_PREDICATE:
3731 // To immediately use a predicate set by any instructions, the minimum
3732 // number of stall counts is 13.
3733 score->rd.p[a] = cycle + 13;
3734 break;
3735 case FILE_FLAGS:
3736 score->rd.c = ready;
3737 break;
3738 default:
3739 break;
3740 }
3741 }
3742
3743 void
3744 SchedDataCalculatorGM107::checkRd(const Value *v, int cycle, int &delay) const
3745 {
3746 int a = v->reg.data.id, b;
3747 int ready = cycle;
3748
3749 switch (v->reg.file) {
3750 case FILE_GPR:
3751 b = a + v->reg.size / 4;
3752 for (int r = a; r < b; ++r)
3753 ready = MAX2(ready, score->rd.r[r]);
3754 break;
3755 case FILE_PREDICATE:
3756 ready = MAX2(ready, score->rd.p[a]);
3757 break;
3758 case FILE_FLAGS:
3759 ready = MAX2(ready, score->rd.c);
3760 break;
3761 default:
3762 break;
3763 }
3764 if (cycle < ready)
3765 delay = MAX2(delay, ready - cycle);
3766 }
3767
3768 void
3769 SchedDataCalculatorGM107::commitInsn(const Instruction *insn, int cycle)
3770 {
3771 const int ready = cycle + targ->getLatency(insn);
3772
3773 for (int d = 0; insn->defExists(d); ++d)
3774 recordWr(insn->getDef(d), cycle, ready);
3775
3776 #ifdef GM107_DEBUG_SCHED_DATA
3777 score->print(cycle);
3778 #endif
3779 }
3780
3781 #define GM107_MIN_ISSUE_DELAY 0x1
3782 #define GM107_MAX_ISSUE_DELAY 0xf
3783
3784 int
3785 SchedDataCalculatorGM107::calcDelay(const Instruction *insn, int cycle) const
3786 {
3787 int delay = 0, ready = cycle;
3788
3789 for (int s = 0; insn->srcExists(s); ++s)
3790 checkRd(insn->getSrc(s), cycle, delay);
3791
3792 // TODO: make use of getReadLatency()!
3793
3794 return MAX2(delay, ready - cycle);
3795 }
3796
3797 void
3798 SchedDataCalculatorGM107::setDelay(Instruction *insn, int delay,
3799 const Instruction *next)
3800 {
3801 const OpClass cl = targ->getOpClass(insn->op);
3802 int wr, rd;
3803
3804 if (insn->op == OP_EXIT ||
3805 insn->op == OP_BAR ||
3806 insn->op == OP_MEMBAR) {
3807 delay = GM107_MAX_ISSUE_DELAY;
3808 } else
3809 if (insn->op == OP_QUADON ||
3810 insn->op == OP_QUADPOP) {
3811 delay = 0xd;
3812 } else
3813 if (cl == OPCLASS_FLOW || insn->join) {
3814 delay = 0xd;
3815 }
3816
3817 if (!next || !targ->canDualIssue(insn, next)) {
3818 delay = CLAMP(delay, GM107_MIN_ISSUE_DELAY, GM107_MAX_ISSUE_DELAY);
3819 } else {
3820 delay = 0x0; // dual-issue
3821 }
3822
3823 wr = getWrDepBar(insn);
3824 rd = getRdDepBar(insn);
3825
3826 if (delay == GM107_MIN_ISSUE_DELAY && (wr & rd) != 7) {
3827 // Barriers take one additional clock cycle to become active on top of
3828 // the clock consumed by the instruction producing it.
3829 if (!next || insn->bb != next->bb) {
3830 delay = 0x2;
3831 } else {
3832 int wt = getWtDepBar(next);
3833 if ((wt & (1 << wr)) | (wt & (1 << rd)))
3834 delay = 0x2;
3835 }
3836 }
3837
3838 emitStall(insn, delay);
3839 }
3840
3841
3842 // Return true when the given instruction needs to emit a read dependency
3843 // barrier (for WaR hazards) because it doesn't operate at a fixed latency, and
3844 // setting the maximum number of stall counts is not enough.
3845 bool
3846 SchedDataCalculatorGM107::needRdDepBar(const Instruction *insn) const
3847 {
3848 BitSet srcs(255, 1), defs(255, 1);
3849 int a, b;
3850
3851 if (!targ->isBarrierRequired(insn))
3852 return false;
3853
3854 // Do not emit a read dependency barrier when the instruction doesn't use
3855 // any GPR (like st s[0x4] 0x0) as input because it's unnecessary.
3856 for (int s = 0; insn->srcExists(s); ++s) {
3857 const Value *src = insn->src(s).rep();
3858 if (insn->src(s).getFile() != FILE_GPR)
3859 continue;
3860 if (src->reg.data.id == 255)
3861 continue;
3862
3863 a = src->reg.data.id;
3864 b = a + src->reg.size / 4;
3865 for (int r = a; r < b; ++r)
3866 srcs.set(r);
3867 }
3868
3869 if (!srcs.popCount())
3870 return false;
3871
3872 // Do not emit a read dependency barrier when the output GPRs are equal to
3873 // the input GPRs (like rcp $r0 $r0) because a write dependency barrier will
3874 // be produced and WaR hazards are prevented.
3875 for (int d = 0; insn->defExists(d); ++d) {
3876 const Value *def = insn->def(d).rep();
3877 if (insn->def(d).getFile() != FILE_GPR)
3878 continue;
3879 if (def->reg.data.id == 255)
3880 continue;
3881
3882 a = def->reg.data.id;
3883 b = a + def->reg.size / 4;
3884 for (int r = a; r < b; ++r)
3885 defs.set(r);
3886 }
3887
3888 srcs.andNot(defs);
3889 if (!srcs.popCount())
3890 return false;
3891
3892 return true;
3893 }
3894
3895 // Return true when the given instruction needs to emit a write dependency
3896 // barrier (for RaW hazards) because it doesn't operate at a fixed latency, and
3897 // setting the maximum number of stall counts is not enough. This is only legal
3898 // if the instruction output something.
3899 bool
3900 SchedDataCalculatorGM107::needWrDepBar(const Instruction *insn) const
3901 {
3902 if (!targ->isBarrierRequired(insn))
3903 return false;
3904
3905 for (int d = 0; insn->defExists(d); ++d) {
3906 if (insn->def(d).getFile() == FILE_GPR ||
3907 insn->def(d).getFile() == FILE_PREDICATE)
3908 return true;
3909 }
3910 return false;
3911 }
3912
3913 // Find the next instruction inside the same basic block which uses the output
3914 // of the given instruction in order to avoid RaW hazards.
3915 Instruction *
3916 SchedDataCalculatorGM107::findFirstUse(const Instruction *bari) const
3917 {
3918 Instruction *insn, *next;
3919 int minGPR, maxGPR;
3920
3921 if (!bari->defExists(0))
3922 return NULL;
3923
3924 minGPR = bari->def(0).rep()->reg.data.id;
3925 maxGPR = minGPR + bari->def(0).rep()->reg.size / 4 - 1;
3926
3927 for (insn = bari->next; insn != NULL; insn = next) {
3928 next = insn->next;
3929
3930 for (int s = 0; insn->srcExists(s); ++s) {
3931 const Value *src = insn->src(s).rep();
3932 if (bari->def(0).getFile() == FILE_GPR) {
3933 if (insn->src(s).getFile() != FILE_GPR ||
3934 src->reg.data.id + src->reg.size / 4 - 1 < minGPR ||
3935 src->reg.data.id > maxGPR)
3936 continue;
3937 return insn;
3938 } else
3939 if (bari->def(0).getFile() == FILE_PREDICATE) {
3940 if (insn->src(s).getFile() != FILE_PREDICATE ||
3941 src->reg.data.id != minGPR)
3942 continue;
3943 return insn;
3944 }
3945 }
3946 }
3947 return NULL;
3948 }
3949
3950 // Find the next instruction inside the same basic block which overwrites, at
3951 // least, one source of the given instruction in order to avoid WaR hazards.
3952 Instruction *
3953 SchedDataCalculatorGM107::findFirstDef(const Instruction *bari) const
3954 {
3955 Instruction *insn, *next;
3956 int minGPR, maxGPR;
3957
3958 for (insn = bari->next; insn != NULL; insn = next) {
3959 next = insn->next;
3960
3961 for (int d = 0; insn->defExists(d); ++d) {
3962 const Value *def = insn->def(d).rep();
3963 if (insn->def(d).getFile() != FILE_GPR)
3964 continue;
3965
3966 minGPR = def->reg.data.id;
3967 maxGPR = minGPR + def->reg.size / 4 - 1;
3968
3969 for (int s = 0; bari->srcExists(s); ++s) {
3970 const Value *src = bari->src(s).rep();
3971 if (bari->src(s).getFile() != FILE_GPR ||
3972 src->reg.data.id + src->reg.size / 4 - 1 < minGPR ||
3973 src->reg.data.id > maxGPR)
3974 continue;
3975 return insn;
3976 }
3977 }
3978 }
3979 return NULL;
3980 }
3981
3982 // Dependency barriers:
3983 // This pass is a bit ugly and could probably be improved by performing a
3984 // better allocation.
3985 //
3986 // The main idea is to avoid WaR and RaW hazards by emitting read/write
3987 // dependency barriers using the control codes.
3988 bool
3989 SchedDataCalculatorGM107::insertBarriers(BasicBlock *bb)
3990 {
3991 std::list<LiveBarUse> live_uses;
3992 std::list<LiveBarDef> live_defs;
3993 Instruction *insn, *next;
3994 BitSet bars(6, 1);
3995 int bar_id;
3996
3997 for (insn = bb->getEntry(); insn != NULL; insn = next) {
3998 Instruction *usei = NULL, *defi = NULL;
3999 bool need_wr_bar, need_rd_bar;
4000
4001 next = insn->next;
4002
4003 // Expire old barrier uses.
4004 for (std::list<LiveBarUse>::iterator it = live_uses.begin();
4005 it != live_uses.end();) {
4006 if (insn->serial >= it->usei->serial) {
4007 int wr = getWrDepBar(it->insn);
4008 emitWtDepBar(insn, wr);
4009 bars.clr(wr); // free barrier
4010 it = live_uses.erase(it);
4011 continue;
4012 }
4013 ++it;
4014 }
4015
4016 // Expire old barrier defs.
4017 for (std::list<LiveBarDef>::iterator it = live_defs.begin();
4018 it != live_defs.end();) {
4019 if (insn->serial >= it->defi->serial) {
4020 int rd = getRdDepBar(it->insn);
4021 emitWtDepBar(insn, rd);
4022 bars.clr(rd); // free barrier
4023 it = live_defs.erase(it);
4024 continue;
4025 }
4026 ++it;
4027 }
4028
4029 need_wr_bar = needWrDepBar(insn);
4030 need_rd_bar = needRdDepBar(insn);
4031
4032 if (need_wr_bar) {
4033 // When the instruction requires to emit a write dependency barrier
4034 // (all which write something at a variable latency), find the next
4035 // instruction which reads the outputs.
4036 usei = findFirstUse(insn);
4037
4038 // Allocate and emit a new barrier.
4039 bar_id = bars.findFreeRange(1);
4040 if (bar_id == -1)
4041 bar_id = 5;
4042 bars.set(bar_id);
4043 emitWrDepBar(insn, bar_id);
4044 if (usei)
4045 live_uses.push_back(LiveBarUse(insn, usei));
4046 }
4047
4048 if (need_rd_bar) {
4049 // When the instruction requires to emit a read dependency barrier
4050 // (all which read something at a variable latency), find the next
4051 // instruction which will write the inputs.
4052 defi = findFirstDef(insn);
4053
4054 if (usei && defi && usei->serial <= defi->serial)
4055 continue;
4056
4057 // Allocate and emit a new barrier.
4058 bar_id = bars.findFreeRange(1);
4059 if (bar_id == -1)
4060 bar_id = 5;
4061 bars.set(bar_id);
4062 emitRdDepBar(insn, bar_id);
4063 if (defi)
4064 live_defs.push_back(LiveBarDef(insn, defi));
4065 }
4066 }
4067
4068 // Remove unnecessary barrier waits.
4069 BitSet alive_bars(6, 1);
4070 for (insn = bb->getEntry(); insn != NULL; insn = next) {
4071 int wr, rd, wt;
4072
4073 next = insn->next;
4074
4075 wr = getWrDepBar(insn);
4076 rd = getRdDepBar(insn);
4077 wt = getWtDepBar(insn);
4078
4079 for (int idx = 0; idx < 6; ++idx) {
4080 if (!(wt & (1 << idx)))
4081 continue;
4082 if (!alive_bars.test(idx)) {
4083 insn->sched &= ~(1 << (11 + idx));
4084 } else {
4085 alive_bars.clr(idx);
4086 }
4087 }
4088
4089 if (wr < 6)
4090 alive_bars.set(wr);
4091 if (rd < 6)
4092 alive_bars.set(rd);
4093 }
4094
4095 return true;
4096 }
4097
4098 bool
4099 SchedDataCalculatorGM107::visit(Function *func)
4100 {
4101 ArrayList insns;
4102
4103 func->orderInstructions(insns);
4104
4105 scoreBoards.resize(func->cfg.getSize());
4106 for (size_t i = 0; i < scoreBoards.size(); ++i)
4107 scoreBoards[i].wipe();
4108 return true;
4109 }
4110
4111 bool
4112 SchedDataCalculatorGM107::visit(BasicBlock *bb)
4113 {
4114 Instruction *insn, *next = NULL;
4115 int cycle = 0;
4116
4117 for (Instruction *insn = bb->getEntry(); insn; insn = insn->next) {
4118 /*XXX*/
4119 insn->sched = 0x7e0;
4120 }
4121
4122 if (!debug_get_bool_option("NV50_PROG_SCHED", true))
4123 return true;
4124
4125 // Insert read/write dependency barriers for instructions which don't
4126 // operate at a fixed latency.
4127 insertBarriers(bb);
4128
4129 score = &scoreBoards.at(bb->getId());
4130
4131 for (Graph::EdgeIterator ei = bb->cfg.incident(); !ei.end(); ei.next()) {
4132 // back branches will wait until all target dependencies are satisfied
4133 if (ei.getType() == Graph::Edge::BACK) // sched would be uninitialized
4134 continue;
4135 BasicBlock *in = BasicBlock::get(ei.getNode());
4136 score->setMax(&scoreBoards.at(in->getId()));
4137 }
4138
4139 #ifdef GM107_DEBUG_SCHED_DATA
4140 INFO("=== BB:%i initial scores\n", bb->getId());
4141 score->print(cycle);
4142 #endif
4143
4144 // Because barriers are allocated locally (intra-BB), we have to make sure
4145 // that all produced barriers have been consumed before entering inside a
4146 // new basic block. The best way is to do a global allocation pre RA but
4147 // it's really more difficult, especially because of the phi nodes. Anyways,
4148 // it seems like that waiting on a barrier which has already been consumed
4149 // doesn't add any additional cost, it's just not elegant!
4150 Instruction *start = bb->getEntry();
4151 if (start && bb->cfg.incidentCount() > 0) {
4152 for (int b = 0; b < 6; b++)
4153 emitWtDepBar(start, b);
4154 }
4155
4156 for (insn = bb->getEntry(); insn && insn->next; insn = insn->next) {
4157 next = insn->next;
4158
4159 commitInsn(insn, cycle);
4160 int delay = calcDelay(next, cycle);
4161 setDelay(insn, delay, next);
4162 cycle += getStall(insn);
4163
4164 setReuseFlag(insn);
4165
4166 // XXX: The yield flag seems to destroy a bunch of things when it is
4167 // set on every instruction, need investigation.
4168 //emitYield(insn);
4169
4170 #ifdef GM107_DEBUG_SCHED_DATA
4171 printSchedInfo(cycle, insn);
4172 insn->print();
4173 next->print();
4174 #endif
4175 }
4176
4177 if (!insn)
4178 return true;
4179 commitInsn(insn, cycle);
4180
4181 int bbDelay = -1;
4182
4183 #ifdef GM107_DEBUG_SCHED_DATA
4184 fprintf(stderr, "last instruction is : ");
4185 insn->print();
4186 fprintf(stderr, "cycle=%d\n", cycle);
4187 #endif
4188
4189 for (Graph::EdgeIterator ei = bb->cfg.outgoing(); !ei.end(); ei.next()) {
4190 BasicBlock *out = BasicBlock::get(ei.getNode());
4191
4192 if (ei.getType() != Graph::Edge::BACK) {
4193 // Only test the first instruction of the outgoing block.
4194 next = out->getEntry();
4195 if (next) {
4196 bbDelay = MAX2(bbDelay, calcDelay(next, cycle));
4197 } else {
4198 // When the outgoing BB is empty, make sure to set the number of
4199 // stall counts needed by the instruction because we don't know the
4200 // next instruction.
4201 bbDelay = MAX2(bbDelay, targ->getLatency(insn));
4202 }
4203 } else {
4204 // Wait until all dependencies are satisfied.
4205 const int regsFree = score->getLatest();
4206 next = out->getFirst();
4207 for (int c = cycle; next && c < regsFree; next = next->next) {
4208 bbDelay = MAX2(bbDelay, calcDelay(next, c));
4209 c += getStall(next);
4210 }
4211 next = NULL;
4212 }
4213 }
4214 if (bb->cfg.outgoingCount() != 1)
4215 next = NULL;
4216 setDelay(insn, bbDelay, next);
4217 cycle += getStall(insn);
4218
4219 score->rebase(cycle); // common base for initializing out blocks' scores
4220 return true;
4221 }
4222
4223 /*******************************************************************************
4224 * main
4225 ******************************************************************************/
4226
4227 void
4228 CodeEmitterGM107::prepareEmission(Function *func)
4229 {
4230 SchedDataCalculatorGM107 sched(targGM107);
4231 CodeEmitter::prepareEmission(func);
4232 sched.run(func, true, true);
4233 }
4234
4235 static inline uint32_t sizeToBundlesGM107(uint32_t size)
4236 {
4237 return (size + 23) / 24;
4238 }
4239
4240 void
4241 CodeEmitterGM107::prepareEmission(Program *prog)
4242 {
4243 for (ArrayList::Iterator fi = prog->allFuncs.iterator();
4244 !fi.end(); fi.next()) {
4245 Function *func = reinterpret_cast<Function *>(fi.get());
4246 func->binPos = prog->binSize;
4247 prepareEmission(func);
4248
4249 // adjust sizes & positions for schedulding info:
4250 if (prog->getTarget()->hasSWSched) {
4251 uint32_t adjPos = func->binPos;
4252 BasicBlock *bb = NULL;
4253 for (int i = 0; i < func->bbCount; ++i) {
4254 bb = func->bbArray[i];
4255 int32_t adjSize = bb->binSize;
4256 if (adjPos % 32) {
4257 adjSize -= 32 - adjPos % 32;
4258 if (adjSize < 0)
4259 adjSize = 0;
4260 }
4261 adjSize = bb->binSize + sizeToBundlesGM107(adjSize) * 8;
4262 bb->binPos = adjPos;
4263 bb->binSize = adjSize;
4264 adjPos += adjSize;
4265 }
4266 if (bb)
4267 func->binSize = adjPos - func->binPos;
4268 }
4269
4270 prog->binSize += func->binSize;
4271 }
4272 }
4273
4274 CodeEmitterGM107::CodeEmitterGM107(const TargetGM107 *target)
4275 : CodeEmitter(target),
4276 targGM107(target),
4277 writeIssueDelays(target->hasSWSched)
4278 {
4279 code = NULL;
4280 codeSize = codeSizeLimit = 0;
4281 relocInfo = NULL;
4282 }
4283
4284 CodeEmitter *
4285 TargetGM107::createCodeEmitterGM107(Program::Type type)
4286 {
4287 CodeEmitterGM107 *emit = new CodeEmitterGM107(this);
4288 emit->setProgramType(type);
4289 return emit;
4290 }
4291
4292 } // namespace nv50_ir