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