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