gm107/ir: fix indirect txq emission
[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 namespace nv50_ir {
28
29 class CodeEmitterGM107 : public CodeEmitter
30 {
31 public:
32 CodeEmitterGM107(const TargetGM107 *);
33
34 virtual bool emitInstruction(Instruction *);
35 virtual uint32_t getMinEncodingSize(const Instruction *) const;
36
37 virtual void prepareEmission(Program *);
38 virtual void prepareEmission(Function *);
39
40 inline void setProgramType(Program::Type pType) { progType = pType; }
41
42 private:
43 const TargetGM107 *targGM107;
44
45 Program::Type progType;
46
47 const Instruction *insn;
48 const bool writeIssueDelays;
49 uint32_t *data;
50
51 private:
52 inline void emitField(uint32_t *, int, int, uint32_t);
53 inline void emitField(int b, int s, uint32_t v) { emitField(code, b, s, v); }
54
55 inline void emitInsn(uint32_t, bool);
56 inline void emitInsn(uint32_t o) { emitInsn(o, true); }
57 inline void emitPred();
58 inline void emitGPR(int, const Value *);
59 inline void emitGPR(int pos) {
60 emitGPR(pos, (const Value *)NULL);
61 }
62 inline void emitGPR(int pos, const ValueRef &ref) {
63 emitGPR(pos, ref.get() ? ref.rep() : (const Value *)NULL);
64 }
65 inline void emitGPR(int pos, const ValueRef *ref) {
66 emitGPR(pos, ref ? ref->rep() : (const Value *)NULL);
67 }
68 inline void emitGPR(int pos, const ValueDef &def) {
69 emitGPR(pos, def.get() ? def.rep() : (const Value *)NULL);
70 }
71 inline void emitSYS(int, const Value *);
72 inline void emitSYS(int pos, const ValueRef &ref) {
73 emitSYS(pos, ref.get() ? ref.rep() : (const Value *)NULL);
74 }
75 inline void emitPRED(int, const Value *);
76 inline void emitPRED(int pos) {
77 emitPRED(pos, (const Value *)NULL);
78 }
79 inline void emitPRED(int pos, const ValueRef &ref) {
80 emitPRED(pos, ref.get() ? ref.rep() : (const Value *)NULL);
81 }
82 inline void emitPRED(int pos, const ValueDef &def) {
83 emitPRED(pos, def.get() ? def.rep() : (const Value *)NULL);
84 }
85 inline void emitADDR(int, int, int, int, const ValueRef &);
86 inline void emitCBUF(int, int, int, int, int, const ValueRef &);
87 inline bool longIMMD(const ValueRef &);
88 inline void emitIMMD(int, int, const ValueRef &);
89
90 void emitCond3(int, CondCode);
91 void emitCond4(int, CondCode);
92 void emitCond5(int pos, CondCode cc) { emitCond4(pos, cc); }
93 inline void emitO(int);
94 inline void emitP(int);
95 inline void emitSAT(int);
96 inline void emitCC(int);
97 inline void emitX(int);
98 inline void emitABS(int, const ValueRef &);
99 inline void emitNEG(int, const ValueRef &);
100 inline void emitNEG2(int, const ValueRef &, const ValueRef &);
101 inline void emitFMZ(int, int);
102 inline void emitRND(int, RoundMode, int);
103 inline void emitRND(int pos) {
104 emitRND(pos, insn->rnd, -1);
105 }
106 inline void emitPDIV(int);
107 inline void emitINV(int, const ValueRef &);
108
109 void emitEXIT();
110 void emitBRA();
111 void emitCAL();
112 void emitPCNT();
113 void emitCONT();
114 void emitPBK();
115 void emitBRK();
116 void emitPRET();
117 void emitRET();
118 void emitSSY();
119 void emitSYNC();
120 void emitSAM();
121 void emitRAM();
122
123 void emitMOV();
124 void emitS2R();
125 void emitF2F();
126 void emitF2I();
127 void emitI2F();
128 void emitI2I();
129 void emitSHFL();
130
131 void emitDADD();
132 void emitDMUL();
133 void emitDFMA();
134 void emitDMNMX();
135 void emitDSET();
136 void emitDSETP();
137
138 void emitFADD();
139 void emitFMUL();
140 void emitFFMA();
141 void emitMUFU();
142 void emitFMNMX();
143 void emitRRO();
144 void emitFCMP();
145 void emitFSET();
146 void emitFSETP();
147 void emitFSWZADD();
148
149 void emitLOP();
150 void emitNOT();
151 void emitIADD();
152 void emitIMUL();
153 void emitIMAD();
154 void emitIMNMX();
155 void emitICMP();
156 void emitISET();
157 void emitISETP();
158 void emitSHL();
159 void emitSHR();
160 void emitPOPC();
161 void emitBFI();
162 void emitBFE();
163 void emitFLO();
164
165 void emitLDSTs(int, DataType);
166 void emitLDSTc(int);
167 void emitLDC();
168 void emitLDL();
169 void emitLDS();
170 void emitLD();
171 void emitSTL();
172 void emitSTS();
173 void emitST();
174 void emitALD();
175 void emitAST();
176 void emitISBERD();
177 void emitIPA();
178
179 void emitPIXLD();
180
181 void emitTEXs(int);
182 void emitTEX();
183 void emitTLD();
184 void emitTLD4();
185 void emitTXD();
186 void emitTXQ();
187 void emitTMML();
188 void emitDEPBAR();
189
190 void emitNOP();
191 void emitKIL();
192 void emitOUT();
193 };
194
195 /*******************************************************************************
196 * general instruction layout/fields
197 ******************************************************************************/
198
199 void
200 CodeEmitterGM107::emitField(uint32_t *data, int b, int s, uint32_t v)
201 {
202 if (b >= 0) {
203 uint32_t m = ((1ULL << s) - 1);
204 uint64_t d = (uint64_t)(v & m) << b;
205 assert(!(v & ~m) || (v & ~m) == ~m);
206 data[1] |= d >> 32;
207 data[0] |= d;
208 }
209 }
210
211 void
212 CodeEmitterGM107::emitPred()
213 {
214 if (insn->predSrc >= 0) {
215 emitField(16, 3, insn->getSrc(insn->predSrc)->rep()->reg.data.id);
216 emitField(19, 1, insn->cc == CC_NOT_P);
217 } else {
218 emitField(16, 3, 7);
219 }
220 }
221
222 void
223 CodeEmitterGM107::emitInsn(uint32_t hi, bool pred)
224 {
225 code[0] = 0x00000000;
226 code[1] = hi;
227 if (pred)
228 emitPred();
229 }
230
231 void
232 CodeEmitterGM107::emitGPR(int pos, const Value *val)
233 {
234 emitField(pos, 8, val ? val->reg.data.id : 255);
235 }
236
237 void
238 CodeEmitterGM107::emitSYS(int pos, const Value *val)
239 {
240 int id = val ? val->reg.data.id : -1;
241
242 switch (id) {
243 case SV_LANEID : id = 0x00; break;
244 case SV_VERTEX_COUNT : id = 0x10; break;
245 case SV_INVOCATION_ID : id = 0x11; break;
246 case SV_INVOCATION_INFO: id = 0x1d; break;
247 default:
248 assert(!"invalid system value");
249 id = 0;
250 break;
251 }
252
253 emitField(pos, 8, id);
254 }
255
256 void
257 CodeEmitterGM107::emitPRED(int pos, const Value *val)
258 {
259 emitField(pos, 3, val ? val->reg.data.id : 7);
260 }
261
262 void
263 CodeEmitterGM107::emitADDR(int gpr, int off, int len, int shr,
264 const ValueRef &ref)
265 {
266 const Value *v = ref.get();
267 assert(!(v->reg.data.offset & ((1 << shr) - 1)));
268 if (gpr >= 0)
269 emitGPR(gpr, ref.getIndirect(0));
270 emitField(off, len, v->reg.data.offset >> shr);
271 }
272
273 void
274 CodeEmitterGM107::emitCBUF(int buf, int gpr, int off, int len, int shr,
275 const ValueRef &ref)
276 {
277 const Value *v = ref.get();
278 const Symbol *s = v->asSym();
279
280 assert(!(s->reg.data.offset & ((1 << shr) - 1)));
281
282 emitField(buf, 5, v->reg.fileIndex);
283 if (gpr >= 0)
284 emitGPR(gpr, ref.getIndirect(0));
285 emitField(off, 16, s->reg.data.offset >> shr);
286 }
287
288 bool
289 CodeEmitterGM107::longIMMD(const ValueRef &ref)
290 {
291 if (ref.getFile() == FILE_IMMEDIATE) {
292 const ImmediateValue *imm = ref.get()->asImm();
293 if (isFloatType(insn->sType)) {
294 if ((imm->reg.data.u32 & 0x00000fff) != 0x00000000)
295 return true;
296 } else {
297 if ((imm->reg.data.u32 & 0xfff00000) != 0x00000000 &&
298 (imm->reg.data.u32 & 0xfff00000) != 0xfff00000)
299 return true;
300 }
301 }
302 return false;
303 }
304
305 void
306 CodeEmitterGM107::emitIMMD(int pos, int len, const ValueRef &ref)
307 {
308 const ImmediateValue *imm = ref.get()->asImm();
309 uint32_t val = imm->reg.data.u32;
310
311 if (len == 19) {
312 if (isFloatType(insn->sType)) {
313 assert(!(val & 0x00000fff));
314 val >>= 12;
315 }
316 assert(!(val & 0xfff00000) || (val & 0xfff00000) == 0xfff00000);
317 emitField( 56, 1, (val & 0x80000) >> 19);
318 emitField(pos, len, (val & 0x7ffff));
319 } else {
320 emitField(pos, len, val);
321 }
322 }
323
324 /*******************************************************************************
325 * modifiers
326 ******************************************************************************/
327
328 void
329 CodeEmitterGM107::emitCond3(int pos, CondCode code)
330 {
331 int data = 0;
332
333 switch (code) {
334 case CC_FL : data = 0x00; break;
335 case CC_LTU:
336 case CC_LT : data = 0x01; break;
337 case CC_EQU:
338 case CC_EQ : data = 0x02; break;
339 case CC_LEU:
340 case CC_LE : data = 0x03; break;
341 case CC_GTU:
342 case CC_GT : data = 0x04; break;
343 case CC_NEU:
344 case CC_NE : data = 0x05; break;
345 case CC_GEU:
346 case CC_GE : data = 0x06; break;
347 case CC_TR : data = 0x07; break;
348 default:
349 assert(!"invalid cond3");
350 break;
351 }
352
353 emitField(pos, 3, data);
354 }
355
356 void
357 CodeEmitterGM107::emitCond4(int pos, CondCode code)
358 {
359 int data = 0;
360
361 switch (code) {
362 case CC_FL: data = 0x00; break;
363 case CC_LT: data = 0x01; break;
364 case CC_EQ: data = 0x02; break;
365 case CC_LE: data = 0x03; break;
366 case CC_GT: data = 0x04; break;
367 case CC_NE: data = 0x05; break;
368 case CC_GE: data = 0x06; break;
369 // case CC_NUM: data = 0x07; break;
370 // case CC_NAN: data = 0x08; break;
371 case CC_LTU: data = 0x09; break;
372 case CC_EQU: data = 0x0a; break;
373 case CC_LEU: data = 0x0b; break;
374 case CC_GTU: data = 0x0c; break;
375 case CC_NEU: data = 0x0d; break;
376 case CC_GEU: data = 0x0e; break;
377 case CC_TR: data = 0x0f; break;
378 default:
379 assert(!"invalid cond4");
380 break;
381 }
382
383 emitField(pos, 4, data);
384 }
385
386 void
387 CodeEmitterGM107::emitO(int pos)
388 {
389 emitField(pos, 1, insn->getSrc(0)->reg.file == FILE_SHADER_OUTPUT);
390 }
391
392 void
393 CodeEmitterGM107::emitP(int pos)
394 {
395 emitField(pos, 1, insn->perPatch);
396 }
397
398 void
399 CodeEmitterGM107::emitSAT(int pos)
400 {
401 emitField(pos, 1, insn->saturate);
402 }
403
404 void
405 CodeEmitterGM107::emitCC(int pos)
406 {
407 emitField(pos, 1, insn->defExists(1));
408 }
409
410 void
411 CodeEmitterGM107::emitX(int pos)
412 {
413 emitField(pos, 1, insn->flagsSrc >= 0);
414 }
415
416 void
417 CodeEmitterGM107::emitABS(int pos, const ValueRef &ref)
418 {
419 emitField(pos, 1, ref.mod.abs());
420 }
421
422 void
423 CodeEmitterGM107::emitNEG(int pos, const ValueRef &ref)
424 {
425 emitField(pos, 1, ref.mod.neg());
426 }
427
428 void
429 CodeEmitterGM107::emitNEG2(int pos, const ValueRef &a, const ValueRef &b)
430 {
431 emitField(pos, 1, a.mod.neg() ^ b.mod.neg());
432 }
433
434 void
435 CodeEmitterGM107::emitFMZ(int pos, int len)
436 {
437 emitField(pos, len, insn->dnz << 1 | insn->ftz);
438 }
439
440 void
441 CodeEmitterGM107::emitRND(int rmp, RoundMode rnd, int rip)
442 {
443 int rm = 0, ri = 0;
444 switch (rnd) {
445 case ROUND_NI: ri = 1;
446 case ROUND_N : rm = 0; break;
447 case ROUND_MI: ri = 1;
448 case ROUND_M : rm = 1; break;
449 case ROUND_PI: ri = 1;
450 case ROUND_P : rm = 2; break;
451 case ROUND_ZI: ri = 1;
452 case ROUND_Z : rm = 3; break;
453 default:
454 assert(!"invalid round mode");
455 break;
456 }
457 emitField(rip, 1, ri);
458 emitField(rmp, 2, rm);
459 }
460
461 void
462 CodeEmitterGM107::emitPDIV(int pos)
463 {
464 assert(insn->postFactor >= -3 && insn->postFactor <= 3);
465 if (insn->postFactor > 0)
466 emitField(pos, 3, 7 - insn->postFactor);
467 else
468 emitField(pos, 3, 0 - insn->postFactor);
469 }
470
471 void
472 CodeEmitterGM107::emitINV(int pos, const ValueRef &ref)
473 {
474 emitField(pos, 1, !!(ref.mod & Modifier(NV50_IR_MOD_NOT)));
475 }
476
477 /*******************************************************************************
478 * control flow
479 ******************************************************************************/
480
481 void
482 CodeEmitterGM107::emitEXIT()
483 {
484 emitInsn (0xe3000000);
485 emitCond5(0x00, CC_TR);
486 }
487
488 void
489 CodeEmitterGM107::emitBRA()
490 {
491 const FlowInstruction *insn = this->insn->asFlow();
492 int gpr = -1;
493
494 if (insn->indirect) {
495 if (insn->absolute)
496 emitInsn(0xe2000000); // JMX
497 else
498 emitInsn(0xe2500000); // BRX
499 gpr = 0x08;
500 } else {
501 if (insn->absolute)
502 emitInsn(0xe2100000); // JMP
503 else
504 emitInsn(0xe2400000); // BRA
505 emitField(0x07, 1, insn->allWarp);
506 }
507
508 emitField(0x06, 1, insn->limit);
509 emitCond5(0x00, CC_TR);
510
511 if (!insn->srcExists(0) || insn->src(0).getFile() != FILE_MEMORY_CONST) {
512 int32_t pos = insn->target.bb->binPos;
513 if (writeIssueDelays && !(pos & 0x1f))
514 pos += 8;
515 if (!insn->absolute)
516 emitField(0x14, 24, pos - (codeSize + 8));
517 else
518 emitField(0x14, 32, pos);
519 } else {
520 emitCBUF (0x24, gpr, 20, 16, 0, insn->src(0));
521 emitField(0x05, 1, 1);
522 }
523 }
524
525 void
526 CodeEmitterGM107::emitCAL()
527 {
528 const FlowInstruction *insn = this->insn->asFlow();
529
530 if (insn->absolute) {
531 emitInsn(0xe2200000, 0); // JCAL
532 } else {
533 emitInsn(0xe2600000, 0); // CAL
534 }
535
536 if (!insn->srcExists(0) || insn->src(0).getFile() != FILE_MEMORY_CONST) {
537 if (!insn->absolute)
538 emitField(0x14, 24, insn->target.bb->binPos - (codeSize + 8));
539 else {
540 if (insn->builtin) {
541 int pcAbs = targGM107->getBuiltinOffset(insn->target.builtin);
542 addReloc(RelocEntry::TYPE_BUILTIN, 0, pcAbs, 0xfff00000, 20);
543 addReloc(RelocEntry::TYPE_BUILTIN, 1, pcAbs, 0x000fffff, -12);
544 } else {
545 emitField(0x14, 32, insn->target.bb->binPos);
546 }
547 }
548 } else {
549 emitCBUF (0x24, -1, 20, 16, 0, insn->src(0));
550 emitField(0x05, 1, 1);
551 }
552 }
553
554 void
555 CodeEmitterGM107::emitPCNT()
556 {
557 const FlowInstruction *insn = this->insn->asFlow();
558
559 emitInsn(0xe2b00000, 0);
560
561 if (!insn->srcExists(0) || insn->src(0).getFile() != FILE_MEMORY_CONST) {
562 emitField(0x14, 24, insn->target.bb->binPos - (codeSize + 8));
563 } else {
564 emitCBUF (0x24, -1, 20, 16, 0, insn->src(0));
565 emitField(0x05, 1, 1);
566 }
567 }
568
569 void
570 CodeEmitterGM107::emitCONT()
571 {
572 emitInsn (0xe3500000);
573 emitCond5(0x00, CC_TR);
574 }
575
576 void
577 CodeEmitterGM107::emitPBK()
578 {
579 const FlowInstruction *insn = this->insn->asFlow();
580
581 emitInsn(0xe2a00000, 0);
582
583 if (!insn->srcExists(0) || insn->src(0).getFile() != FILE_MEMORY_CONST) {
584 emitField(0x14, 24, insn->target.bb->binPos - (codeSize + 8));
585 } else {
586 emitCBUF (0x24, -1, 20, 16, 0, insn->src(0));
587 emitField(0x05, 1, 1);
588 }
589 }
590
591 void
592 CodeEmitterGM107::emitBRK()
593 {
594 emitInsn (0xe3400000);
595 emitCond5(0x00, CC_TR);
596 }
597
598 void
599 CodeEmitterGM107::emitPRET()
600 {
601 const FlowInstruction *insn = this->insn->asFlow();
602
603 emitInsn(0xe2700000, 0);
604
605 if (!insn->srcExists(0) || insn->src(0).getFile() != FILE_MEMORY_CONST) {
606 emitField(0x14, 24, insn->target.bb->binPos - (codeSize + 8));
607 } else {
608 emitCBUF (0x24, -1, 20, 16, 0, insn->src(0));
609 emitField(0x05, 1, 1);
610 }
611 }
612
613 void
614 CodeEmitterGM107::emitRET()
615 {
616 emitInsn (0xe3200000);
617 emitCond5(0x00, CC_TR);
618 }
619
620 void
621 CodeEmitterGM107::emitSSY()
622 {
623 const FlowInstruction *insn = this->insn->asFlow();
624
625 emitInsn(0xe2900000, 0);
626
627 if (!insn->srcExists(0) || insn->src(0).getFile() != FILE_MEMORY_CONST) {
628 emitField(0x14, 24, insn->target.bb->binPos - (codeSize + 8));
629 } else {
630 emitCBUF (0x24, -1, 20, 16, 0, insn->src(0));
631 emitField(0x05, 1, 1);
632 }
633 }
634
635 void
636 CodeEmitterGM107::emitSYNC()
637 {
638 emitInsn (0xf0f80000);
639 emitCond5(0x00, CC_TR);
640 }
641
642 void
643 CodeEmitterGM107::emitSAM()
644 {
645 emitInsn(0xe3700000, 0);
646 }
647
648 void
649 CodeEmitterGM107::emitRAM()
650 {
651 emitInsn(0xe3800000, 0);
652 }
653
654 /*******************************************************************************
655 * predicate/cc
656 ******************************************************************************/
657
658 /*******************************************************************************
659 * movement / conversion
660 ******************************************************************************/
661
662 void
663 CodeEmitterGM107::emitMOV()
664 {
665 if ( insn->src(0).getFile() != FILE_IMMEDIATE ||
666 (insn->sType != TYPE_F32 && !longIMMD(insn->src(0)))) {
667 switch (insn->src(0).getFile()) {
668 case FILE_GPR:
669 emitInsn(0x5c980000);
670 emitGPR (0x14, insn->src(0));
671 break;
672 case FILE_MEMORY_CONST:
673 emitInsn(0x4c980000);
674 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
675 break;
676 case FILE_IMMEDIATE:
677 emitInsn(0x38980000);
678 emitIMMD(0x14, 19, insn->src(0));
679 break;
680 default:
681 assert(!"bad src file");
682 break;
683 }
684 emitField(0x27, 4, insn->lanes);
685 } else {
686 emitInsn (0x01000000);
687 emitIMMD (0x14, 32, insn->src(0));
688 emitField(0x0c, 4, insn->lanes);
689 }
690
691 emitGPR(0x00, insn->def(0));
692 }
693
694 void
695 CodeEmitterGM107::emitS2R()
696 {
697 emitInsn(0xf0c80000);
698 emitSYS (0x14, insn->src(0));
699 emitGPR (0x00, insn->def(0));
700 }
701
702 void
703 CodeEmitterGM107::emitF2F()
704 {
705 RoundMode rnd = insn->rnd;
706
707 switch (insn->op) {
708 case OP_FLOOR: rnd = ROUND_MI; break;
709 case OP_CEIL : rnd = ROUND_PI; break;
710 case OP_TRUNC: rnd = ROUND_ZI; break;
711 default:
712 break;
713 }
714
715 switch (insn->src(0).getFile()) {
716 case FILE_GPR:
717 emitInsn(0x5ca80000);
718 emitGPR (0x14, insn->src(0));
719 break;
720 case FILE_MEMORY_CONST:
721 emitInsn(0x4ca80000);
722 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
723 break;
724 case FILE_IMMEDIATE:
725 emitInsn(0x38a80000);
726 emitIMMD(0x14, 19, insn->src(0));
727 break;
728 default:
729 assert(!"bad src0 file");
730 break;
731 }
732
733 emitField(0x32, 1, (insn->op == OP_SAT) || insn->saturate);
734 emitField(0x31, 1, (insn->op == OP_ABS) || insn->src(0).mod.abs());
735 emitCC (0x2f);
736 emitField(0x2d, 1, (insn->op == OP_NEG) || insn->src(0).mod.neg());
737 emitFMZ (0x2c, 1);
738 emitRND (0x27, rnd, 0x2a);
739 emitField(0x0a, 2, util_logbase2(typeSizeof(insn->sType)));
740 emitField(0x08, 2, util_logbase2(typeSizeof(insn->dType)));
741 emitGPR (0x00, insn->def(0));
742 }
743
744 void
745 CodeEmitterGM107::emitF2I()
746 {
747 RoundMode rnd = insn->rnd;
748
749 switch (insn->op) {
750 case OP_FLOOR: rnd = ROUND_M; break;
751 case OP_CEIL : rnd = ROUND_P; break;
752 case OP_TRUNC: rnd = ROUND_Z; break;
753 default:
754 break;
755 }
756
757 switch (insn->src(0).getFile()) {
758 case FILE_GPR:
759 emitInsn(0x5cb00000);
760 emitGPR (0x14, insn->src(0));
761 break;
762 case FILE_MEMORY_CONST:
763 emitInsn(0x4cb00000);
764 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
765 break;
766 case FILE_IMMEDIATE:
767 emitInsn(0x38b00000);
768 emitIMMD(0x14, 19, insn->src(0));
769 break;
770 default:
771 assert(!"bad src0 file");
772 break;
773 }
774
775 emitField(0x31, 1, (insn->op == OP_ABS) || insn->src(0).mod.abs());
776 emitCC (0x2f);
777 emitField(0x2d, 1, (insn->op == OP_NEG) || insn->src(0).mod.neg());
778 emitFMZ (0x2c, 1);
779 emitRND (0x27, rnd, 0x2a);
780 emitField(0x0c, 1, isSignedType(insn->dType));
781 emitField(0x0a, 2, util_logbase2(typeSizeof(insn->sType)));
782 emitField(0x08, 2, util_logbase2(typeSizeof(insn->dType)));
783 emitGPR (0x00, insn->def(0));
784 }
785
786 void
787 CodeEmitterGM107::emitI2F()
788 {
789 RoundMode rnd = insn->rnd;
790
791 switch (insn->op) {
792 case OP_FLOOR: rnd = ROUND_M; break;
793 case OP_CEIL : rnd = ROUND_P; break;
794 case OP_TRUNC: rnd = ROUND_Z; break;
795 default:
796 break;
797 }
798
799 switch (insn->src(0).getFile()) {
800 case FILE_GPR:
801 emitInsn(0x5cb80000);
802 emitGPR (0x14, insn->src(0));
803 break;
804 case FILE_MEMORY_CONST:
805 emitInsn(0x4cb80000);
806 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
807 break;
808 case FILE_IMMEDIATE:
809 emitInsn(0x38b80000);
810 emitIMMD(0x14, 19, insn->src(0));
811 break;
812 default:
813 assert(!"bad src0 file");
814 break;
815 }
816
817 emitField(0x31, 1, (insn->op == OP_ABS) || insn->src(0).mod.abs());
818 emitCC (0x2f);
819 emitField(0x2d, 1, (insn->op == OP_NEG) || insn->src(0).mod.neg());
820 emitRND (0x27, rnd, -1);
821 emitField(0x0d, 1, isSignedType(insn->sType));
822 emitField(0x0a, 2, util_logbase2(typeSizeof(insn->sType)));
823 emitField(0x08, 2, util_logbase2(typeSizeof(insn->dType)));
824 emitGPR (0x00, insn->def(0));
825 }
826
827 void
828 CodeEmitterGM107::emitI2I()
829 {
830 switch (insn->src(0).getFile()) {
831 case FILE_GPR:
832 emitInsn(0x5ce00000);
833 emitGPR (0x14, insn->src(0));
834 break;
835 case FILE_MEMORY_CONST:
836 emitInsn(0x4ce00000);
837 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
838 break;
839 case FILE_IMMEDIATE:
840 emitInsn(0x38e00000);
841 emitIMMD(0x14, 19, insn->src(0));
842 break;
843 default:
844 assert(!"bad src0 file");
845 break;
846 }
847
848 emitSAT (0x32);
849 emitField(0x31, 1, (insn->op == OP_ABS) || insn->src(0).mod.abs());
850 emitCC (0x2f);
851 emitField(0x2d, 1, (insn->op == OP_NEG) || insn->src(0).mod.neg());
852 emitField(0x0d, 1, isSignedType(insn->sType));
853 emitField(0x0c, 1, isSignedType(insn->dType));
854 emitField(0x0a, 2, util_logbase2(typeSizeof(insn->sType)));
855 emitField(0x08, 2, util_logbase2(typeSizeof(insn->dType)));
856 emitGPR (0x00, insn->def(0));
857 }
858
859 void
860 CodeEmitterGM107::emitSHFL()
861 {
862 int type = 0;
863
864 emitInsn (0xef100000);
865
866 switch (insn->src(1).getFile()) {
867 case FILE_GPR:
868 emitGPR(0x14, insn->src(1));
869 break;
870 case FILE_IMMEDIATE:
871 emitIMMD(0x14, 5, insn->src(1));
872 type |= 1;
873 break;
874 default:
875 assert(!"invalid src1 file");
876 break;
877 }
878
879 /*XXX: what is this arg? hardcode immediate for now */
880 emitField(0x22, 13, 0x1c03);
881 type |= 2;
882
883 emitPRED (0x30);
884 emitField(0x1e, 2, insn->subOp);
885 emitField(0x1c, 2, type);
886 emitGPR (0x08, insn->src(0));
887 emitGPR (0x00, insn->def(0));
888 }
889
890 /*******************************************************************************
891 * double
892 ******************************************************************************/
893
894 void
895 CodeEmitterGM107::emitDADD()
896 {
897 switch (insn->src(1).getFile()) {
898 case FILE_GPR:
899 emitInsn(0x5c700000);
900 emitGPR (0x14, insn->src(1));
901 break;
902 case FILE_MEMORY_CONST:
903 emitInsn(0x4c700000);
904 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
905 break;
906 case FILE_IMMEDIATE:
907 emitInsn(0x38700000);
908 emitIMMD(0x14, 19, insn->src(1));
909 break;
910 default:
911 assert(!"bad src1 file");
912 break;
913 }
914 emitABS(0x31, insn->src(1));
915 emitNEG(0x30, insn->src(0));
916 emitCC (0x2f);
917 emitABS(0x2e, insn->src(0));
918 emitNEG(0x2d, insn->src(1));
919
920 if (insn->op == OP_SUB)
921 code[1] ^= 0x00002000;
922
923 emitGPR(0x08, insn->src(0));
924 emitGPR(0x00, insn->def(0));
925 }
926
927 void
928 CodeEmitterGM107::emitDMUL()
929 {
930 switch (insn->src(1).getFile()) {
931 case FILE_GPR:
932 emitInsn(0x5c800000);
933 emitGPR (0x14, insn->src(1));
934 break;
935 case FILE_MEMORY_CONST:
936 emitInsn(0x4c800000);
937 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
938 break;
939 case FILE_IMMEDIATE:
940 emitInsn(0x38800000);
941 emitIMMD(0x14, 19, insn->src(1));
942 break;
943 default:
944 assert(!"bad src1 file");
945 break;
946 }
947
948 emitNEG2(0x30, insn->src(0), insn->src(1));
949 emitCC (0x2f);
950 emitRND (0x27);
951 emitGPR (0x08, insn->src(0));
952 emitGPR (0x00, insn->def(0));
953 }
954
955 void
956 CodeEmitterGM107::emitDFMA()
957 {
958 switch(insn->src(2).getFile()) {
959 case FILE_GPR:
960 switch (insn->src(1).getFile()) {
961 case FILE_GPR:
962 emitInsn(0x5b700000);
963 emitGPR (0x14, insn->src(1));
964 break;
965 case FILE_MEMORY_CONST:
966 emitInsn(0x4b700000);
967 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
968 break;
969 case FILE_IMMEDIATE:
970 emitInsn(0x36700000);
971 emitIMMD(0x14, 19, insn->src(1));
972 break;
973 default:
974 assert(!"bad src1 file");
975 break;
976 }
977 emitGPR (0x27, insn->src(2));
978 break;
979 case FILE_MEMORY_CONST:
980 emitInsn(0x53700000);
981 emitGPR (0x27, insn->src(1));
982 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(2));
983 break;
984 default:
985 assert(!"bad src2 file");
986 break;
987 }
988
989 emitRND (0x32);
990 emitNEG (0x31, insn->src(2));
991 emitNEG2(0x30, insn->src(0), insn->src(1));
992 emitCC (0x2f);
993 emitGPR (0x08, insn->src(0));
994 emitGPR (0x00, insn->def(0));
995 }
996
997 void
998 CodeEmitterGM107::emitDMNMX()
999 {
1000 switch (insn->src(1).getFile()) {
1001 case FILE_GPR:
1002 emitInsn(0x5c500000);
1003 emitGPR (0x14, insn->src(1));
1004 break;
1005 case FILE_MEMORY_CONST:
1006 emitInsn(0x4c500000);
1007 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1008 break;
1009 case FILE_IMMEDIATE:
1010 emitInsn(0x38500000);
1011 emitIMMD(0x14, 19, insn->src(1));
1012 break;
1013 default:
1014 assert(!"bad src1 file");
1015 break;
1016 }
1017
1018 emitABS (0x31, insn->src(1));
1019 emitNEG (0x30, insn->src(0));
1020 emitCC (0x2f);
1021 emitABS (0x2e, insn->src(0));
1022 emitNEG (0x2d, insn->src(1));
1023 emitField(0x2a, 1, insn->op == OP_MAX);
1024 emitPRED (0x27);
1025 emitGPR (0x08, insn->src(0));
1026 emitGPR (0x00, insn->def(0));
1027 }
1028
1029 void
1030 CodeEmitterGM107::emitDSET()
1031 {
1032 const CmpInstruction *insn = this->insn->asCmp();
1033
1034 switch (insn->src(1).getFile()) {
1035 case FILE_GPR:
1036 emitInsn(0x59000000);
1037 emitGPR (0x14, insn->src(1));
1038 break;
1039 case FILE_MEMORY_CONST:
1040 emitInsn(0x49000000);
1041 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1042 break;
1043 case FILE_IMMEDIATE:
1044 emitInsn(0x32000000);
1045 emitIMMD(0x14, 19, insn->src(1));
1046 break;
1047 default:
1048 assert(!"bad src1 file");
1049 break;
1050 }
1051
1052 if (insn->op != OP_SET) {
1053 switch (insn->op) {
1054 case OP_SET_AND: emitField(0x2d, 2, 0); break;
1055 case OP_SET_OR : emitField(0x2d, 2, 1); break;
1056 case OP_SET_XOR: emitField(0x2d, 2, 2); break;
1057 default:
1058 assert(!"invalid set op");
1059 break;
1060 }
1061 emitPRED(0x27, insn->src(2));
1062 } else {
1063 emitPRED(0x27);
1064 }
1065
1066 emitABS (0x36, insn->src(0));
1067 emitNEG (0x35, insn->src(1));
1068 emitField(0x34, 1, insn->dType == TYPE_F32);
1069 emitCond4(0x30, insn->setCond);
1070 emitCC (0x2f);
1071 emitABS (0x2c, insn->src(1));
1072 emitNEG (0x2b, insn->src(0));
1073 emitGPR (0x08, insn->src(0));
1074 emitGPR (0x00, insn->def(0));
1075 }
1076
1077 void
1078 CodeEmitterGM107::emitDSETP()
1079 {
1080 const CmpInstruction *insn = this->insn->asCmp();
1081
1082 switch (insn->src(1).getFile()) {
1083 case FILE_GPR:
1084 emitInsn(0x5b800000);
1085 emitGPR (0x14, insn->src(1));
1086 break;
1087 case FILE_MEMORY_CONST:
1088 emitInsn(0x4b800000);
1089 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1090 break;
1091 case FILE_IMMEDIATE:
1092 emitInsn(0x36800000);
1093 emitIMMD(0x14, 19, insn->src(1));
1094 break;
1095 default:
1096 assert(!"bad src1 file");
1097 break;
1098 }
1099
1100 if (insn->op != OP_SET) {
1101 switch (insn->op) {
1102 case OP_SET_AND: emitField(0x2d, 2, 0); break;
1103 case OP_SET_OR : emitField(0x2d, 2, 1); break;
1104 case OP_SET_XOR: emitField(0x2d, 2, 2); break;
1105 default:
1106 assert(!"invalid set op");
1107 break;
1108 }
1109 emitPRED(0x27, insn->src(2));
1110 } else {
1111 emitPRED(0x27);
1112 }
1113
1114 emitCond4(0x30, insn->setCond);
1115 emitABS (0x2c, insn->src(1));
1116 emitNEG (0x2b, insn->src(0));
1117 emitGPR (0x08, insn->src(0));
1118 emitABS (0x07, insn->src(0));
1119 emitNEG (0x06, insn->src(1));
1120 emitPRED (0x03, insn->def(0));
1121 if (insn->defExists(1))
1122 emitPRED(0x00, insn->def(1));
1123 else
1124 emitPRED(0x00);
1125 }
1126
1127 /*******************************************************************************
1128 * float
1129 ******************************************************************************/
1130
1131 void
1132 CodeEmitterGM107::emitFADD()
1133 {
1134 if (!longIMMD(insn->src(1))) {
1135 switch (insn->src(1).getFile()) {
1136 case FILE_GPR:
1137 emitInsn(0x5c580000);
1138 emitGPR (0x14, insn->src(1));
1139 break;
1140 case FILE_MEMORY_CONST:
1141 emitInsn(0x4c580000);
1142 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1143 break;
1144 case FILE_IMMEDIATE:
1145 emitInsn(0x38580000);
1146 emitIMMD(0x14, 19, insn->src(1));
1147 break;
1148 default:
1149 assert(!"bad src1 file");
1150 break;
1151 }
1152 emitSAT(0x32);
1153 emitABS(0x31, insn->src(1));
1154 emitNEG(0x30, insn->src(0));
1155 emitCC (0x2f);
1156 emitABS(0x2e, insn->src(0));
1157 emitNEG(0x2d, insn->src(1));
1158 emitFMZ(0x2c, 1);
1159 } else {
1160 emitInsn(0x08000000);
1161 emitABS(0x39, insn->src(1));
1162 emitNEG(0x38, insn->src(0));
1163 emitFMZ(0x37, 1);
1164 emitABS(0x36, insn->src(0));
1165 emitNEG(0x35, insn->src(1));
1166 emitCC (0x34);
1167 emitIMMD(0x14, 32, insn->src(1));
1168 }
1169
1170 if (insn->op == OP_SUB)
1171 code[1] ^= 0x00002000;
1172
1173 emitGPR(0x08, insn->src(0));
1174 emitGPR(0x00, insn->def(0));
1175 }
1176
1177 void
1178 CodeEmitterGM107::emitFMUL()
1179 {
1180 if (!longIMMD(insn->src(1))) {
1181 switch (insn->src(1).getFile()) {
1182 case FILE_GPR:
1183 emitInsn(0x5c680000);
1184 emitGPR (0x14, insn->src(1));
1185 break;
1186 case FILE_MEMORY_CONST:
1187 emitInsn(0x4c680000);
1188 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1189 break;
1190 case FILE_IMMEDIATE:
1191 emitInsn(0x38680000);
1192 emitIMMD(0x14, 19, insn->src(1));
1193 break;
1194 default:
1195 assert(!"bad src1 file");
1196 break;
1197 }
1198 emitSAT (0x32);
1199 emitNEG2(0x30, insn->src(0), insn->src(1));
1200 emitCC (0x2f);
1201 emitFMZ (0x2c, 2);
1202 emitPDIV(0x29);
1203 emitRND (0x27);
1204 } else {
1205 emitInsn(0x1e000000);
1206 emitSAT (0x37);
1207 emitFMZ (0x35, 2);
1208 emitCC (0x34);
1209 emitIMMD(0x14, 32, insn->src(1));
1210 if (insn->src(0).mod.neg() ^ insn->src(1).mod.neg())
1211 code[1] ^= 0x00080000; /* flip immd sign bit */
1212 }
1213
1214 emitGPR(0x08, insn->src(0));
1215 emitGPR(0x00, insn->def(0));
1216 }
1217
1218 void
1219 CodeEmitterGM107::emitFFMA()
1220 {
1221 /*XXX: ffma32i exists, but not using it as third src overlaps dst */
1222 switch(insn->src(2).getFile()) {
1223 case FILE_GPR:
1224 switch (insn->src(1).getFile()) {
1225 case FILE_GPR:
1226 emitInsn(0x59800000);
1227 emitGPR (0x14, insn->src(1));
1228 break;
1229 case FILE_MEMORY_CONST:
1230 emitInsn(0x49800000);
1231 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1232 break;
1233 case FILE_IMMEDIATE:
1234 emitInsn(0x32800000);
1235 emitIMMD(0x14, 19, insn->src(1));
1236 break;
1237 default:
1238 assert(!"bad src1 file");
1239 break;
1240 }
1241 emitGPR (0x27, insn->src(2));
1242 break;
1243 case FILE_MEMORY_CONST:
1244 emitInsn(0x51800000);
1245 emitGPR (0x27, insn->src(1));
1246 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(2));
1247 break;
1248 default:
1249 assert(!"bad src2 file");
1250 break;
1251 }
1252 emitRND (0x33);
1253 emitSAT (0x32);
1254 emitNEG (0x31, insn->src(2));
1255 emitNEG2(0x30, insn->src(0), insn->src(1));
1256 emitCC (0x2f);
1257
1258 emitFMZ(0x35, 2);
1259 emitGPR(0x08, insn->src(0));
1260 emitGPR(0x00, insn->def(0));
1261 }
1262
1263 void
1264 CodeEmitterGM107::emitMUFU()
1265 {
1266 int mufu = 0;
1267
1268 switch (insn->op) {
1269 case OP_COS: mufu = 0; break;
1270 case OP_SIN: mufu = 1; break;
1271 case OP_EX2: mufu = 2; break;
1272 case OP_LG2: mufu = 3; break;
1273 case OP_RCP: mufu = 4 + 2 * insn->subOp; break;
1274 case OP_RSQ: mufu = 5 + 2 * insn->subOp; break;
1275 default:
1276 assert(!"invalid mufu");
1277 break;
1278 }
1279
1280 emitInsn (0x50800000);
1281 emitSAT (0x32);
1282 emitNEG (0x30, insn->src(0));
1283 emitABS (0x2e, insn->src(0));
1284 emitField(0x14, 3, mufu);
1285 emitGPR (0x08, insn->src(0));
1286 emitGPR (0x00, insn->def(0));
1287 }
1288
1289 void
1290 CodeEmitterGM107::emitFMNMX()
1291 {
1292 switch (insn->src(1).getFile()) {
1293 case FILE_GPR:
1294 emitInsn(0x5c600000);
1295 emitGPR (0x14, insn->src(1));
1296 break;
1297 case FILE_MEMORY_CONST:
1298 emitInsn(0x4c600000);
1299 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1300 break;
1301 case FILE_IMMEDIATE:
1302 emitInsn(0x38600000);
1303 emitIMMD(0x14, 19, insn->src(1));
1304 break;
1305 default:
1306 assert(!"bad src1 file");
1307 break;
1308 }
1309
1310 emitField(0x2a, 1, insn->op == OP_MAX);
1311 emitPRED (0x27);
1312
1313 emitABS(0x31, insn->src(1));
1314 emitNEG(0x30, insn->src(0));
1315 emitCC (0x2f);
1316 emitABS(0x2e, insn->src(0));
1317 emitNEG(0x2d, insn->src(1));
1318 emitFMZ(0x2c, 1);
1319 emitGPR(0x08, insn->src(0));
1320 emitGPR(0x00, insn->def(0));
1321 }
1322
1323 void
1324 CodeEmitterGM107::emitRRO()
1325 {
1326 switch (insn->src(0).getFile()) {
1327 case FILE_GPR:
1328 emitInsn(0x5c900000);
1329 emitGPR (0x14, insn->src(0));
1330 break;
1331 case FILE_MEMORY_CONST:
1332 emitInsn(0x4c900000);
1333 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
1334 break;
1335 case FILE_IMMEDIATE:
1336 emitInsn(0x38900000);
1337 emitIMMD(0x14, 19, insn->src(0));
1338 break;
1339 default:
1340 assert(!"bad src file");
1341 break;
1342 }
1343
1344 emitABS (0x31, insn->src(0));
1345 emitNEG (0x2d, insn->src(0));
1346 emitField(0x27, 1, insn->op == OP_PREEX2);
1347 emitGPR (0x00, insn->def(0));
1348 }
1349
1350 void
1351 CodeEmitterGM107::emitFCMP()
1352 {
1353 const CmpInstruction *insn = this->insn->asCmp();
1354 CondCode cc = insn->setCond;
1355
1356 if (insn->src(2).mod.neg())
1357 cc = reverseCondCode(cc);
1358
1359 switch(insn->src(2).getFile()) {
1360 case FILE_GPR:
1361 switch (insn->src(1).getFile()) {
1362 case FILE_GPR:
1363 emitInsn(0x5ba00000);
1364 emitGPR (0x14, insn->src(1));
1365 break;
1366 case FILE_MEMORY_CONST:
1367 emitInsn(0x4ba00000);
1368 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1369 break;
1370 case FILE_IMMEDIATE:
1371 emitInsn(0x36a00000);
1372 emitIMMD(0x14, 19, insn->src(1));
1373 break;
1374 default:
1375 assert(!"bad src1 file");
1376 break;
1377 }
1378 emitGPR (0x27, insn->src(2));
1379 break;
1380 case FILE_MEMORY_CONST:
1381 emitInsn(0x53a00000);
1382 emitGPR (0x27, insn->src(1));
1383 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(2));
1384 break;
1385 default:
1386 assert(!"bad src2 file");
1387 break;
1388 }
1389
1390 emitCond4(0x30, cc);
1391 emitFMZ (0x2f, 1);
1392 emitGPR (0x08, insn->src(0));
1393 emitGPR (0x00, insn->def(0));
1394 }
1395
1396 void
1397 CodeEmitterGM107::emitFSET()
1398 {
1399 const CmpInstruction *insn = this->insn->asCmp();
1400
1401 switch (insn->src(1).getFile()) {
1402 case FILE_GPR:
1403 emitInsn(0x58000000);
1404 emitGPR (0x14, insn->src(1));
1405 break;
1406 case FILE_MEMORY_CONST:
1407 emitInsn(0x48000000);
1408 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1409 break;
1410 case FILE_IMMEDIATE:
1411 emitInsn(0x30000000);
1412 emitIMMD(0x14, 19, insn->src(1));
1413 break;
1414 default:
1415 assert(!"bad src1 file");
1416 break;
1417 }
1418
1419 if (insn->op != OP_SET) {
1420 switch (insn->op) {
1421 case OP_SET_AND: emitField(0x2d, 2, 0); break;
1422 case OP_SET_OR : emitField(0x2d, 2, 1); break;
1423 case OP_SET_XOR: emitField(0x2d, 2, 2); break;
1424 default:
1425 assert(!"invalid set op");
1426 break;
1427 }
1428 emitPRED(0x27, insn->src(2));
1429 } else {
1430 emitPRED(0x27);
1431 }
1432
1433 emitFMZ (0x37, 1);
1434 emitABS (0x36, insn->src(0));
1435 emitNEG (0x35, insn->src(1));
1436 emitField(0x34, 1, insn->dType == TYPE_F32);
1437 emitCond4(0x30, insn->setCond);
1438 emitCC (0x2f);
1439 emitABS (0x2c, insn->src(1));
1440 emitNEG (0x2b, insn->src(0));
1441 emitGPR (0x08, insn->src(0));
1442 emitGPR (0x00, insn->def(0));
1443 }
1444
1445 void
1446 CodeEmitterGM107::emitFSETP()
1447 {
1448 const CmpInstruction *insn = this->insn->asCmp();
1449
1450 switch (insn->src(1).getFile()) {
1451 case FILE_GPR:
1452 emitInsn(0x5bb00000);
1453 emitGPR (0x14, insn->src(1));
1454 break;
1455 case FILE_MEMORY_CONST:
1456 emitInsn(0x4bb00000);
1457 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1458 break;
1459 case FILE_IMMEDIATE:
1460 emitInsn(0x36b00000);
1461 emitIMMD(0x14, 19, insn->src(1));
1462 break;
1463 default:
1464 assert(!"bad src1 file");
1465 break;
1466 }
1467
1468 if (insn->op != OP_SET) {
1469 switch (insn->op) {
1470 case OP_SET_AND: emitField(0x2d, 2, 0); break;
1471 case OP_SET_OR : emitField(0x2d, 2, 1); break;
1472 case OP_SET_XOR: emitField(0x2d, 2, 2); break;
1473 default:
1474 assert(!"invalid set op");
1475 break;
1476 }
1477 emitPRED(0x27, insn->src(2));
1478 } else {
1479 emitPRED(0x27);
1480 }
1481
1482 emitCond4(0x30, insn->setCond);
1483 emitFMZ (0x2f, 1);
1484 emitABS (0x2c, insn->src(1));
1485 emitNEG (0x2b, insn->src(0));
1486 emitGPR (0x08, insn->src(0));
1487 emitABS (0x07, insn->src(0));
1488 emitNEG (0x06, insn->src(1));
1489 emitPRED (0x03, insn->def(0));
1490 if (insn->defExists(1))
1491 emitPRED(0x00, insn->def(1));
1492 else
1493 emitPRED(0x00);
1494 }
1495
1496 void
1497 CodeEmitterGM107::emitFSWZADD()
1498 {
1499 emitInsn (0x50f80000);
1500 emitCC (0x2f);
1501 emitFMZ (0x2c, 1);
1502 emitRND (0x27);
1503 emitField(0x26, 1, insn->lanes); /* abused for .ndv */
1504 emitField(0x1c, 8, insn->subOp);
1505 emitGPR (0x14, insn->src(1));
1506 emitGPR (0x08, insn->src(0));
1507 emitGPR (0x00, insn->def(0));
1508 }
1509
1510 /*******************************************************************************
1511 * integer
1512 ******************************************************************************/
1513
1514 void
1515 CodeEmitterGM107::emitLOP()
1516 {
1517 int lop = 0;
1518
1519 switch (insn->op) {
1520 case OP_AND: lop = 0; break;
1521 case OP_OR : lop = 1; break;
1522 case OP_XOR: lop = 2; break;
1523 default:
1524 assert(!"invalid lop");
1525 break;
1526 }
1527
1528 if (!longIMMD(insn->src(1))) {
1529 switch (insn->src(1).getFile()) {
1530 case FILE_GPR:
1531 emitInsn(0x5c400000);
1532 emitGPR (0x14, insn->src(1));
1533 break;
1534 case FILE_MEMORY_CONST:
1535 emitInsn(0x4c400000);
1536 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1537 break;
1538 case FILE_IMMEDIATE:
1539 emitInsn(0x38400000);
1540 emitIMMD(0x14, 19, insn->src(1));
1541 break;
1542 default:
1543 assert(!"bad src1 file");
1544 break;
1545 }
1546 emitPRED (0x30);
1547 emitField(0x29, 2, lop);
1548 emitINV (0x28, insn->src(1));
1549 emitINV (0x27, insn->src(0));
1550 } else {
1551 emitInsn (0x04000000);
1552 emitINV (0x38, insn->src(1));
1553 emitINV (0x37, insn->src(0));
1554 emitField(0x35, 2, lop);
1555 emitIMMD (0x14, 32, insn->src(1));
1556 }
1557
1558 emitGPR (0x08, insn->src(0));
1559 emitGPR (0x00, insn->def(0));
1560 }
1561
1562 /* special-case of emitLOP(): lop pass_b dst 0 ~src */
1563 void
1564 CodeEmitterGM107::emitNOT()
1565 {
1566 if (!longIMMD(insn->src(0))) {
1567 switch (insn->src(0).getFile()) {
1568 case FILE_GPR:
1569 emitInsn(0x5c400700);
1570 emitGPR (0x14, insn->src(0));
1571 break;
1572 case FILE_MEMORY_CONST:
1573 emitInsn(0x4c400700);
1574 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
1575 break;
1576 case FILE_IMMEDIATE:
1577 emitInsn(0x38400700);
1578 emitIMMD(0x14, 19, insn->src(0));
1579 break;
1580 default:
1581 assert(!"bad src1 file");
1582 break;
1583 }
1584 emitPRED (0x30);
1585 } else {
1586 emitInsn (0x05600000);
1587 emitIMMD (0x14, 32, insn->src(1));
1588 }
1589
1590 emitGPR(0x08);
1591 emitGPR(0x00, insn->def(0));
1592 }
1593
1594 void
1595 CodeEmitterGM107::emitIADD()
1596 {
1597 if (!longIMMD(insn->src(1))) {
1598 switch (insn->src(1).getFile()) {
1599 case FILE_GPR:
1600 emitInsn(0x5c100000);
1601 emitGPR (0x14, insn->src(1));
1602 break;
1603 case FILE_MEMORY_CONST:
1604 emitInsn(0x4c100000);
1605 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1606 break;
1607 case FILE_IMMEDIATE:
1608 emitInsn(0x38100000);
1609 emitIMMD(0x14, 19, insn->src(1));
1610 break;
1611 default:
1612 assert(!"bad src1 file");
1613 break;
1614 }
1615 emitSAT(0x32);
1616 emitNEG(0x31, insn->src(0));
1617 emitNEG(0x30, insn->src(1));
1618 emitCC (0x2f);
1619 } else {
1620 emitInsn(0x1c000000);
1621 emitSAT (0x36);
1622 emitCC (0x34);
1623 emitIMMD(0x14, 32, insn->src(1));
1624 }
1625
1626 if (insn->op == OP_SUB)
1627 code[1] ^= 0x00010000;
1628
1629 emitGPR(0x08, insn->src(0));
1630 emitGPR(0x00, insn->def(0));
1631 }
1632
1633 void
1634 CodeEmitterGM107::emitIMUL()
1635 {
1636 if (!longIMMD(insn->src(1))) {
1637 switch (insn->src(1).getFile()) {
1638 case FILE_GPR:
1639 emitInsn(0x5c380000);
1640 emitGPR (0x14, insn->src(1));
1641 break;
1642 case FILE_MEMORY_CONST:
1643 emitInsn(0x4c380000);
1644 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1645 break;
1646 case FILE_IMMEDIATE:
1647 emitInsn(0x38380000);
1648 emitIMMD(0x14, 19, insn->src(1));
1649 break;
1650 default:
1651 assert(!"bad src1 file");
1652 break;
1653 }
1654 emitCC (0x2f);
1655 emitField(0x29, 1, isSignedType(insn->sType));
1656 emitField(0x28, 1, isSignedType(insn->dType));
1657 emitField(0x27, 1, insn->subOp == NV50_IR_SUBOP_MUL_HIGH);
1658 } else {
1659 emitInsn (0x1f000000);
1660 emitField(0x37, 1, isSignedType(insn->sType));
1661 emitField(0x36, 1, isSignedType(insn->dType));
1662 emitField(0x35, 1, insn->subOp == NV50_IR_SUBOP_MUL_HIGH);
1663 emitCC (0x34);
1664 emitIMMD (0x14, 32, insn->src(1));
1665 }
1666
1667 emitGPR(0x08, insn->src(0));
1668 emitGPR(0x00, insn->def(0));
1669 }
1670
1671 void
1672 CodeEmitterGM107::emitIMAD()
1673 {
1674 /*XXX: imad32i exists, but not using it as third src overlaps dst */
1675 switch(insn->src(2).getFile()) {
1676 case FILE_GPR:
1677 switch (insn->src(1).getFile()) {
1678 case FILE_GPR:
1679 emitInsn(0x5a000000);
1680 emitGPR (0x14, insn->src(1));
1681 break;
1682 case FILE_MEMORY_CONST:
1683 emitInsn(0x4a000000);
1684 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1685 break;
1686 case FILE_IMMEDIATE:
1687 emitInsn(0x34000000);
1688 emitIMMD(0x14, 19, insn->src(1));
1689 break;
1690 default:
1691 assert(!"bad src1 file");
1692 break;
1693 }
1694 emitGPR (0x27, insn->src(2));
1695 break;
1696 case FILE_MEMORY_CONST:
1697 emitInsn(0x52000000);
1698 emitGPR (0x27, insn->src(1));
1699 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(2));
1700 break;
1701 default:
1702 assert(!"bad src2 file");
1703 break;
1704 }
1705
1706 emitField(0x36, 1, insn->subOp == NV50_IR_SUBOP_MUL_HIGH);
1707 emitField(0x35, 1, isSignedType(insn->sType));
1708 emitNEG (0x34, insn->src(2));
1709 emitNEG2 (0x33, insn->src(0), insn->src(1));
1710 emitSAT (0x32);
1711 emitX (0x31);
1712 emitField(0x30, 1, isSignedType(insn->dType));
1713 emitCC (0x2f);
1714 emitGPR (0x08, insn->src(0));
1715 emitGPR (0x00, insn->def(0));
1716 }
1717
1718 void
1719 CodeEmitterGM107::emitIMNMX()
1720 {
1721 switch (insn->src(1).getFile()) {
1722 case FILE_GPR:
1723 emitInsn(0x5c200000);
1724 emitGPR (0x14, insn->src(1));
1725 break;
1726 case FILE_MEMORY_CONST:
1727 emitInsn(0x4c200000);
1728 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1729 break;
1730 case FILE_IMMEDIATE:
1731 emitInsn(0x38200000);
1732 emitIMMD(0x14, 19, insn->src(1));
1733 break;
1734 default:
1735 assert(!"bad src1 file");
1736 break;
1737 }
1738
1739 emitField(0x30, 1, isSignedType(insn->dType));
1740 emitCC (0x2f);
1741 emitField(0x2a, 1, insn->op == OP_MAX);
1742 emitPRED (0x27);
1743 emitGPR (0x08, insn->src(0));
1744 emitGPR (0x00, insn->def(0));
1745 }
1746
1747 void
1748 CodeEmitterGM107::emitICMP()
1749 {
1750 const CmpInstruction *insn = this->insn->asCmp();
1751 CondCode cc = insn->setCond;
1752
1753 if (insn->src(2).mod.neg())
1754 cc = reverseCondCode(cc);
1755
1756 switch(insn->src(2).getFile()) {
1757 case FILE_GPR:
1758 switch (insn->src(1).getFile()) {
1759 case FILE_GPR:
1760 emitInsn(0x5b400000);
1761 emitGPR (0x14, insn->src(1));
1762 break;
1763 case FILE_MEMORY_CONST:
1764 emitInsn(0x4b400000);
1765 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1766 break;
1767 case FILE_IMMEDIATE:
1768 emitInsn(0x36400000);
1769 emitIMMD(0x14, 19, insn->src(1));
1770 break;
1771 default:
1772 assert(!"bad src1 file");
1773 break;
1774 }
1775 emitGPR (0x27, insn->src(2));
1776 break;
1777 case FILE_MEMORY_CONST:
1778 emitInsn(0x53400000);
1779 emitGPR (0x27, insn->src(1));
1780 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(2));
1781 break;
1782 default:
1783 assert(!"bad src2 file");
1784 break;
1785 }
1786
1787 emitCond3(0x31, cc);
1788 emitField(0x30, 1, isSignedType(insn->sType));
1789 emitGPR (0x08, insn->src(0));
1790 emitGPR (0x00, insn->def(0));
1791 }
1792
1793 void
1794 CodeEmitterGM107::emitISET()
1795 {
1796 const CmpInstruction *insn = this->insn->asCmp();
1797
1798 switch (insn->src(1).getFile()) {
1799 case FILE_GPR:
1800 emitInsn(0x5b500000);
1801 emitGPR (0x14, insn->src(1));
1802 break;
1803 case FILE_MEMORY_CONST:
1804 emitInsn(0x4b500000);
1805 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1806 break;
1807 case FILE_IMMEDIATE:
1808 emitInsn(0x36500000);
1809 emitIMMD(0x14, 19, insn->src(1));
1810 break;
1811 default:
1812 assert(!"bad src1 file");
1813 break;
1814 }
1815
1816 if (insn->op != OP_SET) {
1817 switch (insn->op) {
1818 case OP_SET_AND: emitField(0x2d, 2, 0); break;
1819 case OP_SET_OR : emitField(0x2d, 2, 1); break;
1820 case OP_SET_XOR: emitField(0x2d, 2, 2); break;
1821 default:
1822 assert(!"invalid set op");
1823 break;
1824 }
1825 emitPRED(0x27, insn->src(2));
1826 } else {
1827 emitPRED(0x27);
1828 }
1829
1830 emitCond3(0x31, insn->setCond);
1831 emitField(0x30, 1, isSignedType(insn->sType));
1832 emitCC (0x2f);
1833 emitField(0x2c, 1, insn->dType == TYPE_F32);
1834 emitX (0x2b);
1835 emitGPR (0x08, insn->src(0));
1836 emitGPR (0x00, insn->def(0));
1837 }
1838
1839 void
1840 CodeEmitterGM107::emitISETP()
1841 {
1842 const CmpInstruction *insn = this->insn->asCmp();
1843
1844 switch (insn->src(1).getFile()) {
1845 case FILE_GPR:
1846 emitInsn(0x5b600000);
1847 emitGPR (0x14, insn->src(1));
1848 break;
1849 case FILE_MEMORY_CONST:
1850 emitInsn(0x4b600000);
1851 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1852 break;
1853 case FILE_IMMEDIATE:
1854 emitInsn(0x36600000);
1855 emitIMMD(0x14, 19, insn->src(1));
1856 break;
1857 default:
1858 assert(!"bad src1 file");
1859 break;
1860 }
1861
1862 if (insn->op != OP_SET) {
1863 switch (insn->op) {
1864 case OP_SET_AND: emitField(0x2d, 2, 0); break;
1865 case OP_SET_OR : emitField(0x2d, 2, 1); break;
1866 case OP_SET_XOR: emitField(0x2d, 2, 2); break;
1867 default:
1868 assert(!"invalid set op");
1869 break;
1870 }
1871 emitPRED(0x27, insn->src(2));
1872 } else {
1873 emitPRED(0x27);
1874 }
1875
1876 emitCond3(0x31, insn->setCond);
1877 emitField(0x30, 1, isSignedType(insn->sType));
1878 emitX (0x2b);
1879 emitGPR (0x08, insn->src(0));
1880 emitPRED (0x03, insn->def(0));
1881 if (insn->defExists(1))
1882 emitPRED(0x00, insn->def(1));
1883 else
1884 emitPRED(0x00);
1885 }
1886
1887 void
1888 CodeEmitterGM107::emitSHL()
1889 {
1890 switch (insn->src(1).getFile()) {
1891 case FILE_GPR:
1892 emitInsn(0x5c480000);
1893 emitGPR (0x14, insn->src(1));
1894 break;
1895 case FILE_MEMORY_CONST:
1896 emitInsn(0x4c480000);
1897 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1898 break;
1899 case FILE_IMMEDIATE:
1900 emitInsn(0x38480000);
1901 emitIMMD(0x14, 19, insn->src(1));
1902 break;
1903 default:
1904 assert(!"bad src1 file");
1905 break;
1906 }
1907
1908 emitCC (0x2f);
1909 emitX (0x2b);
1910 emitField(0x27, 1, insn->subOp == NV50_IR_SUBOP_SHIFT_WRAP);
1911 emitGPR (0x08, insn->src(0));
1912 emitGPR (0x00, insn->def(0));
1913 }
1914
1915 void
1916 CodeEmitterGM107::emitSHR()
1917 {
1918 switch (insn->src(1).getFile()) {
1919 case FILE_GPR:
1920 emitInsn(0x5c280000);
1921 emitGPR (0x14, insn->src(1));
1922 break;
1923 case FILE_MEMORY_CONST:
1924 emitInsn(0x4c280000);
1925 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1926 break;
1927 case FILE_IMMEDIATE:
1928 emitInsn(0x38280000);
1929 emitIMMD(0x14, 19, insn->src(1));
1930 break;
1931 default:
1932 assert(!"bad src1 file");
1933 break;
1934 }
1935
1936 emitField(0x30, 1, isSignedType(insn->dType));
1937 emitCC (0x2f);
1938 emitX (0x2c);
1939 emitField(0x27, 1, insn->subOp == NV50_IR_SUBOP_SHIFT_WRAP);
1940 emitGPR (0x08, insn->src(0));
1941 emitGPR (0x00, insn->def(0));
1942 }
1943
1944 void
1945 CodeEmitterGM107::emitPOPC()
1946 {
1947 switch (insn->src(0).getFile()) {
1948 case FILE_GPR:
1949 emitInsn(0x5c080000);
1950 emitGPR (0x14, insn->src(0));
1951 break;
1952 case FILE_MEMORY_CONST:
1953 emitInsn(0x4c080000);
1954 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
1955 break;
1956 case FILE_IMMEDIATE:
1957 emitInsn(0x38080000);
1958 emitIMMD(0x14, 19, insn->src(0));
1959 break;
1960 default:
1961 assert(!"bad src1 file");
1962 break;
1963 }
1964
1965 emitINV(0x28, insn->src(0));
1966 emitGPR(0x00, insn->def(0));
1967 }
1968
1969 void
1970 CodeEmitterGM107::emitBFI()
1971 {
1972 switch(insn->src(2).getFile()) {
1973 case FILE_GPR:
1974 switch (insn->src(1).getFile()) {
1975 case FILE_GPR:
1976 emitInsn(0x5bf00000);
1977 emitGPR (0x14, insn->src(1));
1978 break;
1979 case FILE_MEMORY_CONST:
1980 emitInsn(0x4bf00000);
1981 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1982 break;
1983 case FILE_IMMEDIATE:
1984 emitInsn(0x36f00000);
1985 emitIMMD(0x14, 19, insn->src(1));
1986 break;
1987 default:
1988 assert(!"bad src1 file");
1989 break;
1990 }
1991 emitGPR (0x27, insn->src(2));
1992 break;
1993 case FILE_MEMORY_CONST:
1994 emitInsn(0x53f00000);
1995 emitGPR (0x27, insn->src(1));
1996 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(2));
1997 break;
1998 default:
1999 assert(!"bad src2 file");
2000 break;
2001 }
2002
2003 emitCC (0x2f);
2004 emitGPR (0x08, insn->src(0));
2005 emitGPR (0x00, insn->def(0));
2006 }
2007
2008 void
2009 CodeEmitterGM107::emitBFE()
2010 {
2011 switch (insn->src(1).getFile()) {
2012 case FILE_GPR:
2013 emitInsn(0x5c000000);
2014 emitGPR (0x14, insn->src(1));
2015 break;
2016 case FILE_MEMORY_CONST:
2017 emitInsn(0x4c000000);
2018 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
2019 break;
2020 case FILE_IMMEDIATE:
2021 emitInsn(0x38000000);
2022 emitIMMD(0x14, 19, insn->src(1));
2023 break;
2024 default:
2025 assert(!"bad src1 file");
2026 break;
2027 }
2028
2029 emitField(0x30, 1, isSignedType(insn->dType));
2030 emitCC (0x2f);
2031 emitField(0x28, 1, insn->subOp == NV50_IR_SUBOP_EXTBF_REV);
2032 emitGPR (0x08, insn->src(0));
2033 emitGPR (0x00, insn->def(0));
2034 }
2035
2036 void
2037 CodeEmitterGM107::emitFLO()
2038 {
2039 switch (insn->src(0).getFile()) {
2040 case FILE_GPR:
2041 emitInsn(0x5c300000);
2042 emitGPR (0x14, insn->src(0));
2043 break;
2044 case FILE_MEMORY_CONST:
2045 emitInsn(0x4c300000);
2046 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
2047 break;
2048 case FILE_IMMEDIATE:
2049 emitInsn(0x38300000);
2050 emitIMMD(0x14, 19, insn->src(0));
2051 break;
2052 default:
2053 assert(!"bad src1 file");
2054 break;
2055 }
2056
2057 emitField(0x30, 1, isSignedType(insn->dType));
2058 emitCC (0x2f);
2059 emitField(0x29, 1, insn->subOp == NV50_IR_SUBOP_BFIND_SAMT);
2060 emitINV (0x28, insn->src(0));
2061 emitGPR (0x00, insn->def(0));
2062 }
2063
2064 /*******************************************************************************
2065 * memory
2066 ******************************************************************************/
2067
2068 void
2069 CodeEmitterGM107::emitLDSTs(int pos, DataType type)
2070 {
2071 int data = 0;
2072
2073 switch (typeSizeof(type)) {
2074 case 1: data = isSignedType(type) ? 1 : 0; break;
2075 case 2: data = isSignedType(type) ? 3 : 2; break;
2076 case 4: data = 4; break;
2077 case 8: data = 5; break;
2078 case 16: data = 6; break;
2079 default:
2080 assert(!"bad type");
2081 break;
2082 }
2083
2084 emitField(pos, 3, data);
2085 }
2086
2087 void
2088 CodeEmitterGM107::emitLDSTc(int pos)
2089 {
2090 int mode = 0;
2091
2092 switch (insn->cache) {
2093 case CACHE_CA: mode = 0; break;
2094 case CACHE_CG: mode = 1; break;
2095 case CACHE_CS: mode = 2; break;
2096 case CACHE_CV: mode = 3; break;
2097 default:
2098 assert(!"invalid caching mode");
2099 break;
2100 }
2101
2102 emitField(pos, 2, mode);
2103 }
2104
2105 void
2106 CodeEmitterGM107::emitLDC()
2107 {
2108 emitInsn (0xef900000);
2109 emitLDSTs(0x30, insn->dType);
2110 emitField(0x2c, 2, insn->subOp);
2111 emitCBUF (0x24, 0x08, 0x14, 16, 0, insn->src(0));
2112 emitGPR (0x00, insn->def(0));
2113 }
2114
2115 void
2116 CodeEmitterGM107::emitLDL()
2117 {
2118 emitInsn (0xef400000);
2119 emitLDSTs(0x30, insn->dType);
2120 emitLDSTc(0x2c);
2121 emitADDR (0x08, 0x14, 24, 0, insn->src(0));
2122 emitGPR (0x00, insn->def(0));
2123 }
2124
2125 void
2126 CodeEmitterGM107::emitLDS()
2127 {
2128 emitInsn (0xef480000);
2129 emitLDSTs(0x30, insn->dType);
2130 emitADDR (0x08, 0x14, 24, 0, insn->src(0));
2131 emitGPR (0x00, insn->def(0));
2132 }
2133
2134 void
2135 CodeEmitterGM107::emitLD()
2136 {
2137 emitInsn (0x80000000);
2138 emitPRED (0x3a);
2139 emitLDSTc(0x38);
2140 emitLDSTs(0x35, insn->dType);
2141 emitADDR (0x08, 0x14, 32, 0, insn->src(0));
2142 emitGPR (0x00, insn->def(0));
2143 }
2144
2145 void
2146 CodeEmitterGM107::emitSTL()
2147 {
2148 emitInsn (0xef500000);
2149 emitLDSTs(0x30, insn->dType);
2150 emitLDSTc(0x2c);
2151 emitADDR (0x08, 0x14, 24, 0, insn->src(0));
2152 emitGPR (0x00, insn->src(1));
2153 }
2154
2155 void
2156 CodeEmitterGM107::emitSTS()
2157 {
2158 emitInsn (0xef580000);
2159 emitLDSTs(0x30, insn->dType);
2160 emitADDR (0x08, 0x14, 24, 0, insn->src(0));
2161 emitGPR (0x00, insn->src(1));
2162 }
2163
2164 void
2165 CodeEmitterGM107::emitST()
2166 {
2167 emitInsn (0xa0000000);
2168 emitPRED (0x3a);
2169 emitLDSTc(0x38);
2170 emitLDSTs(0x35, insn->dType);
2171 emitADDR (0x08, 0x14, 32, 0, insn->src(0));
2172 emitGPR (0x00, insn->src(1));
2173 }
2174
2175 void
2176 CodeEmitterGM107::emitALD()
2177 {
2178 emitInsn (0xefd80000);
2179 emitField(0x2f, 2, (insn->getDef(0)->reg.size / 4) - 1);
2180 emitGPR (0x27, insn->src(0).getIndirect(1));
2181 emitO (0x20);
2182 emitP (0x1f);
2183 emitADDR (0x08, 20, 10, 0, insn->src(0));
2184 emitGPR (0x00, insn->def(0));
2185 }
2186
2187 void
2188 CodeEmitterGM107::emitAST()
2189 {
2190 emitInsn (0xeff00000);
2191 emitField(0x2f, 2, (typeSizeof(insn->dType) / 4) - 1);
2192 emitGPR (0x27, insn->src(0).getIndirect(1));
2193 emitP (0x1f);
2194 emitADDR (0x08, 20, 10, 0, insn->src(0));
2195 emitGPR (0x00, insn->src(1));
2196 }
2197
2198 void
2199 CodeEmitterGM107::emitISBERD()
2200 {
2201 emitInsn(0xefd00000);
2202 emitGPR (0x08, insn->src(0));
2203 emitGPR (0x00, insn->def(0));
2204 }
2205
2206 void
2207 CodeEmitterGM107::emitIPA()
2208 {
2209 int ipam = 0, ipas = 0;
2210
2211 switch (insn->getInterpMode()) {
2212 case NV50_IR_INTERP_LINEAR : ipam = 0; break;
2213 case NV50_IR_INTERP_PERSPECTIVE: ipam = 1; break;
2214 case NV50_IR_INTERP_FLAT : ipam = 2; break;
2215 case NV50_IR_INTERP_SC : ipam = 3; break;
2216 default:
2217 assert(!"invalid ipa mode");
2218 break;
2219 }
2220
2221 switch (insn->getSampleMode()) {
2222 case NV50_IR_INTERP_DEFAULT : ipas = 0; break;
2223 case NV50_IR_INTERP_CENTROID: ipas = 1; break;
2224 case NV50_IR_INTERP_OFFSET : ipas = 2; break;
2225 default:
2226 assert(!"invalid ipa sample mode");
2227 break;
2228 }
2229
2230 emitInsn (0xe0000000);
2231 emitField(0x36, 2, ipam);
2232 emitField(0x34, 2, ipas);
2233 emitSAT (0x33);
2234 emitField(0x2f, 3, 7);
2235 emitADDR (0x08, 0x1c, 10, 0, insn->src(0));
2236 if ((code[0] & 0x0000ff00) != 0x0000ff00)
2237 code[1] |= 0x00000040; /* .idx */
2238 emitGPR(0x00, insn->def(0));
2239
2240 if (insn->op == OP_PINTERP) {
2241 emitGPR(0x14, insn->src(1));
2242 if (insn->getSampleMode() == NV50_IR_INTERP_OFFSET)
2243 emitGPR(0x27, insn->src(2));
2244 } else {
2245 if (insn->getSampleMode() == NV50_IR_INTERP_OFFSET)
2246 emitGPR(0x27, insn->src(1));
2247 emitGPR(0x14);
2248 }
2249
2250 if (insn->getSampleMode() != NV50_IR_INTERP_OFFSET)
2251 emitGPR(0x27);
2252 }
2253
2254 /*******************************************************************************
2255 * surface
2256 ******************************************************************************/
2257
2258 void
2259 CodeEmitterGM107::emitPIXLD()
2260 {
2261 emitInsn (0xefe80000);
2262 emitPRED (0x2d);
2263 emitField(0x1f, 3, insn->subOp);
2264 emitGPR (0x08, insn->src(0));
2265 emitGPR (0x00, insn->def(0));
2266 }
2267
2268 /*******************************************************************************
2269 * texture
2270 ******************************************************************************/
2271
2272 void
2273 CodeEmitterGM107::emitTEXs(int pos)
2274 {
2275 int src1 = insn->predSrc == 1 ? 2 : 1;
2276 if (insn->srcExists(src1))
2277 emitGPR(pos, insn->src(src1));
2278 else
2279 emitGPR(pos);
2280 }
2281
2282 void
2283 CodeEmitterGM107::emitTEX()
2284 {
2285 const TexInstruction *insn = this->insn->asTex();
2286 int lodm = 0;
2287
2288 if (!insn->tex.levelZero) {
2289 switch (insn->op) {
2290 case OP_TEX: lodm = 0; break;
2291 case OP_TXB: lodm = 2; break;
2292 case OP_TXL: lodm = 3; break;
2293 default:
2294 assert(!"invalid tex op");
2295 break;
2296 }
2297 } else {
2298 lodm = 1;
2299 }
2300
2301 if (insn->tex.rIndirectSrc >= 0) {
2302 emitInsn (0xdeb80000);
2303 emitField(0x35, 2, lodm);
2304 emitField(0x24, 1, insn->tex.useOffsets == 1);
2305 } else {
2306 emitInsn (0xc0380000);
2307 emitField(0x37, 2, lodm);
2308 emitField(0x36, 1, insn->tex.useOffsets == 1);
2309 emitField(0x24, 13, insn->tex.r);
2310 }
2311
2312 emitField(0x32, 1, insn->tex.target.isShadow());
2313 emitField(0x31, 1, insn->tex.liveOnly);
2314 emitField(0x23, 1, insn->tex.derivAll);
2315 emitField(0x1f, 4, insn->tex.mask);
2316 emitField(0x1d, 2, insn->tex.target.isCube() ? 3 :
2317 insn->tex.target.getDim() - 1);
2318 emitField(0x1c, 1, insn->tex.target.isArray());
2319 emitTEXs (0x14);
2320 emitGPR (0x08, insn->src(0));
2321 emitGPR (0x00, insn->def(0));
2322 }
2323
2324 void
2325 CodeEmitterGM107::emitTLD()
2326 {
2327 const TexInstruction *insn = this->insn->asTex();
2328
2329 if (insn->tex.rIndirectSrc >= 0) {
2330 emitInsn (0xdd380000);
2331 } else {
2332 emitInsn (0xdc380000);
2333 emitField(0x24, 13, insn->tex.r);
2334 }
2335
2336 emitField(0x37, 1, insn->tex.levelZero == 0);
2337 emitField(0x32, 1, insn->tex.target.isMS());
2338 emitField(0x31, 1, insn->tex.liveOnly);
2339 emitField(0x23, 1, insn->tex.useOffsets == 1);
2340 emitField(0x1f, 4, insn->tex.mask);
2341 emitField(0x1d, 2, insn->tex.target.isCube() ? 3 :
2342 insn->tex.target.getDim() - 1);
2343 emitField(0x1c, 1, insn->tex.target.isArray());
2344 emitTEXs (0x14);
2345 emitGPR (0x08, insn->src(0));
2346 emitGPR (0x00, insn->def(0));
2347 }
2348
2349 void
2350 CodeEmitterGM107::emitTLD4()
2351 {
2352 const TexInstruction *insn = this->insn->asTex();
2353
2354 if (insn->tex.rIndirectSrc >= 0) {
2355 emitInsn (0xdef80000);
2356 emitField(0x26, 2, insn->tex.gatherComp);
2357 emitField(0x25, 2, insn->tex.useOffsets == 4);
2358 emitField(0x24, 2, insn->tex.useOffsets == 1);
2359 } else {
2360 emitInsn (0xc8380000);
2361 emitField(0x38, 2, insn->tex.gatherComp);
2362 emitField(0x37, 2, insn->tex.useOffsets == 4);
2363 emitField(0x36, 2, insn->tex.useOffsets == 1);
2364 emitField(0x24, 13, insn->tex.r);
2365 }
2366
2367 emitField(0x32, 1, insn->tex.target.isShadow());
2368 emitField(0x31, 1, insn->tex.liveOnly);
2369 emitField(0x23, 1, insn->tex.derivAll);
2370 emitField(0x1f, 4, insn->tex.mask);
2371 emitField(0x1d, 2, insn->tex.target.isCube() ? 3 :
2372 insn->tex.target.getDim() - 1);
2373 emitField(0x1c, 1, insn->tex.target.isArray());
2374 emitTEXs (0x14);
2375 emitGPR (0x08, insn->src(0));
2376 emitGPR (0x00, insn->def(0));
2377 }
2378
2379 void
2380 CodeEmitterGM107::emitTXD()
2381 {
2382 const TexInstruction *insn = this->insn->asTex();
2383
2384 if (insn->tex.rIndirectSrc >= 0) {
2385 emitInsn (0xde780000);
2386 } else {
2387 emitInsn (0xde380000);
2388 emitField(0x24, 13, insn->tex.r);
2389 }
2390
2391 emitField(0x31, 1, insn->tex.liveOnly);
2392 emitField(0x23, 1, insn->tex.useOffsets == 1);
2393 emitField(0x1f, 4, insn->tex.mask);
2394 emitField(0x1d, 2, insn->tex.target.isCube() ? 3 :
2395 insn->tex.target.getDim() - 1);
2396 emitField(0x1c, 1, insn->tex.target.isArray());
2397 emitTEXs (0x14);
2398 emitGPR (0x08, insn->src(0));
2399 emitGPR (0x00, insn->def(0));
2400 }
2401
2402 void
2403 CodeEmitterGM107::emitTMML()
2404 {
2405 const TexInstruction *insn = this->insn->asTex();
2406
2407 if (insn->tex.rIndirectSrc >= 0) {
2408 emitInsn (0xdf600000);
2409 } else {
2410 emitInsn (0xdf580000);
2411 emitField(0x24, 13, insn->tex.r);
2412 }
2413
2414 emitField(0x31, 1, insn->tex.liveOnly);
2415 emitField(0x23, 1, insn->tex.derivAll);
2416 emitField(0x1f, 4, insn->tex.mask);
2417 emitField(0x1d, 2, insn->tex.target.isCube() ? 3 :
2418 insn->tex.target.getDim() - 1);
2419 emitField(0x1c, 1, insn->tex.target.isArray());
2420 emitTEXs (0x14);
2421 emitGPR (0x08, insn->src(0));
2422 emitGPR (0x00, insn->def(0));
2423 }
2424
2425 void
2426 CodeEmitterGM107::emitTXQ()
2427 {
2428 const TexInstruction *insn = this->insn->asTex();
2429 int type = 0;
2430
2431 switch (insn->tex.query) {
2432 case TXQ_DIMS : type = 0x01; break;
2433 case TXQ_TYPE : type = 0x02; break;
2434 case TXQ_SAMPLE_POSITION: type = 0x05; break;
2435 case TXQ_FILTER : type = 0x10; break;
2436 case TXQ_LOD : type = 0x12; break;
2437 case TXQ_WRAP : type = 0x14; break;
2438 case TXQ_BORDER_COLOUR : type = 0x16; break;
2439 default:
2440 assert(!"invalid txq query");
2441 break;
2442 }
2443
2444 if (insn->tex.rIndirectSrc >= 0) {
2445 emitInsn (0xdf500000);
2446 } else {
2447 emitInsn (0xdf480000);
2448 emitField(0x24, 13, insn->tex.r);
2449 }
2450
2451 emitField(0x31, 1, insn->tex.liveOnly);
2452 emitField(0x1f, 4, insn->tex.mask);
2453 emitField(0x16, 6, type);
2454 emitGPR (0x08, insn->src(0));
2455 emitGPR (0x00, insn->def(0));
2456 }
2457
2458 void
2459 CodeEmitterGM107::emitDEPBAR()
2460 {
2461 emitInsn (0xf0f00000);
2462 emitField(0x1d, 1, 1); /* le */
2463 emitField(0x1a, 3, 5);
2464 emitField(0x14, 6, insn->subOp);
2465 emitField(0x00, 6, insn->subOp);
2466 }
2467
2468 /*******************************************************************************
2469 * misc
2470 ******************************************************************************/
2471
2472 void
2473 CodeEmitterGM107::emitNOP()
2474 {
2475 emitInsn(0x50b00000);
2476 }
2477
2478 void
2479 CodeEmitterGM107::emitKIL()
2480 {
2481 emitInsn (0xe3300000);
2482 emitCond5(0x00, CC_TR);
2483 }
2484
2485 void
2486 CodeEmitterGM107::emitOUT()
2487 {
2488 const int cut = insn->op == OP_RESTART || insn->subOp;
2489 const int emit = insn->op == OP_EMIT;
2490
2491 switch (insn->src(1).getFile()) {
2492 case FILE_GPR:
2493 emitInsn(0xfbe00000);
2494 emitGPR (0x14, insn->src(1));
2495 break;
2496 case FILE_IMMEDIATE:
2497 emitInsn(0xf6e00000);
2498 emitIMMD(0x14, 19, insn->src(1));
2499 break;
2500 case FILE_MEMORY_CONST:
2501 emitInsn(0xebe00000);
2502 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
2503 break;
2504 default:
2505 assert(!"bad src1 file");
2506 break;
2507 }
2508
2509 emitField(0x27, 2, (cut << 1) | emit);
2510 emitGPR (0x08, insn->src(0));
2511 emitGPR (0x00, insn->def(0));
2512 }
2513
2514 /*******************************************************************************
2515 * assembler front-end
2516 ******************************************************************************/
2517
2518 bool
2519 CodeEmitterGM107::emitInstruction(Instruction *i)
2520 {
2521 const unsigned int size = (writeIssueDelays && !(codeSize & 0x1f)) ? 16 : 8;
2522 bool ret = true;
2523
2524 insn = i;
2525
2526 if (insn->encSize != 8) {
2527 ERROR("skipping undecodable instruction: "); insn->print();
2528 return false;
2529 } else
2530 if (codeSize + size > codeSizeLimit) {
2531 ERROR("code emitter output buffer too small\n");
2532 return false;
2533 }
2534
2535 if (writeIssueDelays) {
2536 int n = ((codeSize & 0x1f) / 8) - 1;
2537 if (n < 0) {
2538 data = code;
2539 data[0] = 0x00000000;
2540 data[1] = 0x00000000;
2541 code += 2;
2542 codeSize += 8;
2543 n++;
2544 }
2545
2546 emitField(data, n * 21, 21, insn->sched);
2547 }
2548
2549 switch (insn->op) {
2550 case OP_EXIT:
2551 emitEXIT();
2552 break;
2553 case OP_BRA:
2554 emitBRA();
2555 break;
2556 case OP_CALL:
2557 emitCAL();
2558 break;
2559 case OP_PRECONT:
2560 emitPCNT();
2561 break;
2562 case OP_CONT:
2563 emitCONT();
2564 break;
2565 case OP_PREBREAK:
2566 emitPBK();
2567 break;
2568 case OP_BREAK:
2569 emitBRK();
2570 break;
2571 case OP_PRERET:
2572 emitPRET();
2573 break;
2574 case OP_RET:
2575 emitRET();
2576 break;
2577 case OP_JOINAT:
2578 emitSSY();
2579 break;
2580 case OP_JOIN:
2581 emitSYNC();
2582 break;
2583 case OP_QUADON:
2584 emitSAM();
2585 break;
2586 case OP_QUADPOP:
2587 emitRAM();
2588 break;
2589 case OP_MOV:
2590 if (insn->def(0).getFile() == FILE_GPR &&
2591 insn->src(0).getFile() != FILE_PREDICATE)
2592 emitMOV();
2593 else
2594 assert(!"R2P/P2R");
2595 break;
2596 case OP_RDSV:
2597 emitS2R();
2598 break;
2599 case OP_ABS:
2600 case OP_NEG:
2601 case OP_SAT:
2602 case OP_FLOOR:
2603 case OP_CEIL:
2604 case OP_TRUNC:
2605 case OP_CVT:
2606 if (isFloatType(insn->dType)) {
2607 if (isFloatType(insn->sType))
2608 emitF2F();
2609 else
2610 emitI2F();
2611 } else {
2612 if (isFloatType(insn->sType))
2613 emitF2I();
2614 else
2615 emitI2I();
2616 }
2617 break;
2618 case OP_SHFL:
2619 emitSHFL();
2620 break;
2621 case OP_ADD:
2622 case OP_SUB:
2623 if (isFloatType(insn->dType)) {
2624 if (insn->dType == TYPE_F64)
2625 emitDADD();
2626 else
2627 emitFADD();
2628 } else {
2629 emitIADD();
2630 }
2631 break;
2632 case OP_MUL:
2633 if (isFloatType(insn->dType)) {
2634 if (insn->dType == TYPE_F64)
2635 emitDMUL();
2636 else
2637 emitFMUL();
2638 } else {
2639 emitIMUL();
2640 }
2641 break;
2642 case OP_MAD:
2643 case OP_FMA:
2644 if (isFloatType(insn->dType)) {
2645 if (insn->dType == TYPE_F64)
2646 emitDFMA();
2647 else
2648 emitFFMA();
2649 } else {
2650 emitIMAD();
2651 }
2652 break;
2653 case OP_MIN:
2654 case OP_MAX:
2655 if (isFloatType(insn->dType)) {
2656 if (insn->dType == TYPE_F64)
2657 emitDMNMX();
2658 else
2659 emitFMNMX();
2660 } else {
2661 emitIMNMX();
2662 }
2663 break;
2664 case OP_SHL:
2665 emitSHL();
2666 break;
2667 case OP_SHR:
2668 emitSHR();
2669 break;
2670 case OP_POPCNT:
2671 emitPOPC();
2672 break;
2673 case OP_INSBF:
2674 emitBFI();
2675 break;
2676 case OP_EXTBF:
2677 emitBFE();
2678 break;
2679 case OP_BFIND:
2680 emitFLO();
2681 break;
2682 case OP_SLCT:
2683 if (isFloatType(insn->dType))
2684 emitFCMP();
2685 else
2686 emitICMP();
2687 break;
2688 case OP_SET:
2689 case OP_SET_AND:
2690 case OP_SET_OR:
2691 case OP_SET_XOR:
2692 if (insn->def(0).getFile() != FILE_PREDICATE) {
2693 if (isFloatType(insn->sType))
2694 if (insn->sType == TYPE_F64)
2695 emitDSET();
2696 else
2697 emitFSET();
2698 else
2699 emitISET();
2700 } else {
2701 if (isFloatType(insn->sType))
2702 if (insn->sType == TYPE_F64)
2703 emitDSETP();
2704 else
2705 emitFSETP();
2706 else
2707 emitISETP();
2708 }
2709 break;
2710 case OP_PRESIN:
2711 case OP_PREEX2:
2712 emitRRO();
2713 break;
2714 case OP_COS:
2715 case OP_SIN:
2716 case OP_EX2:
2717 case OP_LG2:
2718 case OP_RCP:
2719 case OP_RSQ:
2720 emitMUFU();
2721 break;
2722 case OP_AND:
2723 case OP_OR:
2724 case OP_XOR:
2725 emitLOP();
2726 break;
2727 case OP_NOT:
2728 emitNOT();
2729 break;
2730 case OP_LOAD:
2731 switch (insn->src(0).getFile()) {
2732 case FILE_MEMORY_CONST : emitLDC(); break;
2733 case FILE_MEMORY_LOCAL : emitLDL(); break;
2734 case FILE_MEMORY_SHARED: emitLDS(); break;
2735 case FILE_MEMORY_GLOBAL: emitLD(); break;
2736 default:
2737 assert(!"invalid load");
2738 emitNOP();
2739 break;
2740 }
2741 break;
2742 case OP_STORE:
2743 switch (insn->src(0).getFile()) {
2744 case FILE_MEMORY_LOCAL : emitSTL(); break;
2745 case FILE_MEMORY_SHARED: emitSTS(); break;
2746 case FILE_MEMORY_GLOBAL: emitST(); break;
2747 default:
2748 assert(!"invalid load");
2749 emitNOP();
2750 break;
2751 }
2752 break;
2753 case OP_VFETCH:
2754 emitALD();
2755 break;
2756 case OP_EXPORT:
2757 emitAST();
2758 break;
2759 case OP_PFETCH:
2760 emitISBERD();
2761 break;
2762 case OP_LINTERP:
2763 case OP_PINTERP:
2764 emitIPA();
2765 break;
2766 case OP_PIXLD:
2767 emitPIXLD();
2768 break;
2769 case OP_TEX:
2770 case OP_TXB:
2771 case OP_TXL:
2772 emitTEX();
2773 break;
2774 case OP_TXF:
2775 emitTLD();
2776 break;
2777 case OP_TXG:
2778 emitTLD4();
2779 break;
2780 case OP_TXD:
2781 emitTXD();
2782 break;
2783 case OP_TXQ:
2784 emitTXQ();
2785 break;
2786 case OP_TXLQ:
2787 emitTMML();
2788 break;
2789 case OP_TEXBAR:
2790 emitDEPBAR();
2791 break;
2792 case OP_QUADOP:
2793 emitFSWZADD();
2794 break;
2795 case OP_NOP:
2796 emitNOP();
2797 break;
2798 case OP_DISCARD:
2799 emitKIL();
2800 break;
2801 case OP_EMIT:
2802 case OP_RESTART:
2803 emitOUT();
2804 break;
2805 default:
2806 assert(!"invalid opcode");
2807 emitNOP();
2808 ret = false;
2809 break;
2810 }
2811
2812 if (insn->join) {
2813 /*XXX*/
2814 }
2815
2816 code += 2;
2817 codeSize += 8;
2818 return ret;
2819 }
2820
2821 uint32_t
2822 CodeEmitterGM107::getMinEncodingSize(const Instruction *i) const
2823 {
2824 return 8;
2825 }
2826
2827 /*******************************************************************************
2828 * sched data calculator
2829 ******************************************************************************/
2830
2831 class SchedDataCalculatorGM107 : public Pass
2832 {
2833 public:
2834 SchedDataCalculatorGM107(const Target *targ) : targ(targ) {}
2835 private:
2836 const Target *targ;
2837 bool visit(BasicBlock *bb);
2838 };
2839
2840 bool
2841 SchedDataCalculatorGM107::visit(BasicBlock *bb)
2842 {
2843 for (Instruction *insn = bb->getEntry(); insn; insn = insn->next) {
2844 /*XXX*/
2845 insn->sched = 0x7e0;
2846 }
2847
2848 return true;
2849 }
2850
2851 /*******************************************************************************
2852 * main
2853 ******************************************************************************/
2854
2855 void
2856 CodeEmitterGM107::prepareEmission(Function *func)
2857 {
2858 SchedDataCalculatorGM107 sched(targ);
2859 CodeEmitter::prepareEmission(func);
2860 sched.run(func, true, true);
2861 }
2862
2863 static inline uint32_t sizeToBundlesGM107(uint32_t size)
2864 {
2865 return (size + 23) / 24;
2866 }
2867
2868 void
2869 CodeEmitterGM107::prepareEmission(Program *prog)
2870 {
2871 for (ArrayList::Iterator fi = prog->allFuncs.iterator();
2872 !fi.end(); fi.next()) {
2873 Function *func = reinterpret_cast<Function *>(fi.get());
2874 func->binPos = prog->binSize;
2875 prepareEmission(func);
2876
2877 // adjust sizes & positions for schedulding info:
2878 if (prog->getTarget()->hasSWSched) {
2879 uint32_t adjPos = func->binPos;
2880 BasicBlock *bb = NULL;
2881 for (int i = 0; i < func->bbCount; ++i) {
2882 bb = func->bbArray[i];
2883 int32_t adjSize = bb->binSize;
2884 if (adjPos % 32) {
2885 adjSize -= 32 - adjPos % 32;
2886 if (adjSize < 0)
2887 adjSize = 0;
2888 }
2889 adjSize = bb->binSize + sizeToBundlesGM107(adjSize) * 8;
2890 bb->binPos = adjPos;
2891 bb->binSize = adjSize;
2892 adjPos += adjSize;
2893 }
2894 if (bb)
2895 func->binSize = adjPos - func->binPos;
2896 }
2897
2898 prog->binSize += func->binSize;
2899 }
2900 }
2901
2902 CodeEmitterGM107::CodeEmitterGM107(const TargetGM107 *target)
2903 : CodeEmitter(target),
2904 targGM107(target),
2905 writeIssueDelays(target->hasSWSched)
2906 {
2907 code = NULL;
2908 codeSize = codeSizeLimit = 0;
2909 relocInfo = NULL;
2910 }
2911
2912 CodeEmitter *
2913 TargetGM107::createCodeEmitterGM107(Program::Type type)
2914 {
2915 CodeEmitterGM107 *emit = new CodeEmitterGM107(this);
2916 emit->setProgramType(type);
2917 return emit;
2918 }
2919
2920 } // namespace nv50_ir