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