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