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