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