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