nvc0: add support for VOTE tgsi opcodes
[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->defExists(1));
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 (insn->sType != TYPE_F32 && !longIMMD(insn->src(0)))) {
683 switch (insn->src(0).getFile()) {
684 case FILE_GPR:
685 if (insn->def(0).getFile() == FILE_PREDICATE) {
686 emitInsn(0x5b6a0000);
687 emitGPR (0x08);
688 } else {
689 emitInsn(0x5c980000);
690 }
691 emitGPR (0x14, insn->src(0));
692 break;
693 case FILE_MEMORY_CONST:
694 emitInsn(0x4c980000);
695 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
696 break;
697 case FILE_IMMEDIATE:
698 emitInsn(0x38980000);
699 emitIMMD(0x14, 19, insn->src(0));
700 break;
701 case FILE_PREDICATE:
702 emitInsn(0x50880000);
703 emitPRED(0x0c, insn->src(0));
704 emitPRED(0x1d);
705 emitPRED(0x27);
706 break;
707 default:
708 assert(!"bad src file");
709 break;
710 }
711 if (insn->def(0).getFile() != FILE_PREDICATE &&
712 insn->src(0).getFile() != FILE_PREDICATE)
713 emitField(0x27, 4, insn->lanes);
714 } else {
715 emitInsn (0x01000000);
716 emitIMMD (0x14, 32, insn->src(0));
717 emitField(0x0c, 4, insn->lanes);
718 }
719
720 if (insn->def(0).getFile() == FILE_PREDICATE) {
721 emitPRED(0x27);
722 emitPRED(0x03, insn->def(0));
723 emitPRED(0x00);
724 } else {
725 emitGPR(0x00, insn->def(0));
726 }
727 }
728
729 void
730 CodeEmitterGM107::emitS2R()
731 {
732 emitInsn(0xf0c80000);
733 emitSYS (0x14, insn->src(0));
734 emitGPR (0x00, insn->def(0));
735 }
736
737 void
738 CodeEmitterGM107::emitF2F()
739 {
740 RoundMode rnd = insn->rnd;
741
742 switch (insn->op) {
743 case OP_FLOOR: rnd = ROUND_MI; break;
744 case OP_CEIL : rnd = ROUND_PI; break;
745 case OP_TRUNC: rnd = ROUND_ZI; break;
746 default:
747 break;
748 }
749
750 switch (insn->src(0).getFile()) {
751 case FILE_GPR:
752 emitInsn(0x5ca80000);
753 emitGPR (0x14, insn->src(0));
754 break;
755 case FILE_MEMORY_CONST:
756 emitInsn(0x4ca80000);
757 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
758 break;
759 case FILE_IMMEDIATE:
760 emitInsn(0x38a80000);
761 emitIMMD(0x14, 19, insn->src(0));
762 break;
763 default:
764 assert(!"bad src0 file");
765 break;
766 }
767
768 emitField(0x32, 1, (insn->op == OP_SAT) || insn->saturate);
769 emitField(0x31, 1, (insn->op == OP_ABS) || insn->src(0).mod.abs());
770 emitCC (0x2f);
771 emitField(0x2d, 1, (insn->op == OP_NEG) || insn->src(0).mod.neg());
772 emitFMZ (0x2c, 1);
773 emitField(0x29, 1, insn->subOp);
774 emitRND (0x27, rnd, 0x2a);
775 emitField(0x0a, 2, util_logbase2(typeSizeof(insn->sType)));
776 emitField(0x08, 2, util_logbase2(typeSizeof(insn->dType)));
777 emitGPR (0x00, insn->def(0));
778 }
779
780 void
781 CodeEmitterGM107::emitF2I()
782 {
783 RoundMode rnd = insn->rnd;
784
785 switch (insn->op) {
786 case OP_FLOOR: rnd = ROUND_M; break;
787 case OP_CEIL : rnd = ROUND_P; break;
788 case OP_TRUNC: rnd = ROUND_Z; break;
789 default:
790 break;
791 }
792
793 switch (insn->src(0).getFile()) {
794 case FILE_GPR:
795 emitInsn(0x5cb00000);
796 emitGPR (0x14, insn->src(0));
797 break;
798 case FILE_MEMORY_CONST:
799 emitInsn(0x4cb00000);
800 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
801 break;
802 case FILE_IMMEDIATE:
803 emitInsn(0x38b00000);
804 emitIMMD(0x14, 19, insn->src(0));
805 break;
806 default:
807 assert(!"bad src0 file");
808 break;
809 }
810
811 emitField(0x31, 1, (insn->op == OP_ABS) || insn->src(0).mod.abs());
812 emitCC (0x2f);
813 emitField(0x2d, 1, (insn->op == OP_NEG) || insn->src(0).mod.neg());
814 emitFMZ (0x2c, 1);
815 emitRND (0x27, rnd, 0x2a);
816 emitField(0x0c, 1, isSignedType(insn->dType));
817 emitField(0x0a, 2, util_logbase2(typeSizeof(insn->sType)));
818 emitField(0x08, 2, util_logbase2(typeSizeof(insn->dType)));
819 emitGPR (0x00, insn->def(0));
820 }
821
822 void
823 CodeEmitterGM107::emitI2F()
824 {
825 RoundMode rnd = insn->rnd;
826
827 switch (insn->op) {
828 case OP_FLOOR: rnd = ROUND_M; break;
829 case OP_CEIL : rnd = ROUND_P; break;
830 case OP_TRUNC: rnd = ROUND_Z; break;
831 default:
832 break;
833 }
834
835 switch (insn->src(0).getFile()) {
836 case FILE_GPR:
837 emitInsn(0x5cb80000);
838 emitGPR (0x14, insn->src(0));
839 break;
840 case FILE_MEMORY_CONST:
841 emitInsn(0x4cb80000);
842 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
843 break;
844 case FILE_IMMEDIATE:
845 emitInsn(0x38b80000);
846 emitIMMD(0x14, 19, insn->src(0));
847 break;
848 default:
849 assert(!"bad src0 file");
850 break;
851 }
852
853 emitField(0x31, 1, (insn->op == OP_ABS) || insn->src(0).mod.abs());
854 emitCC (0x2f);
855 emitField(0x2d, 1, (insn->op == OP_NEG) || insn->src(0).mod.neg());
856 emitField(0x29, 2, insn->subOp);
857 emitRND (0x27, rnd, -1);
858 emitField(0x0d, 1, isSignedType(insn->sType));
859 emitField(0x0a, 2, util_logbase2(typeSizeof(insn->sType)));
860 emitField(0x08, 2, util_logbase2(typeSizeof(insn->dType)));
861 emitGPR (0x00, insn->def(0));
862 }
863
864 void
865 CodeEmitterGM107::emitI2I()
866 {
867 switch (insn->src(0).getFile()) {
868 case FILE_GPR:
869 emitInsn(0x5ce00000);
870 emitGPR (0x14, insn->src(0));
871 break;
872 case FILE_MEMORY_CONST:
873 emitInsn(0x4ce00000);
874 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
875 break;
876 case FILE_IMMEDIATE:
877 emitInsn(0x38e00000);
878 emitIMMD(0x14, 19, insn->src(0));
879 break;
880 default:
881 assert(!"bad src0 file");
882 break;
883 }
884
885 emitSAT (0x32);
886 emitField(0x31, 1, (insn->op == OP_ABS) || insn->src(0).mod.abs());
887 emitCC (0x2f);
888 emitField(0x2d, 1, (insn->op == OP_NEG) || insn->src(0).mod.neg());
889 emitField(0x29, 2, insn->subOp);
890 emitField(0x0d, 1, isSignedType(insn->sType));
891 emitField(0x0c, 1, isSignedType(insn->dType));
892 emitField(0x0a, 2, util_logbase2(typeSizeof(insn->sType)));
893 emitField(0x08, 2, util_logbase2(typeSizeof(insn->dType)));
894 emitGPR (0x00, insn->def(0));
895 }
896
897 static void
898 selpFlip(const FixupEntry *entry, uint32_t *code, const FixupData& data)
899 {
900 int loc = entry->loc;
901 if (data.force_persample_interp)
902 code[loc + 1] |= 1 << 10;
903 else
904 code[loc + 1] &= ~(1 << 10);
905 }
906
907 void
908 CodeEmitterGM107::emitSEL()
909 {
910 switch (insn->src(1).getFile()) {
911 case FILE_GPR:
912 emitInsn(0x5ca00000);
913 emitGPR (0x14, insn->src(1));
914 break;
915 case FILE_MEMORY_CONST:
916 emitInsn(0x4ca00000);
917 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
918 break;
919 case FILE_IMMEDIATE:
920 emitInsn(0x38a00000);
921 emitIMMD(0x14, 19, insn->src(1));
922 break;
923 default:
924 assert(!"bad src1 file");
925 break;
926 }
927
928 emitINV (0x2a, insn->src(2));
929 emitPRED(0x27, insn->src(2));
930 emitGPR (0x08, insn->src(0));
931 emitGPR (0x00, insn->def(0));
932
933 if (insn->subOp == 1) {
934 addInterp(0, 0, selpFlip);
935 }
936 }
937
938 void
939 CodeEmitterGM107::emitSHFL()
940 {
941 int type = 0;
942
943 emitInsn (0xef100000);
944
945 switch (insn->src(1).getFile()) {
946 case FILE_GPR:
947 emitGPR(0x14, insn->src(1));
948 break;
949 case FILE_IMMEDIATE:
950 emitIMMD(0x14, 5, insn->src(1));
951 type |= 1;
952 break;
953 default:
954 assert(!"invalid src1 file");
955 break;
956 }
957
958 /*XXX: what is this arg? hardcode immediate for now */
959 emitField(0x22, 13, 0x1c03);
960 type |= 2;
961
962 emitPRED (0x30);
963 emitField(0x1e, 2, insn->subOp);
964 emitField(0x1c, 2, type);
965 emitGPR (0x08, insn->src(0));
966 emitGPR (0x00, insn->def(0));
967 }
968
969 /*******************************************************************************
970 * double
971 ******************************************************************************/
972
973 void
974 CodeEmitterGM107::emitDADD()
975 {
976 switch (insn->src(1).getFile()) {
977 case FILE_GPR:
978 emitInsn(0x5c700000);
979 emitGPR (0x14, insn->src(1));
980 break;
981 case FILE_MEMORY_CONST:
982 emitInsn(0x4c700000);
983 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
984 break;
985 case FILE_IMMEDIATE:
986 emitInsn(0x38700000);
987 emitIMMD(0x14, 19, insn->src(1));
988 break;
989 default:
990 assert(!"bad src1 file");
991 break;
992 }
993 emitABS(0x31, insn->src(1));
994 emitNEG(0x30, insn->src(0));
995 emitCC (0x2f);
996 emitABS(0x2e, insn->src(0));
997 emitNEG(0x2d, insn->src(1));
998
999 if (insn->op == OP_SUB)
1000 code[1] ^= 0x00002000;
1001
1002 emitGPR(0x08, insn->src(0));
1003 emitGPR(0x00, insn->def(0));
1004 }
1005
1006 void
1007 CodeEmitterGM107::emitDMUL()
1008 {
1009 switch (insn->src(1).getFile()) {
1010 case FILE_GPR:
1011 emitInsn(0x5c800000);
1012 emitGPR (0x14, insn->src(1));
1013 break;
1014 case FILE_MEMORY_CONST:
1015 emitInsn(0x4c800000);
1016 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1017 break;
1018 case FILE_IMMEDIATE:
1019 emitInsn(0x38800000);
1020 emitIMMD(0x14, 19, insn->src(1));
1021 break;
1022 default:
1023 assert(!"bad src1 file");
1024 break;
1025 }
1026
1027 emitNEG2(0x30, insn->src(0), insn->src(1));
1028 emitCC (0x2f);
1029 emitRND (0x27);
1030 emitGPR (0x08, insn->src(0));
1031 emitGPR (0x00, insn->def(0));
1032 }
1033
1034 void
1035 CodeEmitterGM107::emitDFMA()
1036 {
1037 switch(insn->src(2).getFile()) {
1038 case FILE_GPR:
1039 switch (insn->src(1).getFile()) {
1040 case FILE_GPR:
1041 emitInsn(0x5b700000);
1042 emitGPR (0x14, insn->src(1));
1043 break;
1044 case FILE_MEMORY_CONST:
1045 emitInsn(0x4b700000);
1046 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1047 break;
1048 case FILE_IMMEDIATE:
1049 emitInsn(0x36700000);
1050 emitIMMD(0x14, 19, insn->src(1));
1051 break;
1052 default:
1053 assert(!"bad src1 file");
1054 break;
1055 }
1056 emitGPR (0x27, insn->src(2));
1057 break;
1058 case FILE_MEMORY_CONST:
1059 emitInsn(0x53700000);
1060 emitGPR (0x27, insn->src(1));
1061 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(2));
1062 break;
1063 default:
1064 assert(!"bad src2 file");
1065 break;
1066 }
1067
1068 emitRND (0x32);
1069 emitNEG (0x31, insn->src(2));
1070 emitNEG2(0x30, insn->src(0), insn->src(1));
1071 emitCC (0x2f);
1072 emitGPR (0x08, insn->src(0));
1073 emitGPR (0x00, insn->def(0));
1074 }
1075
1076 void
1077 CodeEmitterGM107::emitDMNMX()
1078 {
1079 switch (insn->src(1).getFile()) {
1080 case FILE_GPR:
1081 emitInsn(0x5c500000);
1082 emitGPR (0x14, insn->src(1));
1083 break;
1084 case FILE_MEMORY_CONST:
1085 emitInsn(0x4c500000);
1086 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1087 break;
1088 case FILE_IMMEDIATE:
1089 emitInsn(0x38500000);
1090 emitIMMD(0x14, 19, insn->src(1));
1091 break;
1092 default:
1093 assert(!"bad src1 file");
1094 break;
1095 }
1096
1097 emitABS (0x31, insn->src(1));
1098 emitNEG (0x30, insn->src(0));
1099 emitCC (0x2f);
1100 emitABS (0x2e, insn->src(0));
1101 emitNEG (0x2d, insn->src(1));
1102 emitField(0x2a, 1, insn->op == OP_MAX);
1103 emitPRED (0x27);
1104 emitGPR (0x08, insn->src(0));
1105 emitGPR (0x00, insn->def(0));
1106 }
1107
1108 void
1109 CodeEmitterGM107::emitDSET()
1110 {
1111 const CmpInstruction *insn = this->insn->asCmp();
1112
1113 switch (insn->src(1).getFile()) {
1114 case FILE_GPR:
1115 emitInsn(0x59000000);
1116 emitGPR (0x14, insn->src(1));
1117 break;
1118 case FILE_MEMORY_CONST:
1119 emitInsn(0x49000000);
1120 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1121 break;
1122 case FILE_IMMEDIATE:
1123 emitInsn(0x32000000);
1124 emitIMMD(0x14, 19, insn->src(1));
1125 break;
1126 default:
1127 assert(!"bad src1 file");
1128 break;
1129 }
1130
1131 if (insn->op != OP_SET) {
1132 switch (insn->op) {
1133 case OP_SET_AND: emitField(0x2d, 2, 0); break;
1134 case OP_SET_OR : emitField(0x2d, 2, 1); break;
1135 case OP_SET_XOR: emitField(0x2d, 2, 2); break;
1136 default:
1137 assert(!"invalid set op");
1138 break;
1139 }
1140 emitPRED(0x27, insn->src(2));
1141 } else {
1142 emitPRED(0x27);
1143 }
1144
1145 emitABS (0x36, insn->src(0));
1146 emitNEG (0x35, insn->src(1));
1147 emitField(0x34, 1, insn->dType == TYPE_F32);
1148 emitCond4(0x30, insn->setCond);
1149 emitCC (0x2f);
1150 emitABS (0x2c, insn->src(1));
1151 emitNEG (0x2b, insn->src(0));
1152 emitGPR (0x08, insn->src(0));
1153 emitGPR (0x00, insn->def(0));
1154 }
1155
1156 void
1157 CodeEmitterGM107::emitDSETP()
1158 {
1159 const CmpInstruction *insn = this->insn->asCmp();
1160
1161 switch (insn->src(1).getFile()) {
1162 case FILE_GPR:
1163 emitInsn(0x5b800000);
1164 emitGPR (0x14, insn->src(1));
1165 break;
1166 case FILE_MEMORY_CONST:
1167 emitInsn(0x4b800000);
1168 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1169 break;
1170 case FILE_IMMEDIATE:
1171 emitInsn(0x36800000);
1172 emitIMMD(0x14, 19, insn->src(1));
1173 break;
1174 default:
1175 assert(!"bad src1 file");
1176 break;
1177 }
1178
1179 if (insn->op != OP_SET) {
1180 switch (insn->op) {
1181 case OP_SET_AND: emitField(0x2d, 2, 0); break;
1182 case OP_SET_OR : emitField(0x2d, 2, 1); break;
1183 case OP_SET_XOR: emitField(0x2d, 2, 2); break;
1184 default:
1185 assert(!"invalid set op");
1186 break;
1187 }
1188 emitPRED(0x27, insn->src(2));
1189 } else {
1190 emitPRED(0x27);
1191 }
1192
1193 emitCond4(0x30, insn->setCond);
1194 emitABS (0x2c, insn->src(1));
1195 emitNEG (0x2b, insn->src(0));
1196 emitGPR (0x08, insn->src(0));
1197 emitABS (0x07, insn->src(0));
1198 emitNEG (0x06, insn->src(1));
1199 emitPRED (0x03, insn->def(0));
1200 if (insn->defExists(1))
1201 emitPRED(0x00, insn->def(1));
1202 else
1203 emitPRED(0x00);
1204 }
1205
1206 /*******************************************************************************
1207 * float
1208 ******************************************************************************/
1209
1210 void
1211 CodeEmitterGM107::emitFADD()
1212 {
1213 if (!longIMMD(insn->src(1))) {
1214 switch (insn->src(1).getFile()) {
1215 case FILE_GPR:
1216 emitInsn(0x5c580000);
1217 emitGPR (0x14, insn->src(1));
1218 break;
1219 case FILE_MEMORY_CONST:
1220 emitInsn(0x4c580000);
1221 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1222 break;
1223 case FILE_IMMEDIATE:
1224 emitInsn(0x38580000);
1225 emitIMMD(0x14, 19, insn->src(1));
1226 break;
1227 default:
1228 assert(!"bad src1 file");
1229 break;
1230 }
1231 emitSAT(0x32);
1232 emitABS(0x31, insn->src(1));
1233 emitNEG(0x30, insn->src(0));
1234 emitCC (0x2f);
1235 emitABS(0x2e, insn->src(0));
1236 emitNEG(0x2d, insn->src(1));
1237 emitFMZ(0x2c, 1);
1238 } else {
1239 emitInsn(0x08000000);
1240 emitABS(0x39, insn->src(1));
1241 emitNEG(0x38, insn->src(0));
1242 emitFMZ(0x37, 1);
1243 emitABS(0x36, insn->src(0));
1244 emitNEG(0x35, insn->src(1));
1245 emitCC (0x34);
1246 emitIMMD(0x14, 32, insn->src(1));
1247 }
1248
1249 if (insn->op == OP_SUB)
1250 code[1] ^= 0x00002000;
1251
1252 emitGPR(0x08, insn->src(0));
1253 emitGPR(0x00, insn->def(0));
1254 }
1255
1256 void
1257 CodeEmitterGM107::emitFMUL()
1258 {
1259 if (!longIMMD(insn->src(1))) {
1260 switch (insn->src(1).getFile()) {
1261 case FILE_GPR:
1262 emitInsn(0x5c680000);
1263 emitGPR (0x14, insn->src(1));
1264 break;
1265 case FILE_MEMORY_CONST:
1266 emitInsn(0x4c680000);
1267 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1268 break;
1269 case FILE_IMMEDIATE:
1270 emitInsn(0x38680000);
1271 emitIMMD(0x14, 19, insn->src(1));
1272 break;
1273 default:
1274 assert(!"bad src1 file");
1275 break;
1276 }
1277 emitSAT (0x32);
1278 emitNEG2(0x30, insn->src(0), insn->src(1));
1279 emitCC (0x2f);
1280 emitFMZ (0x2c, 2);
1281 emitPDIV(0x29);
1282 emitRND (0x27);
1283 } else {
1284 emitInsn(0x1e000000);
1285 emitSAT (0x37);
1286 emitFMZ (0x35, 2);
1287 emitCC (0x34);
1288 emitIMMD(0x14, 32, insn->src(1));
1289 if (insn->src(0).mod.neg() ^ insn->src(1).mod.neg())
1290 code[1] ^= 0x00080000; /* flip immd sign bit */
1291 }
1292
1293 emitGPR(0x08, insn->src(0));
1294 emitGPR(0x00, insn->def(0));
1295 }
1296
1297 void
1298 CodeEmitterGM107::emitFFMA()
1299 {
1300 /*XXX: ffma32i exists, but not using it as third src overlaps dst */
1301 switch(insn->src(2).getFile()) {
1302 case FILE_GPR:
1303 switch (insn->src(1).getFile()) {
1304 case FILE_GPR:
1305 emitInsn(0x59800000);
1306 emitGPR (0x14, insn->src(1));
1307 break;
1308 case FILE_MEMORY_CONST:
1309 emitInsn(0x49800000);
1310 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1311 break;
1312 case FILE_IMMEDIATE:
1313 emitInsn(0x32800000);
1314 emitIMMD(0x14, 19, insn->src(1));
1315 break;
1316 default:
1317 assert(!"bad src1 file");
1318 break;
1319 }
1320 emitGPR (0x27, insn->src(2));
1321 break;
1322 case FILE_MEMORY_CONST:
1323 emitInsn(0x51800000);
1324 emitGPR (0x27, insn->src(1));
1325 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(2));
1326 break;
1327 default:
1328 assert(!"bad src2 file");
1329 break;
1330 }
1331 emitRND (0x33);
1332 emitSAT (0x32);
1333 emitNEG (0x31, insn->src(2));
1334 emitNEG2(0x30, insn->src(0), insn->src(1));
1335 emitCC (0x2f);
1336
1337 emitFMZ(0x35, 2);
1338 emitGPR(0x08, insn->src(0));
1339 emitGPR(0x00, insn->def(0));
1340 }
1341
1342 void
1343 CodeEmitterGM107::emitMUFU()
1344 {
1345 int mufu = 0;
1346
1347 switch (insn->op) {
1348 case OP_COS: mufu = 0; break;
1349 case OP_SIN: mufu = 1; break;
1350 case OP_EX2: mufu = 2; break;
1351 case OP_LG2: mufu = 3; break;
1352 case OP_RCP: mufu = 4 + 2 * insn->subOp; break;
1353 case OP_RSQ: mufu = 5 + 2 * insn->subOp; break;
1354 default:
1355 assert(!"invalid mufu");
1356 break;
1357 }
1358
1359 emitInsn (0x50800000);
1360 emitSAT (0x32);
1361 emitNEG (0x30, insn->src(0));
1362 emitABS (0x2e, insn->src(0));
1363 emitField(0x14, 3, mufu);
1364 emitGPR (0x08, insn->src(0));
1365 emitGPR (0x00, insn->def(0));
1366 }
1367
1368 void
1369 CodeEmitterGM107::emitFMNMX()
1370 {
1371 switch (insn->src(1).getFile()) {
1372 case FILE_GPR:
1373 emitInsn(0x5c600000);
1374 emitGPR (0x14, insn->src(1));
1375 break;
1376 case FILE_MEMORY_CONST:
1377 emitInsn(0x4c600000);
1378 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1379 break;
1380 case FILE_IMMEDIATE:
1381 emitInsn(0x38600000);
1382 emitIMMD(0x14, 19, insn->src(1));
1383 break;
1384 default:
1385 assert(!"bad src1 file");
1386 break;
1387 }
1388
1389 emitField(0x2a, 1, insn->op == OP_MAX);
1390 emitPRED (0x27);
1391
1392 emitABS(0x31, insn->src(1));
1393 emitNEG(0x30, insn->src(0));
1394 emitCC (0x2f);
1395 emitABS(0x2e, insn->src(0));
1396 emitNEG(0x2d, insn->src(1));
1397 emitFMZ(0x2c, 1);
1398 emitGPR(0x08, insn->src(0));
1399 emitGPR(0x00, insn->def(0));
1400 }
1401
1402 void
1403 CodeEmitterGM107::emitRRO()
1404 {
1405 switch (insn->src(0).getFile()) {
1406 case FILE_GPR:
1407 emitInsn(0x5c900000);
1408 emitGPR (0x14, insn->src(0));
1409 break;
1410 case FILE_MEMORY_CONST:
1411 emitInsn(0x4c900000);
1412 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
1413 break;
1414 case FILE_IMMEDIATE:
1415 emitInsn(0x38900000);
1416 emitIMMD(0x14, 19, insn->src(0));
1417 break;
1418 default:
1419 assert(!"bad src file");
1420 break;
1421 }
1422
1423 emitABS (0x31, insn->src(0));
1424 emitNEG (0x2d, insn->src(0));
1425 emitField(0x27, 1, insn->op == OP_PREEX2);
1426 emitGPR (0x00, insn->def(0));
1427 }
1428
1429 void
1430 CodeEmitterGM107::emitFCMP()
1431 {
1432 const CmpInstruction *insn = this->insn->asCmp();
1433 CondCode cc = insn->setCond;
1434
1435 if (insn->src(2).mod.neg())
1436 cc = reverseCondCode(cc);
1437
1438 switch(insn->src(2).getFile()) {
1439 case FILE_GPR:
1440 switch (insn->src(1).getFile()) {
1441 case FILE_GPR:
1442 emitInsn(0x5ba00000);
1443 emitGPR (0x14, insn->src(1));
1444 break;
1445 case FILE_MEMORY_CONST:
1446 emitInsn(0x4ba00000);
1447 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1448 break;
1449 case FILE_IMMEDIATE:
1450 emitInsn(0x36a00000);
1451 emitIMMD(0x14, 19, insn->src(1));
1452 break;
1453 default:
1454 assert(!"bad src1 file");
1455 break;
1456 }
1457 emitGPR (0x27, insn->src(2));
1458 break;
1459 case FILE_MEMORY_CONST:
1460 emitInsn(0x53a00000);
1461 emitGPR (0x27, insn->src(1));
1462 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(2));
1463 break;
1464 default:
1465 assert(!"bad src2 file");
1466 break;
1467 }
1468
1469 emitCond4(0x30, cc);
1470 emitFMZ (0x2f, 1);
1471 emitGPR (0x08, insn->src(0));
1472 emitGPR (0x00, insn->def(0));
1473 }
1474
1475 void
1476 CodeEmitterGM107::emitFSET()
1477 {
1478 const CmpInstruction *insn = this->insn->asCmp();
1479
1480 switch (insn->src(1).getFile()) {
1481 case FILE_GPR:
1482 emitInsn(0x58000000);
1483 emitGPR (0x14, insn->src(1));
1484 break;
1485 case FILE_MEMORY_CONST:
1486 emitInsn(0x48000000);
1487 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1488 break;
1489 case FILE_IMMEDIATE:
1490 emitInsn(0x30000000);
1491 emitIMMD(0x14, 19, insn->src(1));
1492 break;
1493 default:
1494 assert(!"bad src1 file");
1495 break;
1496 }
1497
1498 if (insn->op != OP_SET) {
1499 switch (insn->op) {
1500 case OP_SET_AND: emitField(0x2d, 2, 0); break;
1501 case OP_SET_OR : emitField(0x2d, 2, 1); break;
1502 case OP_SET_XOR: emitField(0x2d, 2, 2); break;
1503 default:
1504 assert(!"invalid set op");
1505 break;
1506 }
1507 emitPRED(0x27, insn->src(2));
1508 } else {
1509 emitPRED(0x27);
1510 }
1511
1512 emitFMZ (0x37, 1);
1513 emitABS (0x36, insn->src(0));
1514 emitNEG (0x35, insn->src(1));
1515 emitField(0x34, 1, insn->dType == TYPE_F32);
1516 emitCond4(0x30, insn->setCond);
1517 emitCC (0x2f);
1518 emitABS (0x2c, insn->src(1));
1519 emitNEG (0x2b, insn->src(0));
1520 emitGPR (0x08, insn->src(0));
1521 emitGPR (0x00, insn->def(0));
1522 }
1523
1524 void
1525 CodeEmitterGM107::emitFSETP()
1526 {
1527 const CmpInstruction *insn = this->insn->asCmp();
1528
1529 switch (insn->src(1).getFile()) {
1530 case FILE_GPR:
1531 emitInsn(0x5bb00000);
1532 emitGPR (0x14, insn->src(1));
1533 break;
1534 case FILE_MEMORY_CONST:
1535 emitInsn(0x4bb00000);
1536 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1537 break;
1538 case FILE_IMMEDIATE:
1539 emitInsn(0x36b00000);
1540 emitIMMD(0x14, 19, insn->src(1));
1541 break;
1542 default:
1543 assert(!"bad src1 file");
1544 break;
1545 }
1546
1547 if (insn->op != OP_SET) {
1548 switch (insn->op) {
1549 case OP_SET_AND: emitField(0x2d, 2, 0); break;
1550 case OP_SET_OR : emitField(0x2d, 2, 1); break;
1551 case OP_SET_XOR: emitField(0x2d, 2, 2); break;
1552 default:
1553 assert(!"invalid set op");
1554 break;
1555 }
1556 emitPRED(0x27, insn->src(2));
1557 } else {
1558 emitPRED(0x27);
1559 }
1560
1561 emitCond4(0x30, insn->setCond);
1562 emitFMZ (0x2f, 1);
1563 emitABS (0x2c, insn->src(1));
1564 emitNEG (0x2b, insn->src(0));
1565 emitGPR (0x08, insn->src(0));
1566 emitABS (0x07, insn->src(0));
1567 emitNEG (0x06, insn->src(1));
1568 emitPRED (0x03, insn->def(0));
1569 if (insn->defExists(1))
1570 emitPRED(0x00, insn->def(1));
1571 else
1572 emitPRED(0x00);
1573 }
1574
1575 void
1576 CodeEmitterGM107::emitFSWZADD()
1577 {
1578 emitInsn (0x50f80000);
1579 emitCC (0x2f);
1580 emitFMZ (0x2c, 1);
1581 emitRND (0x27);
1582 emitField(0x26, 1, insn->lanes); /* abused for .ndv */
1583 emitField(0x1c, 8, insn->subOp);
1584 if (insn->predSrc != 1)
1585 emitGPR (0x14, insn->src(1));
1586 else
1587 emitGPR (0x14);
1588 emitGPR (0x08, insn->src(0));
1589 emitGPR (0x00, insn->def(0));
1590 }
1591
1592 /*******************************************************************************
1593 * integer
1594 ******************************************************************************/
1595
1596 void
1597 CodeEmitterGM107::emitLOP()
1598 {
1599 int lop = 0;
1600
1601 switch (insn->op) {
1602 case OP_AND: lop = 0; break;
1603 case OP_OR : lop = 1; break;
1604 case OP_XOR: lop = 2; break;
1605 default:
1606 assert(!"invalid lop");
1607 break;
1608 }
1609
1610 if (!longIMMD(insn->src(1))) {
1611 switch (insn->src(1).getFile()) {
1612 case FILE_GPR:
1613 emitInsn(0x5c400000);
1614 emitGPR (0x14, insn->src(1));
1615 break;
1616 case FILE_MEMORY_CONST:
1617 emitInsn(0x4c400000);
1618 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1619 break;
1620 case FILE_IMMEDIATE:
1621 emitInsn(0x38400000);
1622 emitIMMD(0x14, 19, insn->src(1));
1623 break;
1624 default:
1625 assert(!"bad src1 file");
1626 break;
1627 }
1628 emitPRED (0x30);
1629 emitX (0x2b);
1630 emitField(0x29, 2, lop);
1631 emitINV (0x28, insn->src(1));
1632 emitINV (0x27, insn->src(0));
1633 } else {
1634 emitInsn (0x04000000);
1635 emitX (0x39);
1636 emitINV (0x38, insn->src(1));
1637 emitINV (0x37, insn->src(0));
1638 emitField(0x35, 2, lop);
1639 emitIMMD (0x14, 32, insn->src(1));
1640 }
1641
1642 emitGPR (0x08, insn->src(0));
1643 emitGPR (0x00, insn->def(0));
1644 }
1645
1646 /* special-case of emitLOP(): lop pass_b dst 0 ~src */
1647 void
1648 CodeEmitterGM107::emitNOT()
1649 {
1650 if (!longIMMD(insn->src(0))) {
1651 switch (insn->src(0).getFile()) {
1652 case FILE_GPR:
1653 emitInsn(0x5c400700);
1654 emitGPR (0x14, insn->src(0));
1655 break;
1656 case FILE_MEMORY_CONST:
1657 emitInsn(0x4c400700);
1658 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
1659 break;
1660 case FILE_IMMEDIATE:
1661 emitInsn(0x38400700);
1662 emitIMMD(0x14, 19, insn->src(0));
1663 break;
1664 default:
1665 assert(!"bad src1 file");
1666 break;
1667 }
1668 emitPRED (0x30);
1669 } else {
1670 emitInsn (0x05600000);
1671 emitIMMD (0x14, 32, insn->src(1));
1672 }
1673
1674 emitGPR(0x08);
1675 emitGPR(0x00, insn->def(0));
1676 }
1677
1678 void
1679 CodeEmitterGM107::emitIADD()
1680 {
1681 if (!longIMMD(insn->src(1))) {
1682 switch (insn->src(1).getFile()) {
1683 case FILE_GPR:
1684 emitInsn(0x5c100000);
1685 emitGPR (0x14, insn->src(1));
1686 break;
1687 case FILE_MEMORY_CONST:
1688 emitInsn(0x4c100000);
1689 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1690 break;
1691 case FILE_IMMEDIATE:
1692 emitInsn(0x38100000);
1693 emitIMMD(0x14, 19, insn->src(1));
1694 break;
1695 default:
1696 assert(!"bad src1 file");
1697 break;
1698 }
1699 emitSAT(0x32);
1700 emitNEG(0x31, insn->src(0));
1701 emitNEG(0x30, insn->src(1));
1702 emitCC (0x2f);
1703 emitX (0x2b);
1704 } else {
1705 emitInsn(0x1c000000);
1706 emitSAT (0x36);
1707 emitX (0x35);
1708 emitCC (0x34);
1709 emitIMMD(0x14, 32, insn->src(1));
1710 }
1711
1712 if (insn->op == OP_SUB)
1713 code[1] ^= 0x00010000;
1714
1715 emitGPR(0x08, insn->src(0));
1716 emitGPR(0x00, insn->def(0));
1717 }
1718
1719 void
1720 CodeEmitterGM107::emitIMUL()
1721 {
1722 if (!longIMMD(insn->src(1))) {
1723 switch (insn->src(1).getFile()) {
1724 case FILE_GPR:
1725 emitInsn(0x5c380000);
1726 emitGPR (0x14, insn->src(1));
1727 break;
1728 case FILE_MEMORY_CONST:
1729 emitInsn(0x4c380000);
1730 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1731 break;
1732 case FILE_IMMEDIATE:
1733 emitInsn(0x38380000);
1734 emitIMMD(0x14, 19, insn->src(1));
1735 break;
1736 default:
1737 assert(!"bad src1 file");
1738 break;
1739 }
1740 emitCC (0x2f);
1741 emitField(0x29, 1, isSignedType(insn->sType));
1742 emitField(0x28, 1, isSignedType(insn->dType));
1743 emitField(0x27, 1, insn->subOp == NV50_IR_SUBOP_MUL_HIGH);
1744 } else {
1745 emitInsn (0x1f000000);
1746 emitField(0x37, 1, isSignedType(insn->sType));
1747 emitField(0x36, 1, isSignedType(insn->dType));
1748 emitField(0x35, 1, insn->subOp == NV50_IR_SUBOP_MUL_HIGH);
1749 emitCC (0x34);
1750 emitIMMD (0x14, 32, insn->src(1));
1751 }
1752
1753 emitGPR(0x08, insn->src(0));
1754 emitGPR(0x00, insn->def(0));
1755 }
1756
1757 void
1758 CodeEmitterGM107::emitIMAD()
1759 {
1760 /*XXX: imad32i exists, but not using it as third src overlaps dst */
1761 switch(insn->src(2).getFile()) {
1762 case FILE_GPR:
1763 switch (insn->src(1).getFile()) {
1764 case FILE_GPR:
1765 emitInsn(0x5a000000);
1766 emitGPR (0x14, insn->src(1));
1767 break;
1768 case FILE_MEMORY_CONST:
1769 emitInsn(0x4a000000);
1770 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1771 break;
1772 case FILE_IMMEDIATE:
1773 emitInsn(0x34000000);
1774 emitIMMD(0x14, 19, insn->src(1));
1775 break;
1776 default:
1777 assert(!"bad src1 file");
1778 break;
1779 }
1780 emitGPR (0x27, insn->src(2));
1781 break;
1782 case FILE_MEMORY_CONST:
1783 emitInsn(0x52000000);
1784 emitGPR (0x27, insn->src(1));
1785 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(2));
1786 break;
1787 default:
1788 assert(!"bad src2 file");
1789 break;
1790 }
1791
1792 emitField(0x36, 1, insn->subOp == NV50_IR_SUBOP_MUL_HIGH);
1793 emitField(0x35, 1, isSignedType(insn->sType));
1794 emitNEG (0x34, insn->src(2));
1795 emitNEG2 (0x33, insn->src(0), insn->src(1));
1796 emitSAT (0x32);
1797 emitX (0x31);
1798 emitField(0x30, 1, isSignedType(insn->dType));
1799 emitCC (0x2f);
1800 emitGPR (0x08, insn->src(0));
1801 emitGPR (0x00, insn->def(0));
1802 }
1803
1804 void
1805 CodeEmitterGM107::emitIMNMX()
1806 {
1807 switch (insn->src(1).getFile()) {
1808 case FILE_GPR:
1809 emitInsn(0x5c200000);
1810 emitGPR (0x14, insn->src(1));
1811 break;
1812 case FILE_MEMORY_CONST:
1813 emitInsn(0x4c200000);
1814 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1815 break;
1816 case FILE_IMMEDIATE:
1817 emitInsn(0x38200000);
1818 emitIMMD(0x14, 19, insn->src(1));
1819 break;
1820 default:
1821 assert(!"bad src1 file");
1822 break;
1823 }
1824
1825 emitField(0x30, 1, isSignedType(insn->dType));
1826 emitCC (0x2f);
1827 emitField(0x2a, 1, insn->op == OP_MAX);
1828 emitPRED (0x27);
1829 emitGPR (0x08, insn->src(0));
1830 emitGPR (0x00, insn->def(0));
1831 }
1832
1833 void
1834 CodeEmitterGM107::emitICMP()
1835 {
1836 const CmpInstruction *insn = this->insn->asCmp();
1837 CondCode cc = insn->setCond;
1838
1839 if (insn->src(2).mod.neg())
1840 cc = reverseCondCode(cc);
1841
1842 switch(insn->src(2).getFile()) {
1843 case FILE_GPR:
1844 switch (insn->src(1).getFile()) {
1845 case FILE_GPR:
1846 emitInsn(0x5b400000);
1847 emitGPR (0x14, insn->src(1));
1848 break;
1849 case FILE_MEMORY_CONST:
1850 emitInsn(0x4b400000);
1851 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1852 break;
1853 case FILE_IMMEDIATE:
1854 emitInsn(0x36400000);
1855 emitIMMD(0x14, 19, insn->src(1));
1856 break;
1857 default:
1858 assert(!"bad src1 file");
1859 break;
1860 }
1861 emitGPR (0x27, insn->src(2));
1862 break;
1863 case FILE_MEMORY_CONST:
1864 emitInsn(0x53400000);
1865 emitGPR (0x27, insn->src(1));
1866 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(2));
1867 break;
1868 default:
1869 assert(!"bad src2 file");
1870 break;
1871 }
1872
1873 emitCond3(0x31, cc);
1874 emitField(0x30, 1, isSignedType(insn->sType));
1875 emitGPR (0x08, insn->src(0));
1876 emitGPR (0x00, insn->def(0));
1877 }
1878
1879 void
1880 CodeEmitterGM107::emitISET()
1881 {
1882 const CmpInstruction *insn = this->insn->asCmp();
1883
1884 switch (insn->src(1).getFile()) {
1885 case FILE_GPR:
1886 emitInsn(0x5b500000);
1887 emitGPR (0x14, insn->src(1));
1888 break;
1889 case FILE_MEMORY_CONST:
1890 emitInsn(0x4b500000);
1891 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1892 break;
1893 case FILE_IMMEDIATE:
1894 emitInsn(0x36500000);
1895 emitIMMD(0x14, 19, insn->src(1));
1896 break;
1897 default:
1898 assert(!"bad src1 file");
1899 break;
1900 }
1901
1902 if (insn->op != OP_SET) {
1903 switch (insn->op) {
1904 case OP_SET_AND: emitField(0x2d, 2, 0); break;
1905 case OP_SET_OR : emitField(0x2d, 2, 1); break;
1906 case OP_SET_XOR: emitField(0x2d, 2, 2); break;
1907 default:
1908 assert(!"invalid set op");
1909 break;
1910 }
1911 emitPRED(0x27, insn->src(2));
1912 } else {
1913 emitPRED(0x27);
1914 }
1915
1916 emitCond3(0x31, insn->setCond);
1917 emitField(0x30, 1, isSignedType(insn->sType));
1918 emitCC (0x2f);
1919 emitField(0x2c, 1, insn->dType == TYPE_F32);
1920 emitX (0x2b);
1921 emitGPR (0x08, insn->src(0));
1922 emitGPR (0x00, insn->def(0));
1923 }
1924
1925 void
1926 CodeEmitterGM107::emitISETP()
1927 {
1928 const CmpInstruction *insn = this->insn->asCmp();
1929
1930 switch (insn->src(1).getFile()) {
1931 case FILE_GPR:
1932 emitInsn(0x5b600000);
1933 emitGPR (0x14, insn->src(1));
1934 break;
1935 case FILE_MEMORY_CONST:
1936 emitInsn(0x4b600000);
1937 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1938 break;
1939 case FILE_IMMEDIATE:
1940 emitInsn(0x36600000);
1941 emitIMMD(0x14, 19, insn->src(1));
1942 break;
1943 default:
1944 assert(!"bad src1 file");
1945 break;
1946 }
1947
1948 if (insn->op != OP_SET) {
1949 switch (insn->op) {
1950 case OP_SET_AND: emitField(0x2d, 2, 0); break;
1951 case OP_SET_OR : emitField(0x2d, 2, 1); break;
1952 case OP_SET_XOR: emitField(0x2d, 2, 2); break;
1953 default:
1954 assert(!"invalid set op");
1955 break;
1956 }
1957 emitPRED(0x27, insn->src(2));
1958 } else {
1959 emitPRED(0x27);
1960 }
1961
1962 emitCond3(0x31, insn->setCond);
1963 emitField(0x30, 1, isSignedType(insn->sType));
1964 emitX (0x2b);
1965 emitGPR (0x08, insn->src(0));
1966 emitPRED (0x03, insn->def(0));
1967 if (insn->defExists(1))
1968 emitPRED(0x00, insn->def(1));
1969 else
1970 emitPRED(0x00);
1971 }
1972
1973 void
1974 CodeEmitterGM107::emitSHL()
1975 {
1976 switch (insn->src(1).getFile()) {
1977 case FILE_GPR:
1978 emitInsn(0x5c480000);
1979 emitGPR (0x14, insn->src(1));
1980 break;
1981 case FILE_MEMORY_CONST:
1982 emitInsn(0x4c480000);
1983 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1984 break;
1985 case FILE_IMMEDIATE:
1986 emitInsn(0x38480000);
1987 emitIMMD(0x14, 19, insn->src(1));
1988 break;
1989 default:
1990 assert(!"bad src1 file");
1991 break;
1992 }
1993
1994 emitCC (0x2f);
1995 emitX (0x2b);
1996 emitField(0x27, 1, insn->subOp == NV50_IR_SUBOP_SHIFT_WRAP);
1997 emitGPR (0x08, insn->src(0));
1998 emitGPR (0x00, insn->def(0));
1999 }
2000
2001 void
2002 CodeEmitterGM107::emitSHR()
2003 {
2004 switch (insn->src(1).getFile()) {
2005 case FILE_GPR:
2006 emitInsn(0x5c280000);
2007 emitGPR (0x14, insn->src(1));
2008 break;
2009 case FILE_MEMORY_CONST:
2010 emitInsn(0x4c280000);
2011 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
2012 break;
2013 case FILE_IMMEDIATE:
2014 emitInsn(0x38280000);
2015 emitIMMD(0x14, 19, insn->src(1));
2016 break;
2017 default:
2018 assert(!"bad src1 file");
2019 break;
2020 }
2021
2022 emitField(0x30, 1, isSignedType(insn->dType));
2023 emitCC (0x2f);
2024 emitX (0x2c);
2025 emitField(0x27, 1, insn->subOp == NV50_IR_SUBOP_SHIFT_WRAP);
2026 emitGPR (0x08, insn->src(0));
2027 emitGPR (0x00, insn->def(0));
2028 }
2029
2030 void
2031 CodeEmitterGM107::emitPOPC()
2032 {
2033 switch (insn->src(0).getFile()) {
2034 case FILE_GPR:
2035 emitInsn(0x5c080000);
2036 emitGPR (0x14, insn->src(0));
2037 break;
2038 case FILE_MEMORY_CONST:
2039 emitInsn(0x4c080000);
2040 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
2041 break;
2042 case FILE_IMMEDIATE:
2043 emitInsn(0x38080000);
2044 emitIMMD(0x14, 19, insn->src(0));
2045 break;
2046 default:
2047 assert(!"bad src1 file");
2048 break;
2049 }
2050
2051 emitINV(0x28, insn->src(0));
2052 emitGPR(0x00, insn->def(0));
2053 }
2054
2055 void
2056 CodeEmitterGM107::emitBFI()
2057 {
2058 switch(insn->src(2).getFile()) {
2059 case FILE_GPR:
2060 switch (insn->src(1).getFile()) {
2061 case FILE_GPR:
2062 emitInsn(0x5bf00000);
2063 emitGPR (0x14, insn->src(1));
2064 break;
2065 case FILE_MEMORY_CONST:
2066 emitInsn(0x4bf00000);
2067 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
2068 break;
2069 case FILE_IMMEDIATE:
2070 emitInsn(0x36f00000);
2071 emitIMMD(0x14, 19, insn->src(1));
2072 break;
2073 default:
2074 assert(!"bad src1 file");
2075 break;
2076 }
2077 emitGPR (0x27, insn->src(2));
2078 break;
2079 case FILE_MEMORY_CONST:
2080 emitInsn(0x53f00000);
2081 emitGPR (0x27, insn->src(1));
2082 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(2));
2083 break;
2084 default:
2085 assert(!"bad src2 file");
2086 break;
2087 }
2088
2089 emitCC (0x2f);
2090 emitGPR (0x08, insn->src(0));
2091 emitGPR (0x00, insn->def(0));
2092 }
2093
2094 void
2095 CodeEmitterGM107::emitBFE()
2096 {
2097 switch (insn->src(1).getFile()) {
2098 case FILE_GPR:
2099 emitInsn(0x5c000000);
2100 emitGPR (0x14, insn->src(1));
2101 break;
2102 case FILE_MEMORY_CONST:
2103 emitInsn(0x4c000000);
2104 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
2105 break;
2106 case FILE_IMMEDIATE:
2107 emitInsn(0x38000000);
2108 emitIMMD(0x14, 19, insn->src(1));
2109 break;
2110 default:
2111 assert(!"bad src1 file");
2112 break;
2113 }
2114
2115 emitField(0x30, 1, isSignedType(insn->dType));
2116 emitCC (0x2f);
2117 emitField(0x28, 1, insn->subOp == NV50_IR_SUBOP_EXTBF_REV);
2118 emitGPR (0x08, insn->src(0));
2119 emitGPR (0x00, insn->def(0));
2120 }
2121
2122 void
2123 CodeEmitterGM107::emitFLO()
2124 {
2125 switch (insn->src(0).getFile()) {
2126 case FILE_GPR:
2127 emitInsn(0x5c300000);
2128 emitGPR (0x14, insn->src(0));
2129 break;
2130 case FILE_MEMORY_CONST:
2131 emitInsn(0x4c300000);
2132 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
2133 break;
2134 case FILE_IMMEDIATE:
2135 emitInsn(0x38300000);
2136 emitIMMD(0x14, 19, insn->src(0));
2137 break;
2138 default:
2139 assert(!"bad src1 file");
2140 break;
2141 }
2142
2143 emitField(0x30, 1, isSignedType(insn->dType));
2144 emitCC (0x2f);
2145 emitField(0x29, 1, insn->subOp == NV50_IR_SUBOP_BFIND_SAMT);
2146 emitINV (0x28, insn->src(0));
2147 emitGPR (0x00, insn->def(0));
2148 }
2149
2150 /*******************************************************************************
2151 * memory
2152 ******************************************************************************/
2153
2154 void
2155 CodeEmitterGM107::emitLDSTs(int pos, DataType type)
2156 {
2157 int data = 0;
2158
2159 switch (typeSizeof(type)) {
2160 case 1: data = isSignedType(type) ? 1 : 0; break;
2161 case 2: data = isSignedType(type) ? 3 : 2; break;
2162 case 4: data = 4; break;
2163 case 8: data = 5; break;
2164 case 16: data = 6; break;
2165 default:
2166 assert(!"bad type");
2167 break;
2168 }
2169
2170 emitField(pos, 3, data);
2171 }
2172
2173 void
2174 CodeEmitterGM107::emitLDSTc(int pos)
2175 {
2176 int mode = 0;
2177
2178 switch (insn->cache) {
2179 case CACHE_CA: mode = 0; break;
2180 case CACHE_CG: mode = 1; break;
2181 case CACHE_CS: mode = 2; break;
2182 case CACHE_CV: mode = 3; break;
2183 default:
2184 assert(!"invalid caching mode");
2185 break;
2186 }
2187
2188 emitField(pos, 2, mode);
2189 }
2190
2191 void
2192 CodeEmitterGM107::emitLDC()
2193 {
2194 emitInsn (0xef900000);
2195 emitLDSTs(0x30, insn->dType);
2196 emitField(0x2c, 2, insn->subOp);
2197 emitCBUF (0x24, 0x08, 0x14, 16, 0, insn->src(0));
2198 emitGPR (0x00, insn->def(0));
2199 }
2200
2201 void
2202 CodeEmitterGM107::emitLDL()
2203 {
2204 emitInsn (0xef400000);
2205 emitLDSTs(0x30, insn->dType);
2206 emitLDSTc(0x2c);
2207 emitADDR (0x08, 0x14, 24, 0, insn->src(0));
2208 emitGPR (0x00, insn->def(0));
2209 }
2210
2211 void
2212 CodeEmitterGM107::emitLDS()
2213 {
2214 emitInsn (0xef480000);
2215 emitLDSTs(0x30, insn->dType);
2216 emitADDR (0x08, 0x14, 24, 0, insn->src(0));
2217 emitGPR (0x00, insn->def(0));
2218 }
2219
2220 void
2221 CodeEmitterGM107::emitLD()
2222 {
2223 emitInsn (0x80000000);
2224 emitPRED (0x3a);
2225 emitLDSTc(0x38);
2226 emitLDSTs(0x35, insn->dType);
2227 emitField(0x34, 1, insn->src(0).getIndirect(0)->getSize() == 8);
2228 emitADDR (0x08, 0x14, 32, 0, insn->src(0));
2229 emitGPR (0x00, insn->def(0));
2230 }
2231
2232 void
2233 CodeEmitterGM107::emitSTL()
2234 {
2235 emitInsn (0xef500000);
2236 emitLDSTs(0x30, insn->dType);
2237 emitLDSTc(0x2c);
2238 emitADDR (0x08, 0x14, 24, 0, insn->src(0));
2239 emitGPR (0x00, insn->src(1));
2240 }
2241
2242 void
2243 CodeEmitterGM107::emitSTS()
2244 {
2245 emitInsn (0xef580000);
2246 emitLDSTs(0x30, insn->dType);
2247 emitADDR (0x08, 0x14, 24, 0, insn->src(0));
2248 emitGPR (0x00, insn->src(1));
2249 }
2250
2251 void
2252 CodeEmitterGM107::emitST()
2253 {
2254 emitInsn (0xa0000000);
2255 emitPRED (0x3a);
2256 emitLDSTc(0x38);
2257 emitLDSTs(0x35, insn->dType);
2258 emitField(0x34, 1, insn->src(0).getIndirect(0)->getSize() == 8);
2259 emitADDR (0x08, 0x14, 32, 0, insn->src(0));
2260 emitGPR (0x00, insn->src(1));
2261 }
2262
2263 void
2264 CodeEmitterGM107::emitALD()
2265 {
2266 emitInsn (0xefd80000);
2267 emitField(0x2f, 2, (insn->getDef(0)->reg.size / 4) - 1);
2268 emitGPR (0x27, insn->src(0).getIndirect(1));
2269 emitO (0x20);
2270 emitP (0x1f);
2271 emitADDR (0x08, 20, 10, 0, insn->src(0));
2272 emitGPR (0x00, insn->def(0));
2273 }
2274
2275 void
2276 CodeEmitterGM107::emitAST()
2277 {
2278 emitInsn (0xeff00000);
2279 emitField(0x2f, 2, (typeSizeof(insn->dType) / 4) - 1);
2280 emitGPR (0x27, insn->src(0).getIndirect(1));
2281 emitP (0x1f);
2282 emitADDR (0x08, 20, 10, 0, insn->src(0));
2283 emitGPR (0x00, insn->src(1));
2284 }
2285
2286 void
2287 CodeEmitterGM107::emitISBERD()
2288 {
2289 emitInsn(0xefd00000);
2290 emitGPR (0x08, insn->src(0));
2291 emitGPR (0x00, insn->def(0));
2292 }
2293
2294 void
2295 CodeEmitterGM107::emitAL2P()
2296 {
2297 emitInsn (0xefa00000);
2298 emitField(0x2f, 2, (insn->getDef(0)->reg.size / 4) - 1);
2299 emitO (0x20);
2300 emitField(0x14, 11, insn->src(0).get()->reg.data.offset);
2301 emitGPR (0x08, insn->src(0).getIndirect(0));
2302 emitGPR (0x00, insn->def(0));
2303 }
2304
2305 static void
2306 interpApply(const FixupEntry *entry, uint32_t *code, const FixupData& data)
2307 {
2308 int ipa = entry->ipa;
2309 int reg = entry->reg;
2310 int loc = entry->loc;
2311
2312 if (data.flatshade &&
2313 (ipa & NV50_IR_INTERP_MODE_MASK) == NV50_IR_INTERP_SC) {
2314 ipa = NV50_IR_INTERP_FLAT;
2315 reg = 0xff;
2316 } else if (data.force_persample_interp &&
2317 (ipa & NV50_IR_INTERP_SAMPLE_MASK) == NV50_IR_INTERP_DEFAULT &&
2318 (ipa & NV50_IR_INTERP_MODE_MASK) != NV50_IR_INTERP_FLAT) {
2319 ipa |= NV50_IR_INTERP_CENTROID;
2320 }
2321 code[loc + 1] &= ~(0xf << 0x14);
2322 code[loc + 1] |= (ipa & 0x3) << 0x16;
2323 code[loc + 1] |= (ipa & 0xc) << (0x14 - 2);
2324 code[loc + 0] &= ~(0xff << 0x14);
2325 code[loc + 0] |= reg << 0x14;
2326 }
2327
2328 void
2329 CodeEmitterGM107::emitIPA()
2330 {
2331 int ipam = 0, ipas = 0;
2332
2333 switch (insn->getInterpMode()) {
2334 case NV50_IR_INTERP_LINEAR : ipam = 0; break;
2335 case NV50_IR_INTERP_PERSPECTIVE: ipam = 1; break;
2336 case NV50_IR_INTERP_FLAT : ipam = 2; break;
2337 case NV50_IR_INTERP_SC : ipam = 3; break;
2338 default:
2339 assert(!"invalid ipa mode");
2340 break;
2341 }
2342
2343 switch (insn->getSampleMode()) {
2344 case NV50_IR_INTERP_DEFAULT : ipas = 0; break;
2345 case NV50_IR_INTERP_CENTROID: ipas = 1; break;
2346 case NV50_IR_INTERP_OFFSET : ipas = 2; break;
2347 default:
2348 assert(!"invalid ipa sample mode");
2349 break;
2350 }
2351
2352 emitInsn (0xe0000000);
2353 emitField(0x36, 2, ipam);
2354 emitField(0x34, 2, ipas);
2355 emitSAT (0x33);
2356 emitField(0x2f, 3, 7);
2357 emitADDR (0x08, 0x1c, 10, 0, insn->src(0));
2358 if ((code[0] & 0x0000ff00) != 0x0000ff00)
2359 code[1] |= 0x00000040; /* .idx */
2360 emitGPR(0x00, insn->def(0));
2361
2362 if (insn->op == OP_PINTERP) {
2363 emitGPR(0x14, insn->src(1));
2364 if (insn->getSampleMode() == NV50_IR_INTERP_OFFSET)
2365 emitGPR(0x27, insn->src(2));
2366 addInterp(insn->ipa, insn->getSrc(1)->reg.data.id, interpApply);
2367 } else {
2368 if (insn->getSampleMode() == NV50_IR_INTERP_OFFSET)
2369 emitGPR(0x27, insn->src(1));
2370 emitGPR(0x14);
2371 addInterp(insn->ipa, 0xff, interpApply);
2372 }
2373
2374 if (insn->getSampleMode() != NV50_IR_INTERP_OFFSET)
2375 emitGPR(0x27);
2376 }
2377
2378 void
2379 CodeEmitterGM107::emitATOM()
2380 {
2381 unsigned dType, subOp;
2382
2383 if (insn->subOp == NV50_IR_SUBOP_ATOM_CAS) {
2384 switch (insn->dType) {
2385 case TYPE_U32: dType = 0; break;
2386 case TYPE_U64: dType = 1; break;
2387 default: assert(!"unexpected dType"); dType = 0; break;
2388 }
2389 subOp = 15;
2390
2391 emitInsn (0xee000000);
2392 } else {
2393 switch (insn->dType) {
2394 case TYPE_U32: dType = 0; break;
2395 case TYPE_S32: dType = 1; break;
2396 case TYPE_U64: dType = 2; break;
2397 case TYPE_F32: dType = 3; break;
2398 case TYPE_B128: dType = 4; break;
2399 case TYPE_S64: dType = 5; break;
2400 default: assert(!"unexpected dType"); dType = 0; break;
2401 }
2402 if (insn->subOp == NV50_IR_SUBOP_ATOM_EXCH)
2403 subOp = 8;
2404 else
2405 subOp = insn->subOp;
2406
2407 emitInsn (0xed000000);
2408 }
2409
2410 emitField(0x34, 4, subOp);
2411 emitField(0x31, 3, dType);
2412 emitField(0x30, 1, insn->src(0).getIndirect(0)->getSize() == 8);
2413 emitGPR (0x14, insn->src(1));
2414 emitADDR (0x08, 0x1c, 20, 0, insn->src(0));
2415 emitGPR (0x00, insn->def(0));
2416 }
2417
2418 void
2419 CodeEmitterGM107::emitATOMS()
2420 {
2421 unsigned dType, subOp;
2422
2423 if (insn->subOp == NV50_IR_SUBOP_ATOM_CAS) {
2424 switch (insn->dType) {
2425 case TYPE_U32: dType = 0; break;
2426 case TYPE_U64: dType = 1; break;
2427 default: assert(!"unexpected dType"); dType = 0; break;
2428 }
2429 subOp = 4;
2430
2431 emitInsn (0xee000000);
2432 emitField(0x34, 1, dType);
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_S64: dType = 3; break;
2439 default: assert(!"unexpected dType"); dType = 0; break;
2440 }
2441
2442 if (insn->subOp == NV50_IR_SUBOP_ATOM_EXCH)
2443 subOp = 8;
2444 else
2445 subOp = insn->subOp;
2446
2447 emitInsn (0xec000000);
2448 emitField(0x1c, 3, dType);
2449 }
2450
2451 emitField(0x34, 4, subOp);
2452 emitGPR (0x14, insn->src(1));
2453 emitADDR (0x08, 0x12, 22, 0, insn->src(0));
2454 emitGPR (0x00, insn->def(0));
2455 }
2456
2457 void
2458 CodeEmitterGM107::emitCCTL()
2459 {
2460 unsigned width;
2461 if (insn->src(0).getFile() == FILE_MEMORY_GLOBAL) {
2462 emitInsn(0xef600000);
2463 width = 30;
2464 } else {
2465 emitInsn(0xef800000);
2466 width = 22;
2467 }
2468 emitField(0x34, 1, insn->src(0).getIndirect(0)->getSize() == 8);
2469 emitADDR (0x08, 0x16, width, 2, insn->src(0));
2470 emitField(0x00, 4, insn->subOp);
2471 }
2472
2473 /*******************************************************************************
2474 * surface
2475 ******************************************************************************/
2476
2477 void
2478 CodeEmitterGM107::emitPIXLD()
2479 {
2480 emitInsn (0xefe80000);
2481 emitPRED (0x2d);
2482 emitField(0x1f, 3, insn->subOp);
2483 emitGPR (0x08, insn->src(0));
2484 emitGPR (0x00, insn->def(0));
2485 }
2486
2487 /*******************************************************************************
2488 * texture
2489 ******************************************************************************/
2490
2491 void
2492 CodeEmitterGM107::emitTEXs(int pos)
2493 {
2494 int src1 = insn->predSrc == 1 ? 2 : 1;
2495 if (insn->srcExists(src1))
2496 emitGPR(pos, insn->src(src1));
2497 else
2498 emitGPR(pos);
2499 }
2500
2501 void
2502 CodeEmitterGM107::emitTEX()
2503 {
2504 const TexInstruction *insn = this->insn->asTex();
2505 int lodm = 0;
2506
2507 if (!insn->tex.levelZero) {
2508 switch (insn->op) {
2509 case OP_TEX: lodm = 0; break;
2510 case OP_TXB: lodm = 2; break;
2511 case OP_TXL: lodm = 3; break;
2512 default:
2513 assert(!"invalid tex op");
2514 break;
2515 }
2516 } else {
2517 lodm = 1;
2518 }
2519
2520 if (insn->tex.rIndirectSrc >= 0) {
2521 emitInsn (0xdeb80000);
2522 emitField(0x35, 2, lodm);
2523 emitField(0x24, 1, insn->tex.useOffsets == 1);
2524 } else {
2525 emitInsn (0xc0380000);
2526 emitField(0x37, 2, lodm);
2527 emitField(0x36, 1, insn->tex.useOffsets == 1);
2528 emitField(0x24, 13, insn->tex.r);
2529 }
2530
2531 emitField(0x32, 1, insn->tex.target.isShadow());
2532 emitField(0x31, 1, insn->tex.liveOnly);
2533 emitField(0x23, 1, insn->tex.derivAll);
2534 emitField(0x1f, 4, insn->tex.mask);
2535 emitField(0x1d, 2, insn->tex.target.isCube() ? 3 :
2536 insn->tex.target.getDim() - 1);
2537 emitField(0x1c, 1, insn->tex.target.isArray());
2538 emitTEXs (0x14);
2539 emitGPR (0x08, insn->src(0));
2540 emitGPR (0x00, insn->def(0));
2541 }
2542
2543 void
2544 CodeEmitterGM107::emitTLD()
2545 {
2546 const TexInstruction *insn = this->insn->asTex();
2547
2548 if (insn->tex.rIndirectSrc >= 0) {
2549 emitInsn (0xdd380000);
2550 } else {
2551 emitInsn (0xdc380000);
2552 emitField(0x24, 13, insn->tex.r);
2553 }
2554
2555 emitField(0x37, 1, insn->tex.levelZero == 0);
2556 emitField(0x32, 1, insn->tex.target.isMS());
2557 emitField(0x31, 1, insn->tex.liveOnly);
2558 emitField(0x23, 1, insn->tex.useOffsets == 1);
2559 emitField(0x1f, 4, insn->tex.mask);
2560 emitField(0x1d, 2, insn->tex.target.isCube() ? 3 :
2561 insn->tex.target.getDim() - 1);
2562 emitField(0x1c, 1, insn->tex.target.isArray());
2563 emitTEXs (0x14);
2564 emitGPR (0x08, insn->src(0));
2565 emitGPR (0x00, insn->def(0));
2566 }
2567
2568 void
2569 CodeEmitterGM107::emitTLD4()
2570 {
2571 const TexInstruction *insn = this->insn->asTex();
2572
2573 if (insn->tex.rIndirectSrc >= 0) {
2574 emitInsn (0xdef80000);
2575 emitField(0x26, 2, insn->tex.gatherComp);
2576 emitField(0x25, 2, insn->tex.useOffsets == 4);
2577 emitField(0x24, 2, insn->tex.useOffsets == 1);
2578 } else {
2579 emitInsn (0xc8380000);
2580 emitField(0x38, 2, insn->tex.gatherComp);
2581 emitField(0x37, 2, insn->tex.useOffsets == 4);
2582 emitField(0x36, 2, insn->tex.useOffsets == 1);
2583 emitField(0x24, 13, insn->tex.r);
2584 }
2585
2586 emitField(0x32, 1, insn->tex.target.isShadow());
2587 emitField(0x31, 1, insn->tex.liveOnly);
2588 emitField(0x23, 1, insn->tex.derivAll);
2589 emitField(0x1f, 4, insn->tex.mask);
2590 emitField(0x1d, 2, insn->tex.target.isCube() ? 3 :
2591 insn->tex.target.getDim() - 1);
2592 emitField(0x1c, 1, insn->tex.target.isArray());
2593 emitTEXs (0x14);
2594 emitGPR (0x08, insn->src(0));
2595 emitGPR (0x00, insn->def(0));
2596 }
2597
2598 void
2599 CodeEmitterGM107::emitTXD()
2600 {
2601 const TexInstruction *insn = this->insn->asTex();
2602
2603 if (insn->tex.rIndirectSrc >= 0) {
2604 emitInsn (0xde780000);
2605 } else {
2606 emitInsn (0xde380000);
2607 emitField(0x24, 13, insn->tex.r);
2608 }
2609
2610 emitField(0x31, 1, insn->tex.liveOnly);
2611 emitField(0x23, 1, insn->tex.useOffsets == 1);
2612 emitField(0x1f, 4, insn->tex.mask);
2613 emitField(0x1d, 2, insn->tex.target.isCube() ? 3 :
2614 insn->tex.target.getDim() - 1);
2615 emitField(0x1c, 1, insn->tex.target.isArray());
2616 emitTEXs (0x14);
2617 emitGPR (0x08, insn->src(0));
2618 emitGPR (0x00, insn->def(0));
2619 }
2620
2621 void
2622 CodeEmitterGM107::emitTMML()
2623 {
2624 const TexInstruction *insn = this->insn->asTex();
2625
2626 if (insn->tex.rIndirectSrc >= 0) {
2627 emitInsn (0xdf600000);
2628 } else {
2629 emitInsn (0xdf580000);
2630 emitField(0x24, 13, insn->tex.r);
2631 }
2632
2633 emitField(0x31, 1, insn->tex.liveOnly);
2634 emitField(0x23, 1, insn->tex.derivAll);
2635 emitField(0x1f, 4, insn->tex.mask);
2636 emitField(0x1d, 2, insn->tex.target.isCube() ? 3 :
2637 insn->tex.target.getDim() - 1);
2638 emitField(0x1c, 1, insn->tex.target.isArray());
2639 emitTEXs (0x14);
2640 emitGPR (0x08, insn->src(0));
2641 emitGPR (0x00, insn->def(0));
2642 }
2643
2644 void
2645 CodeEmitterGM107::emitTXQ()
2646 {
2647 const TexInstruction *insn = this->insn->asTex();
2648 int type = 0;
2649
2650 switch (insn->tex.query) {
2651 case TXQ_DIMS : type = 0x01; break;
2652 case TXQ_TYPE : type = 0x02; break;
2653 case TXQ_SAMPLE_POSITION: type = 0x05; break;
2654 case TXQ_FILTER : type = 0x10; break;
2655 case TXQ_LOD : type = 0x12; break;
2656 case TXQ_WRAP : type = 0x14; break;
2657 case TXQ_BORDER_COLOUR : type = 0x16; break;
2658 default:
2659 assert(!"invalid txq query");
2660 break;
2661 }
2662
2663 if (insn->tex.rIndirectSrc >= 0) {
2664 emitInsn (0xdf500000);
2665 } else {
2666 emitInsn (0xdf480000);
2667 emitField(0x24, 13, insn->tex.r);
2668 }
2669
2670 emitField(0x31, 1, insn->tex.liveOnly);
2671 emitField(0x1f, 4, insn->tex.mask);
2672 emitField(0x16, 6, type);
2673 emitGPR (0x08, insn->src(0));
2674 emitGPR (0x00, insn->def(0));
2675 }
2676
2677 void
2678 CodeEmitterGM107::emitDEPBAR()
2679 {
2680 emitInsn (0xf0f00000);
2681 emitField(0x1d, 1, 1); /* le */
2682 emitField(0x1a, 3, 5);
2683 emitField(0x14, 6, insn->subOp);
2684 emitField(0x00, 6, insn->subOp);
2685 }
2686
2687 /*******************************************************************************
2688 * misc
2689 ******************************************************************************/
2690
2691 void
2692 CodeEmitterGM107::emitNOP()
2693 {
2694 emitInsn(0x50b00000);
2695 }
2696
2697 void
2698 CodeEmitterGM107::emitKIL()
2699 {
2700 emitInsn (0xe3300000);
2701 emitCond5(0x00, CC_TR);
2702 }
2703
2704 void
2705 CodeEmitterGM107::emitOUT()
2706 {
2707 const int cut = insn->op == OP_RESTART || insn->subOp;
2708 const int emit = insn->op == OP_EMIT;
2709
2710 switch (insn->src(1).getFile()) {
2711 case FILE_GPR:
2712 emitInsn(0xfbe00000);
2713 emitGPR (0x14, insn->src(1));
2714 break;
2715 case FILE_IMMEDIATE:
2716 emitInsn(0xf6e00000);
2717 emitIMMD(0x14, 19, insn->src(1));
2718 break;
2719 case FILE_MEMORY_CONST:
2720 emitInsn(0xebe00000);
2721 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
2722 break;
2723 default:
2724 assert(!"bad src1 file");
2725 break;
2726 }
2727
2728 emitField(0x27, 2, (cut << 1) | emit);
2729 emitGPR (0x08, insn->src(0));
2730 emitGPR (0x00, insn->def(0));
2731 }
2732
2733 void
2734 CodeEmitterGM107::emitBAR()
2735 {
2736 uint8_t subop;
2737
2738 emitInsn (0xf0a80000);
2739
2740 switch (insn->subOp) {
2741 case NV50_IR_SUBOP_BAR_RED_POPC: subop = 0x02; break;
2742 case NV50_IR_SUBOP_BAR_RED_AND: subop = 0x0a; break;
2743 case NV50_IR_SUBOP_BAR_RED_OR: subop = 0x12; break;
2744 case NV50_IR_SUBOP_BAR_ARRIVE: subop = 0x81; break;
2745 default:
2746 subop = 0x80;
2747 assert(insn->subOp == NV50_IR_SUBOP_BAR_SYNC);
2748 break;
2749 }
2750
2751 emitField(0x20, 8, subop);
2752
2753 // barrier id
2754 if (insn->src(0).getFile() == FILE_GPR) {
2755 emitGPR(0x08, insn->src(0));
2756 } else {
2757 ImmediateValue *imm = insn->getSrc(0)->asImm();
2758 assert(imm);
2759 emitField(0x08, 8, imm->reg.data.u32);
2760 emitField(0x2b, 1, 1);
2761 }
2762
2763 // thread count
2764 if (insn->src(1).getFile() == FILE_GPR) {
2765 emitGPR(0x14, insn->src(1));
2766 } else {
2767 ImmediateValue *imm = insn->getSrc(0)->asImm();
2768 assert(imm);
2769 emitField(0x14, 12, imm->reg.data.u32);
2770 emitField(0x2c, 1, 1);
2771 }
2772
2773 if (insn->srcExists(2) && (insn->predSrc != 2)) {
2774 emitPRED (0x27, insn->src(2));
2775 emitField(0x2a, 1, insn->src(2).mod == Modifier(NV50_IR_MOD_NOT));
2776 } else {
2777 emitField(0x27, 3, 7);
2778 }
2779 }
2780
2781 void
2782 CodeEmitterGM107::emitMEMBAR()
2783 {
2784 emitInsn (0xef980000);
2785 emitField(0x08, 2, insn->subOp >> 2);
2786 }
2787
2788 void
2789 CodeEmitterGM107::emitVOTE()
2790 {
2791 assert(insn->src(0).getFile() == FILE_PREDICATE);
2792
2793 int r = -1, p = -1;
2794 for (int i = 0; insn->defExists(i); i++) {
2795 if (insn->def(i).getFile() == FILE_GPR)
2796 r = i;
2797 else if (insn->def(i).getFile() == FILE_PREDICATE)
2798 p = i;
2799 }
2800
2801 emitInsn (0x50d80000);
2802 emitField(0x30, 2, insn->subOp);
2803 if (r >= 0)
2804 emitGPR (0x00, insn->def(r));
2805 else
2806 emitGPR (0x00);
2807 if (p >= 0)
2808 emitPRED (0x2d, insn->def(p));
2809 else
2810 emitPRED (0x2d);
2811 emitField(0x2a, 1, insn->src(0).mod == Modifier(NV50_IR_MOD_NOT));
2812 emitPRED (0x27, insn->src(0));
2813 }
2814
2815 /*******************************************************************************
2816 * assembler front-end
2817 ******************************************************************************/
2818
2819 bool
2820 CodeEmitterGM107::emitInstruction(Instruction *i)
2821 {
2822 const unsigned int size = (writeIssueDelays && !(codeSize & 0x1f)) ? 16 : 8;
2823 bool ret = true;
2824
2825 insn = i;
2826
2827 if (insn->encSize != 8) {
2828 ERROR("skipping undecodable instruction: "); insn->print();
2829 return false;
2830 } else
2831 if (codeSize + size > codeSizeLimit) {
2832 ERROR("code emitter output buffer too small\n");
2833 return false;
2834 }
2835
2836 if (writeIssueDelays) {
2837 int n = ((codeSize & 0x1f) / 8) - 1;
2838 if (n < 0) {
2839 data = code;
2840 data[0] = 0x00000000;
2841 data[1] = 0x00000000;
2842 code += 2;
2843 codeSize += 8;
2844 n++;
2845 }
2846
2847 emitField(data, n * 21, 21, insn->sched);
2848 }
2849
2850 switch (insn->op) {
2851 case OP_EXIT:
2852 emitEXIT();
2853 break;
2854 case OP_BRA:
2855 emitBRA();
2856 break;
2857 case OP_CALL:
2858 emitCAL();
2859 break;
2860 case OP_PRECONT:
2861 emitPCNT();
2862 break;
2863 case OP_CONT:
2864 emitCONT();
2865 break;
2866 case OP_PREBREAK:
2867 emitPBK();
2868 break;
2869 case OP_BREAK:
2870 emitBRK();
2871 break;
2872 case OP_PRERET:
2873 emitPRET();
2874 break;
2875 case OP_RET:
2876 emitRET();
2877 break;
2878 case OP_JOINAT:
2879 emitSSY();
2880 break;
2881 case OP_JOIN:
2882 emitSYNC();
2883 break;
2884 case OP_QUADON:
2885 emitSAM();
2886 break;
2887 case OP_QUADPOP:
2888 emitRAM();
2889 break;
2890 case OP_MOV:
2891 emitMOV();
2892 break;
2893 case OP_RDSV:
2894 emitS2R();
2895 break;
2896 case OP_ABS:
2897 case OP_NEG:
2898 case OP_SAT:
2899 case OP_FLOOR:
2900 case OP_CEIL:
2901 case OP_TRUNC:
2902 case OP_CVT:
2903 if (insn->op == OP_CVT && (insn->def(0).getFile() == FILE_PREDICATE ||
2904 insn->src(0).getFile() == FILE_PREDICATE)) {
2905 emitMOV();
2906 } else if (isFloatType(insn->dType)) {
2907 if (isFloatType(insn->sType))
2908 emitF2F();
2909 else
2910 emitI2F();
2911 } else {
2912 if (isFloatType(insn->sType))
2913 emitF2I();
2914 else
2915 emitI2I();
2916 }
2917 break;
2918 case OP_SHFL:
2919 emitSHFL();
2920 break;
2921 case OP_ADD:
2922 case OP_SUB:
2923 if (isFloatType(insn->dType)) {
2924 if (insn->dType == TYPE_F64)
2925 emitDADD();
2926 else
2927 emitFADD();
2928 } else {
2929 emitIADD();
2930 }
2931 break;
2932 case OP_MUL:
2933 if (isFloatType(insn->dType)) {
2934 if (insn->dType == TYPE_F64)
2935 emitDMUL();
2936 else
2937 emitFMUL();
2938 } else {
2939 emitIMUL();
2940 }
2941 break;
2942 case OP_MAD:
2943 case OP_FMA:
2944 if (isFloatType(insn->dType)) {
2945 if (insn->dType == TYPE_F64)
2946 emitDFMA();
2947 else
2948 emitFFMA();
2949 } else {
2950 emitIMAD();
2951 }
2952 break;
2953 case OP_MIN:
2954 case OP_MAX:
2955 if (isFloatType(insn->dType)) {
2956 if (insn->dType == TYPE_F64)
2957 emitDMNMX();
2958 else
2959 emitFMNMX();
2960 } else {
2961 emitIMNMX();
2962 }
2963 break;
2964 case OP_SHL:
2965 emitSHL();
2966 break;
2967 case OP_SHR:
2968 emitSHR();
2969 break;
2970 case OP_POPCNT:
2971 emitPOPC();
2972 break;
2973 case OP_INSBF:
2974 emitBFI();
2975 break;
2976 case OP_EXTBF:
2977 emitBFE();
2978 break;
2979 case OP_BFIND:
2980 emitFLO();
2981 break;
2982 case OP_SLCT:
2983 if (isFloatType(insn->dType))
2984 emitFCMP();
2985 else
2986 emitICMP();
2987 break;
2988 case OP_SET:
2989 case OP_SET_AND:
2990 case OP_SET_OR:
2991 case OP_SET_XOR:
2992 if (insn->def(0).getFile() != FILE_PREDICATE) {
2993 if (isFloatType(insn->sType))
2994 if (insn->sType == TYPE_F64)
2995 emitDSET();
2996 else
2997 emitFSET();
2998 else
2999 emitISET();
3000 } else {
3001 if (isFloatType(insn->sType))
3002 if (insn->sType == TYPE_F64)
3003 emitDSETP();
3004 else
3005 emitFSETP();
3006 else
3007 emitISETP();
3008 }
3009 break;
3010 case OP_SELP:
3011 emitSEL();
3012 break;
3013 case OP_PRESIN:
3014 case OP_PREEX2:
3015 emitRRO();
3016 break;
3017 case OP_COS:
3018 case OP_SIN:
3019 case OP_EX2:
3020 case OP_LG2:
3021 case OP_RCP:
3022 case OP_RSQ:
3023 emitMUFU();
3024 break;
3025 case OP_AND:
3026 case OP_OR:
3027 case OP_XOR:
3028 emitLOP();
3029 break;
3030 case OP_NOT:
3031 emitNOT();
3032 break;
3033 case OP_LOAD:
3034 switch (insn->src(0).getFile()) {
3035 case FILE_MEMORY_CONST : emitLDC(); break;
3036 case FILE_MEMORY_LOCAL : emitLDL(); break;
3037 case FILE_MEMORY_SHARED: emitLDS(); break;
3038 case FILE_MEMORY_GLOBAL: emitLD(); break;
3039 default:
3040 assert(!"invalid load");
3041 emitNOP();
3042 break;
3043 }
3044 break;
3045 case OP_STORE:
3046 switch (insn->src(0).getFile()) {
3047 case FILE_MEMORY_LOCAL : emitSTL(); break;
3048 case FILE_MEMORY_SHARED: emitSTS(); break;
3049 case FILE_MEMORY_GLOBAL: emitST(); break;
3050 default:
3051 assert(!"invalid store");
3052 emitNOP();
3053 break;
3054 }
3055 break;
3056 case OP_ATOM:
3057 if (insn->src(0).getFile() == FILE_MEMORY_SHARED)
3058 emitATOMS();
3059 else
3060 emitATOM();
3061 break;
3062 case OP_CCTL:
3063 emitCCTL();
3064 break;
3065 case OP_VFETCH:
3066 emitALD();
3067 break;
3068 case OP_EXPORT:
3069 emitAST();
3070 break;
3071 case OP_PFETCH:
3072 emitISBERD();
3073 break;
3074 case OP_AFETCH:
3075 emitAL2P();
3076 break;
3077 case OP_LINTERP:
3078 case OP_PINTERP:
3079 emitIPA();
3080 break;
3081 case OP_PIXLD:
3082 emitPIXLD();
3083 break;
3084 case OP_TEX:
3085 case OP_TXB:
3086 case OP_TXL:
3087 emitTEX();
3088 break;
3089 case OP_TXF:
3090 emitTLD();
3091 break;
3092 case OP_TXG:
3093 emitTLD4();
3094 break;
3095 case OP_TXD:
3096 emitTXD();
3097 break;
3098 case OP_TXQ:
3099 emitTXQ();
3100 break;
3101 case OP_TXLQ:
3102 emitTMML();
3103 break;
3104 case OP_TEXBAR:
3105 emitDEPBAR();
3106 break;
3107 case OP_QUADOP:
3108 emitFSWZADD();
3109 break;
3110 case OP_NOP:
3111 emitNOP();
3112 break;
3113 case OP_DISCARD:
3114 emitKIL();
3115 break;
3116 case OP_EMIT:
3117 case OP_RESTART:
3118 emitOUT();
3119 break;
3120 case OP_BAR:
3121 emitBAR();
3122 break;
3123 case OP_MEMBAR:
3124 emitMEMBAR();
3125 break;
3126 case OP_VOTE:
3127 emitVOTE();
3128 break;
3129 default:
3130 assert(!"invalid opcode");
3131 emitNOP();
3132 ret = false;
3133 break;
3134 }
3135
3136 if (insn->join) {
3137 /*XXX*/
3138 }
3139
3140 code += 2;
3141 codeSize += 8;
3142 return ret;
3143 }
3144
3145 uint32_t
3146 CodeEmitterGM107::getMinEncodingSize(const Instruction *i) const
3147 {
3148 return 8;
3149 }
3150
3151 /*******************************************************************************
3152 * sched data calculator
3153 ******************************************************************************/
3154
3155 class SchedDataCalculatorGM107 : public Pass
3156 {
3157 public:
3158 SchedDataCalculatorGM107(const Target *targ) : targ(targ) {}
3159 private:
3160 const Target *targ;
3161 bool visit(BasicBlock *bb);
3162 };
3163
3164 bool
3165 SchedDataCalculatorGM107::visit(BasicBlock *bb)
3166 {
3167 for (Instruction *insn = bb->getEntry(); insn; insn = insn->next) {
3168 /*XXX*/
3169 insn->sched = 0x7e0;
3170 }
3171
3172 return true;
3173 }
3174
3175 /*******************************************************************************
3176 * main
3177 ******************************************************************************/
3178
3179 void
3180 CodeEmitterGM107::prepareEmission(Function *func)
3181 {
3182 SchedDataCalculatorGM107 sched(targ);
3183 CodeEmitter::prepareEmission(func);
3184 sched.run(func, true, true);
3185 }
3186
3187 static inline uint32_t sizeToBundlesGM107(uint32_t size)
3188 {
3189 return (size + 23) / 24;
3190 }
3191
3192 void
3193 CodeEmitterGM107::prepareEmission(Program *prog)
3194 {
3195 for (ArrayList::Iterator fi = prog->allFuncs.iterator();
3196 !fi.end(); fi.next()) {
3197 Function *func = reinterpret_cast<Function *>(fi.get());
3198 func->binPos = prog->binSize;
3199 prepareEmission(func);
3200
3201 // adjust sizes & positions for schedulding info:
3202 if (prog->getTarget()->hasSWSched) {
3203 uint32_t adjPos = func->binPos;
3204 BasicBlock *bb = NULL;
3205 for (int i = 0; i < func->bbCount; ++i) {
3206 bb = func->bbArray[i];
3207 int32_t adjSize = bb->binSize;
3208 if (adjPos % 32) {
3209 adjSize -= 32 - adjPos % 32;
3210 if (adjSize < 0)
3211 adjSize = 0;
3212 }
3213 adjSize = bb->binSize + sizeToBundlesGM107(adjSize) * 8;
3214 bb->binPos = adjPos;
3215 bb->binSize = adjSize;
3216 adjPos += adjSize;
3217 }
3218 if (bb)
3219 func->binSize = adjPos - func->binPos;
3220 }
3221
3222 prog->binSize += func->binSize;
3223 }
3224 }
3225
3226 CodeEmitterGM107::CodeEmitterGM107(const TargetGM107 *target)
3227 : CodeEmitter(target),
3228 targGM107(target),
3229 writeIssueDelays(target->hasSWSched)
3230 {
3231 code = NULL;
3232 codeSize = codeSizeLimit = 0;
3233 relocInfo = NULL;
3234 }
3235
3236 CodeEmitter *
3237 TargetGM107::createCodeEmitterGM107(Program::Type type)
3238 {
3239 CodeEmitterGM107 *emit = new CodeEmitterGM107(this);
3240 emit->setProgramType(type);
3241 return emit;
3242 }
3243
3244 } // namespace nv50_ir