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