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