gm107/ir: add carry emission to LOP and IADD
[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 emitX (0x2b);
1558 emitField(0x29, 2, lop);
1559 emitINV (0x28, insn->src(1));
1560 emitINV (0x27, insn->src(0));
1561 } else {
1562 emitInsn (0x04000000);
1563 emitX (0x39);
1564 emitINV (0x38, insn->src(1));
1565 emitINV (0x37, insn->src(0));
1566 emitField(0x35, 2, lop);
1567 emitIMMD (0x14, 32, insn->src(1));
1568 }
1569
1570 emitGPR (0x08, insn->src(0));
1571 emitGPR (0x00, insn->def(0));
1572 }
1573
1574 /* special-case of emitLOP(): lop pass_b dst 0 ~src */
1575 void
1576 CodeEmitterGM107::emitNOT()
1577 {
1578 if (!longIMMD(insn->src(0))) {
1579 switch (insn->src(0).getFile()) {
1580 case FILE_GPR:
1581 emitInsn(0x5c400700);
1582 emitGPR (0x14, insn->src(0));
1583 break;
1584 case FILE_MEMORY_CONST:
1585 emitInsn(0x4c400700);
1586 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
1587 break;
1588 case FILE_IMMEDIATE:
1589 emitInsn(0x38400700);
1590 emitIMMD(0x14, 19, insn->src(0));
1591 break;
1592 default:
1593 assert(!"bad src1 file");
1594 break;
1595 }
1596 emitPRED (0x30);
1597 } else {
1598 emitInsn (0x05600000);
1599 emitIMMD (0x14, 32, insn->src(1));
1600 }
1601
1602 emitGPR(0x08);
1603 emitGPR(0x00, insn->def(0));
1604 }
1605
1606 void
1607 CodeEmitterGM107::emitIADD()
1608 {
1609 if (!longIMMD(insn->src(1))) {
1610 switch (insn->src(1).getFile()) {
1611 case FILE_GPR:
1612 emitInsn(0x5c100000);
1613 emitGPR (0x14, insn->src(1));
1614 break;
1615 case FILE_MEMORY_CONST:
1616 emitInsn(0x4c100000);
1617 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1618 break;
1619 case FILE_IMMEDIATE:
1620 emitInsn(0x38100000);
1621 emitIMMD(0x14, 19, insn->src(1));
1622 break;
1623 default:
1624 assert(!"bad src1 file");
1625 break;
1626 }
1627 emitSAT(0x32);
1628 emitNEG(0x31, insn->src(0));
1629 emitNEG(0x30, insn->src(1));
1630 emitCC (0x2f);
1631 emitX (0x2b);
1632 } else {
1633 emitInsn(0x1c000000);
1634 emitSAT (0x36);
1635 emitX (0x35);
1636 emitCC (0x34);
1637 emitIMMD(0x14, 32, insn->src(1));
1638 }
1639
1640 if (insn->op == OP_SUB)
1641 code[1] ^= 0x00010000;
1642
1643 emitGPR(0x08, insn->src(0));
1644 emitGPR(0x00, insn->def(0));
1645 }
1646
1647 void
1648 CodeEmitterGM107::emitIMUL()
1649 {
1650 if (!longIMMD(insn->src(1))) {
1651 switch (insn->src(1).getFile()) {
1652 case FILE_GPR:
1653 emitInsn(0x5c380000);
1654 emitGPR (0x14, insn->src(1));
1655 break;
1656 case FILE_MEMORY_CONST:
1657 emitInsn(0x4c380000);
1658 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1659 break;
1660 case FILE_IMMEDIATE:
1661 emitInsn(0x38380000);
1662 emitIMMD(0x14, 19, insn->src(1));
1663 break;
1664 default:
1665 assert(!"bad src1 file");
1666 break;
1667 }
1668 emitCC (0x2f);
1669 emitField(0x29, 1, isSignedType(insn->sType));
1670 emitField(0x28, 1, isSignedType(insn->dType));
1671 emitField(0x27, 1, insn->subOp == NV50_IR_SUBOP_MUL_HIGH);
1672 } else {
1673 emitInsn (0x1f000000);
1674 emitField(0x37, 1, isSignedType(insn->sType));
1675 emitField(0x36, 1, isSignedType(insn->dType));
1676 emitField(0x35, 1, insn->subOp == NV50_IR_SUBOP_MUL_HIGH);
1677 emitCC (0x34);
1678 emitIMMD (0x14, 32, insn->src(1));
1679 }
1680
1681 emitGPR(0x08, insn->src(0));
1682 emitGPR(0x00, insn->def(0));
1683 }
1684
1685 void
1686 CodeEmitterGM107::emitIMAD()
1687 {
1688 /*XXX: imad32i exists, but not using it as third src overlaps dst */
1689 switch(insn->src(2).getFile()) {
1690 case FILE_GPR:
1691 switch (insn->src(1).getFile()) {
1692 case FILE_GPR:
1693 emitInsn(0x5a000000);
1694 emitGPR (0x14, insn->src(1));
1695 break;
1696 case FILE_MEMORY_CONST:
1697 emitInsn(0x4a000000);
1698 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1699 break;
1700 case FILE_IMMEDIATE:
1701 emitInsn(0x34000000);
1702 emitIMMD(0x14, 19, insn->src(1));
1703 break;
1704 default:
1705 assert(!"bad src1 file");
1706 break;
1707 }
1708 emitGPR (0x27, insn->src(2));
1709 break;
1710 case FILE_MEMORY_CONST:
1711 emitInsn(0x52000000);
1712 emitGPR (0x27, insn->src(1));
1713 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(2));
1714 break;
1715 default:
1716 assert(!"bad src2 file");
1717 break;
1718 }
1719
1720 emitField(0x36, 1, insn->subOp == NV50_IR_SUBOP_MUL_HIGH);
1721 emitField(0x35, 1, isSignedType(insn->sType));
1722 emitNEG (0x34, insn->src(2));
1723 emitNEG2 (0x33, insn->src(0), insn->src(1));
1724 emitSAT (0x32);
1725 emitX (0x31);
1726 emitField(0x30, 1, isSignedType(insn->dType));
1727 emitCC (0x2f);
1728 emitGPR (0x08, insn->src(0));
1729 emitGPR (0x00, insn->def(0));
1730 }
1731
1732 void
1733 CodeEmitterGM107::emitIMNMX()
1734 {
1735 switch (insn->src(1).getFile()) {
1736 case FILE_GPR:
1737 emitInsn(0x5c200000);
1738 emitGPR (0x14, insn->src(1));
1739 break;
1740 case FILE_MEMORY_CONST:
1741 emitInsn(0x4c200000);
1742 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1743 break;
1744 case FILE_IMMEDIATE:
1745 emitInsn(0x38200000);
1746 emitIMMD(0x14, 19, insn->src(1));
1747 break;
1748 default:
1749 assert(!"bad src1 file");
1750 break;
1751 }
1752
1753 emitField(0x30, 1, isSignedType(insn->dType));
1754 emitCC (0x2f);
1755 emitField(0x2a, 1, insn->op == OP_MAX);
1756 emitPRED (0x27);
1757 emitGPR (0x08, insn->src(0));
1758 emitGPR (0x00, insn->def(0));
1759 }
1760
1761 void
1762 CodeEmitterGM107::emitICMP()
1763 {
1764 const CmpInstruction *insn = this->insn->asCmp();
1765 CondCode cc = insn->setCond;
1766
1767 if (insn->src(2).mod.neg())
1768 cc = reverseCondCode(cc);
1769
1770 switch(insn->src(2).getFile()) {
1771 case FILE_GPR:
1772 switch (insn->src(1).getFile()) {
1773 case FILE_GPR:
1774 emitInsn(0x5b400000);
1775 emitGPR (0x14, insn->src(1));
1776 break;
1777 case FILE_MEMORY_CONST:
1778 emitInsn(0x4b400000);
1779 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1780 break;
1781 case FILE_IMMEDIATE:
1782 emitInsn(0x36400000);
1783 emitIMMD(0x14, 19, insn->src(1));
1784 break;
1785 default:
1786 assert(!"bad src1 file");
1787 break;
1788 }
1789 emitGPR (0x27, insn->src(2));
1790 break;
1791 case FILE_MEMORY_CONST:
1792 emitInsn(0x53400000);
1793 emitGPR (0x27, insn->src(1));
1794 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(2));
1795 break;
1796 default:
1797 assert(!"bad src2 file");
1798 break;
1799 }
1800
1801 emitCond3(0x31, cc);
1802 emitField(0x30, 1, isSignedType(insn->sType));
1803 emitGPR (0x08, insn->src(0));
1804 emitGPR (0x00, insn->def(0));
1805 }
1806
1807 void
1808 CodeEmitterGM107::emitISET()
1809 {
1810 const CmpInstruction *insn = this->insn->asCmp();
1811
1812 switch (insn->src(1).getFile()) {
1813 case FILE_GPR:
1814 emitInsn(0x5b500000);
1815 emitGPR (0x14, insn->src(1));
1816 break;
1817 case FILE_MEMORY_CONST:
1818 emitInsn(0x4b500000);
1819 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1820 break;
1821 case FILE_IMMEDIATE:
1822 emitInsn(0x36500000);
1823 emitIMMD(0x14, 19, insn->src(1));
1824 break;
1825 default:
1826 assert(!"bad src1 file");
1827 break;
1828 }
1829
1830 if (insn->op != OP_SET) {
1831 switch (insn->op) {
1832 case OP_SET_AND: emitField(0x2d, 2, 0); break;
1833 case OP_SET_OR : emitField(0x2d, 2, 1); break;
1834 case OP_SET_XOR: emitField(0x2d, 2, 2); break;
1835 default:
1836 assert(!"invalid set op");
1837 break;
1838 }
1839 emitPRED(0x27, insn->src(2));
1840 } else {
1841 emitPRED(0x27);
1842 }
1843
1844 emitCond3(0x31, insn->setCond);
1845 emitField(0x30, 1, isSignedType(insn->sType));
1846 emitCC (0x2f);
1847 emitField(0x2c, 1, insn->dType == TYPE_F32);
1848 emitX (0x2b);
1849 emitGPR (0x08, insn->src(0));
1850 emitGPR (0x00, insn->def(0));
1851 }
1852
1853 void
1854 CodeEmitterGM107::emitISETP()
1855 {
1856 const CmpInstruction *insn = this->insn->asCmp();
1857
1858 switch (insn->src(1).getFile()) {
1859 case FILE_GPR:
1860 emitInsn(0x5b600000);
1861 emitGPR (0x14, insn->src(1));
1862 break;
1863 case FILE_MEMORY_CONST:
1864 emitInsn(0x4b600000);
1865 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1866 break;
1867 case FILE_IMMEDIATE:
1868 emitInsn(0x36600000);
1869 emitIMMD(0x14, 19, insn->src(1));
1870 break;
1871 default:
1872 assert(!"bad src1 file");
1873 break;
1874 }
1875
1876 if (insn->op != OP_SET) {
1877 switch (insn->op) {
1878 case OP_SET_AND: emitField(0x2d, 2, 0); break;
1879 case OP_SET_OR : emitField(0x2d, 2, 1); break;
1880 case OP_SET_XOR: emitField(0x2d, 2, 2); break;
1881 default:
1882 assert(!"invalid set op");
1883 break;
1884 }
1885 emitPRED(0x27, insn->src(2));
1886 } else {
1887 emitPRED(0x27);
1888 }
1889
1890 emitCond3(0x31, insn->setCond);
1891 emitField(0x30, 1, isSignedType(insn->sType));
1892 emitX (0x2b);
1893 emitGPR (0x08, insn->src(0));
1894 emitPRED (0x03, insn->def(0));
1895 if (insn->defExists(1))
1896 emitPRED(0x00, insn->def(1));
1897 else
1898 emitPRED(0x00);
1899 }
1900
1901 void
1902 CodeEmitterGM107::emitSHL()
1903 {
1904 switch (insn->src(1).getFile()) {
1905 case FILE_GPR:
1906 emitInsn(0x5c480000);
1907 emitGPR (0x14, insn->src(1));
1908 break;
1909 case FILE_MEMORY_CONST:
1910 emitInsn(0x4c480000);
1911 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1912 break;
1913 case FILE_IMMEDIATE:
1914 emitInsn(0x38480000);
1915 emitIMMD(0x14, 19, insn->src(1));
1916 break;
1917 default:
1918 assert(!"bad src1 file");
1919 break;
1920 }
1921
1922 emitCC (0x2f);
1923 emitX (0x2b);
1924 emitField(0x27, 1, insn->subOp == NV50_IR_SUBOP_SHIFT_WRAP);
1925 emitGPR (0x08, insn->src(0));
1926 emitGPR (0x00, insn->def(0));
1927 }
1928
1929 void
1930 CodeEmitterGM107::emitSHR()
1931 {
1932 switch (insn->src(1).getFile()) {
1933 case FILE_GPR:
1934 emitInsn(0x5c280000);
1935 emitGPR (0x14, insn->src(1));
1936 break;
1937 case FILE_MEMORY_CONST:
1938 emitInsn(0x4c280000);
1939 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1940 break;
1941 case FILE_IMMEDIATE:
1942 emitInsn(0x38280000);
1943 emitIMMD(0x14, 19, insn->src(1));
1944 break;
1945 default:
1946 assert(!"bad src1 file");
1947 break;
1948 }
1949
1950 emitField(0x30, 1, isSignedType(insn->dType));
1951 emitCC (0x2f);
1952 emitX (0x2c);
1953 emitField(0x27, 1, insn->subOp == NV50_IR_SUBOP_SHIFT_WRAP);
1954 emitGPR (0x08, insn->src(0));
1955 emitGPR (0x00, insn->def(0));
1956 }
1957
1958 void
1959 CodeEmitterGM107::emitPOPC()
1960 {
1961 switch (insn->src(0).getFile()) {
1962 case FILE_GPR:
1963 emitInsn(0x5c080000);
1964 emitGPR (0x14, insn->src(0));
1965 break;
1966 case FILE_MEMORY_CONST:
1967 emitInsn(0x4c080000);
1968 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
1969 break;
1970 case FILE_IMMEDIATE:
1971 emitInsn(0x38080000);
1972 emitIMMD(0x14, 19, insn->src(0));
1973 break;
1974 default:
1975 assert(!"bad src1 file");
1976 break;
1977 }
1978
1979 emitINV(0x28, insn->src(0));
1980 emitGPR(0x00, insn->def(0));
1981 }
1982
1983 void
1984 CodeEmitterGM107::emitBFI()
1985 {
1986 switch(insn->src(2).getFile()) {
1987 case FILE_GPR:
1988 switch (insn->src(1).getFile()) {
1989 case FILE_GPR:
1990 emitInsn(0x5bf00000);
1991 emitGPR (0x14, insn->src(1));
1992 break;
1993 case FILE_MEMORY_CONST:
1994 emitInsn(0x4bf00000);
1995 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1996 break;
1997 case FILE_IMMEDIATE:
1998 emitInsn(0x36f00000);
1999 emitIMMD(0x14, 19, insn->src(1));
2000 break;
2001 default:
2002 assert(!"bad src1 file");
2003 break;
2004 }
2005 emitGPR (0x27, insn->src(2));
2006 break;
2007 case FILE_MEMORY_CONST:
2008 emitInsn(0x53f00000);
2009 emitGPR (0x27, insn->src(1));
2010 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(2));
2011 break;
2012 default:
2013 assert(!"bad src2 file");
2014 break;
2015 }
2016
2017 emitCC (0x2f);
2018 emitGPR (0x08, insn->src(0));
2019 emitGPR (0x00, insn->def(0));
2020 }
2021
2022 void
2023 CodeEmitterGM107::emitBFE()
2024 {
2025 switch (insn->src(1).getFile()) {
2026 case FILE_GPR:
2027 emitInsn(0x5c000000);
2028 emitGPR (0x14, insn->src(1));
2029 break;
2030 case FILE_MEMORY_CONST:
2031 emitInsn(0x4c000000);
2032 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
2033 break;
2034 case FILE_IMMEDIATE:
2035 emitInsn(0x38000000);
2036 emitIMMD(0x14, 19, insn->src(1));
2037 break;
2038 default:
2039 assert(!"bad src1 file");
2040 break;
2041 }
2042
2043 emitField(0x30, 1, isSignedType(insn->dType));
2044 emitCC (0x2f);
2045 emitField(0x28, 1, insn->subOp == NV50_IR_SUBOP_EXTBF_REV);
2046 emitGPR (0x08, insn->src(0));
2047 emitGPR (0x00, insn->def(0));
2048 }
2049
2050 void
2051 CodeEmitterGM107::emitFLO()
2052 {
2053 switch (insn->src(0).getFile()) {
2054 case FILE_GPR:
2055 emitInsn(0x5c300000);
2056 emitGPR (0x14, insn->src(0));
2057 break;
2058 case FILE_MEMORY_CONST:
2059 emitInsn(0x4c300000);
2060 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
2061 break;
2062 case FILE_IMMEDIATE:
2063 emitInsn(0x38300000);
2064 emitIMMD(0x14, 19, insn->src(0));
2065 break;
2066 default:
2067 assert(!"bad src1 file");
2068 break;
2069 }
2070
2071 emitField(0x30, 1, isSignedType(insn->dType));
2072 emitCC (0x2f);
2073 emitField(0x29, 1, insn->subOp == NV50_IR_SUBOP_BFIND_SAMT);
2074 emitINV (0x28, insn->src(0));
2075 emitGPR (0x00, insn->def(0));
2076 }
2077
2078 /*******************************************************************************
2079 * memory
2080 ******************************************************************************/
2081
2082 void
2083 CodeEmitterGM107::emitLDSTs(int pos, DataType type)
2084 {
2085 int data = 0;
2086
2087 switch (typeSizeof(type)) {
2088 case 1: data = isSignedType(type) ? 1 : 0; break;
2089 case 2: data = isSignedType(type) ? 3 : 2; break;
2090 case 4: data = 4; break;
2091 case 8: data = 5; break;
2092 case 16: data = 6; break;
2093 default:
2094 assert(!"bad type");
2095 break;
2096 }
2097
2098 emitField(pos, 3, data);
2099 }
2100
2101 void
2102 CodeEmitterGM107::emitLDSTc(int pos)
2103 {
2104 int mode = 0;
2105
2106 switch (insn->cache) {
2107 case CACHE_CA: mode = 0; break;
2108 case CACHE_CG: mode = 1; break;
2109 case CACHE_CS: mode = 2; break;
2110 case CACHE_CV: mode = 3; break;
2111 default:
2112 assert(!"invalid caching mode");
2113 break;
2114 }
2115
2116 emitField(pos, 2, mode);
2117 }
2118
2119 void
2120 CodeEmitterGM107::emitLDC()
2121 {
2122 emitInsn (0xef900000);
2123 emitLDSTs(0x30, insn->dType);
2124 emitField(0x2c, 2, insn->subOp);
2125 emitCBUF (0x24, 0x08, 0x14, 16, 0, insn->src(0));
2126 emitGPR (0x00, insn->def(0));
2127 }
2128
2129 void
2130 CodeEmitterGM107::emitLDL()
2131 {
2132 emitInsn (0xef400000);
2133 emitLDSTs(0x30, insn->dType);
2134 emitLDSTc(0x2c);
2135 emitADDR (0x08, 0x14, 24, 0, insn->src(0));
2136 emitGPR (0x00, insn->def(0));
2137 }
2138
2139 void
2140 CodeEmitterGM107::emitLDS()
2141 {
2142 emitInsn (0xef480000);
2143 emitLDSTs(0x30, insn->dType);
2144 emitADDR (0x08, 0x14, 24, 0, insn->src(0));
2145 emitGPR (0x00, insn->def(0));
2146 }
2147
2148 void
2149 CodeEmitterGM107::emitLD()
2150 {
2151 emitInsn (0x80000000);
2152 emitPRED (0x3a);
2153 emitLDSTc(0x38);
2154 emitLDSTs(0x35, insn->dType);
2155 emitField(0x34, 1, insn->src(0).getIndirect(0)->getSize() == 8);
2156 emitADDR (0x08, 0x14, 32, 0, insn->src(0));
2157 emitGPR (0x00, insn->def(0));
2158 }
2159
2160 void
2161 CodeEmitterGM107::emitSTL()
2162 {
2163 emitInsn (0xef500000);
2164 emitLDSTs(0x30, insn->dType);
2165 emitLDSTc(0x2c);
2166 emitADDR (0x08, 0x14, 24, 0, insn->src(0));
2167 emitGPR (0x00, insn->src(1));
2168 }
2169
2170 void
2171 CodeEmitterGM107::emitSTS()
2172 {
2173 emitInsn (0xef580000);
2174 emitLDSTs(0x30, insn->dType);
2175 emitADDR (0x08, 0x14, 24, 0, insn->src(0));
2176 emitGPR (0x00, insn->src(1));
2177 }
2178
2179 void
2180 CodeEmitterGM107::emitST()
2181 {
2182 emitInsn (0xa0000000);
2183 emitPRED (0x3a);
2184 emitLDSTc(0x38);
2185 emitLDSTs(0x35, insn->dType);
2186 emitField(0x34, 1, insn->src(0).getIndirect(0)->getSize() == 8);
2187 emitADDR (0x08, 0x14, 32, 0, insn->src(0));
2188 emitGPR (0x00, insn->src(1));
2189 }
2190
2191 void
2192 CodeEmitterGM107::emitALD()
2193 {
2194 emitInsn (0xefd80000);
2195 emitField(0x2f, 2, (insn->getDef(0)->reg.size / 4) - 1);
2196 emitGPR (0x27, insn->src(0).getIndirect(1));
2197 emitO (0x20);
2198 emitP (0x1f);
2199 emitADDR (0x08, 20, 10, 0, insn->src(0));
2200 emitGPR (0x00, insn->def(0));
2201 }
2202
2203 void
2204 CodeEmitterGM107::emitAST()
2205 {
2206 emitInsn (0xeff00000);
2207 emitField(0x2f, 2, (typeSizeof(insn->dType) / 4) - 1);
2208 emitGPR (0x27, insn->src(0).getIndirect(1));
2209 emitP (0x1f);
2210 emitADDR (0x08, 20, 10, 0, insn->src(0));
2211 emitGPR (0x00, insn->src(1));
2212 }
2213
2214 void
2215 CodeEmitterGM107::emitISBERD()
2216 {
2217 emitInsn(0xefd00000);
2218 emitGPR (0x08, insn->src(0));
2219 emitGPR (0x00, insn->def(0));
2220 }
2221
2222 void
2223 CodeEmitterGM107::emitAL2P()
2224 {
2225 emitInsn (0xefa00000);
2226 emitField(0x2f, 2, (insn->getDef(0)->reg.size / 4) - 1);
2227 emitO (0x20);
2228 emitField(0x14, 11, insn->src(0).get()->reg.data.offset);
2229 emitGPR (0x08, insn->src(0).getIndirect(0));
2230 emitGPR (0x00, insn->def(0));
2231 }
2232
2233 static void
2234 interpApply(const InterpEntry *entry, uint32_t *code,
2235 bool force_persample_interp, bool flatshade)
2236 {
2237 int ipa = entry->ipa;
2238 int reg = entry->reg;
2239 int loc = entry->loc;
2240
2241 if (flatshade &&
2242 (ipa & NV50_IR_INTERP_MODE_MASK) == NV50_IR_INTERP_SC) {
2243 ipa = NV50_IR_INTERP_FLAT;
2244 reg = 0xff;
2245 } else if (force_persample_interp &&
2246 (ipa & NV50_IR_INTERP_SAMPLE_MASK) == NV50_IR_INTERP_DEFAULT &&
2247 (ipa & NV50_IR_INTERP_MODE_MASK) != NV50_IR_INTERP_FLAT) {
2248 ipa |= NV50_IR_INTERP_CENTROID;
2249 }
2250 code[loc + 1] &= ~(0xf << 0x14);
2251 code[loc + 1] |= (ipa & 0x3) << 0x16;
2252 code[loc + 1] |= (ipa & 0xc) << (0x14 - 2);
2253 code[loc + 0] &= ~(0xff << 0x14);
2254 code[loc + 0] |= reg << 0x14;
2255 }
2256
2257 void
2258 CodeEmitterGM107::emitIPA()
2259 {
2260 int ipam = 0, ipas = 0;
2261
2262 switch (insn->getInterpMode()) {
2263 case NV50_IR_INTERP_LINEAR : ipam = 0; break;
2264 case NV50_IR_INTERP_PERSPECTIVE: ipam = 1; break;
2265 case NV50_IR_INTERP_FLAT : ipam = 2; break;
2266 case NV50_IR_INTERP_SC : ipam = 3; break;
2267 default:
2268 assert(!"invalid ipa mode");
2269 break;
2270 }
2271
2272 switch (insn->getSampleMode()) {
2273 case NV50_IR_INTERP_DEFAULT : ipas = 0; break;
2274 case NV50_IR_INTERP_CENTROID: ipas = 1; break;
2275 case NV50_IR_INTERP_OFFSET : ipas = 2; break;
2276 default:
2277 assert(!"invalid ipa sample mode");
2278 break;
2279 }
2280
2281 emitInsn (0xe0000000);
2282 emitField(0x36, 2, ipam);
2283 emitField(0x34, 2, ipas);
2284 emitSAT (0x33);
2285 emitField(0x2f, 3, 7);
2286 emitADDR (0x08, 0x1c, 10, 0, insn->src(0));
2287 if ((code[0] & 0x0000ff00) != 0x0000ff00)
2288 code[1] |= 0x00000040; /* .idx */
2289 emitGPR(0x00, insn->def(0));
2290
2291 if (insn->op == OP_PINTERP) {
2292 emitGPR(0x14, insn->src(1));
2293 if (insn->getSampleMode() == NV50_IR_INTERP_OFFSET)
2294 emitGPR(0x27, insn->src(2));
2295 addInterp(insn->ipa, insn->getSrc(1)->reg.data.id, interpApply);
2296 } else {
2297 if (insn->getSampleMode() == NV50_IR_INTERP_OFFSET)
2298 emitGPR(0x27, insn->src(1));
2299 emitGPR(0x14);
2300 addInterp(insn->ipa, 0xff, interpApply);
2301 }
2302
2303 if (insn->getSampleMode() != NV50_IR_INTERP_OFFSET)
2304 emitGPR(0x27);
2305 }
2306
2307 void
2308 CodeEmitterGM107::emitATOM()
2309 {
2310 unsigned dType, subOp;
2311 switch (insn->dType) {
2312 case TYPE_U32: dType = 0; break;
2313 case TYPE_S32: dType = 1; break;
2314 case TYPE_U64: dType = 2; break;
2315 case TYPE_F32: dType = 3; break;
2316 case TYPE_B128: dType = 4; break;
2317 case TYPE_S64: dType = 5; break;
2318 default: assert(!"unexpected dType"); dType = 0; break;
2319 }
2320 if (insn->subOp == NV50_IR_SUBOP_ATOM_EXCH)
2321 subOp = 8;
2322 else
2323 subOp = insn->subOp;
2324 assert(insn->subOp != NV50_IR_SUBOP_ATOM_CAS); /* XXX */
2325
2326 emitInsn (0xed000000);
2327 emitField(0x34, 4, subOp);
2328 emitField(0x31, 3, dType);
2329 emitField(0x30, 1, insn->src(0).getIndirect(0)->getSize() == 8);
2330 emitGPR (0x14, insn->src(1));
2331 emitADDR (0x08, 0x1c, 20, 0, insn->src(0));
2332 emitGPR (0x00, insn->def(0));
2333 }
2334
2335 void
2336 CodeEmitterGM107::emitCCTL()
2337 {
2338 unsigned width;
2339 if (insn->src(0).getFile() == FILE_MEMORY_GLOBAL) {
2340 emitInsn(0xef600000);
2341 width = 30;
2342 } else {
2343 emitInsn(0xef800000);
2344 width = 22;
2345 }
2346 emitField(0x34, 1, insn->src(0).getIndirect(0)->getSize() == 8);
2347 emitADDR (0x08, 0x16, width, 2, insn->src(0));
2348 emitField(0x00, 4, insn->subOp);
2349 }
2350
2351 /*******************************************************************************
2352 * surface
2353 ******************************************************************************/
2354
2355 void
2356 CodeEmitterGM107::emitPIXLD()
2357 {
2358 emitInsn (0xefe80000);
2359 emitPRED (0x2d);
2360 emitField(0x1f, 3, insn->subOp);
2361 emitGPR (0x08, insn->src(0));
2362 emitGPR (0x00, insn->def(0));
2363 }
2364
2365 /*******************************************************************************
2366 * texture
2367 ******************************************************************************/
2368
2369 void
2370 CodeEmitterGM107::emitTEXs(int pos)
2371 {
2372 int src1 = insn->predSrc == 1 ? 2 : 1;
2373 if (insn->srcExists(src1))
2374 emitGPR(pos, insn->src(src1));
2375 else
2376 emitGPR(pos);
2377 }
2378
2379 void
2380 CodeEmitterGM107::emitTEX()
2381 {
2382 const TexInstruction *insn = this->insn->asTex();
2383 int lodm = 0;
2384
2385 if (!insn->tex.levelZero) {
2386 switch (insn->op) {
2387 case OP_TEX: lodm = 0; break;
2388 case OP_TXB: lodm = 2; break;
2389 case OP_TXL: lodm = 3; break;
2390 default:
2391 assert(!"invalid tex op");
2392 break;
2393 }
2394 } else {
2395 lodm = 1;
2396 }
2397
2398 if (insn->tex.rIndirectSrc >= 0) {
2399 emitInsn (0xdeb80000);
2400 emitField(0x35, 2, lodm);
2401 emitField(0x24, 1, insn->tex.useOffsets == 1);
2402 } else {
2403 emitInsn (0xc0380000);
2404 emitField(0x37, 2, lodm);
2405 emitField(0x36, 1, insn->tex.useOffsets == 1);
2406 emitField(0x24, 13, insn->tex.r);
2407 }
2408
2409 emitField(0x32, 1, insn->tex.target.isShadow());
2410 emitField(0x31, 1, insn->tex.liveOnly);
2411 emitField(0x23, 1, insn->tex.derivAll);
2412 emitField(0x1f, 4, insn->tex.mask);
2413 emitField(0x1d, 2, insn->tex.target.isCube() ? 3 :
2414 insn->tex.target.getDim() - 1);
2415 emitField(0x1c, 1, insn->tex.target.isArray());
2416 emitTEXs (0x14);
2417 emitGPR (0x08, insn->src(0));
2418 emitGPR (0x00, insn->def(0));
2419 }
2420
2421 void
2422 CodeEmitterGM107::emitTLD()
2423 {
2424 const TexInstruction *insn = this->insn->asTex();
2425
2426 if (insn->tex.rIndirectSrc >= 0) {
2427 emitInsn (0xdd380000);
2428 } else {
2429 emitInsn (0xdc380000);
2430 emitField(0x24, 13, insn->tex.r);
2431 }
2432
2433 emitField(0x37, 1, insn->tex.levelZero == 0);
2434 emitField(0x32, 1, insn->tex.target.isMS());
2435 emitField(0x31, 1, insn->tex.liveOnly);
2436 emitField(0x23, 1, insn->tex.useOffsets == 1);
2437 emitField(0x1f, 4, insn->tex.mask);
2438 emitField(0x1d, 2, insn->tex.target.isCube() ? 3 :
2439 insn->tex.target.getDim() - 1);
2440 emitField(0x1c, 1, insn->tex.target.isArray());
2441 emitTEXs (0x14);
2442 emitGPR (0x08, insn->src(0));
2443 emitGPR (0x00, insn->def(0));
2444 }
2445
2446 void
2447 CodeEmitterGM107::emitTLD4()
2448 {
2449 const TexInstruction *insn = this->insn->asTex();
2450
2451 if (insn->tex.rIndirectSrc >= 0) {
2452 emitInsn (0xdef80000);
2453 emitField(0x26, 2, insn->tex.gatherComp);
2454 emitField(0x25, 2, insn->tex.useOffsets == 4);
2455 emitField(0x24, 2, insn->tex.useOffsets == 1);
2456 } else {
2457 emitInsn (0xc8380000);
2458 emitField(0x38, 2, insn->tex.gatherComp);
2459 emitField(0x37, 2, insn->tex.useOffsets == 4);
2460 emitField(0x36, 2, insn->tex.useOffsets == 1);
2461 emitField(0x24, 13, insn->tex.r);
2462 }
2463
2464 emitField(0x32, 1, insn->tex.target.isShadow());
2465 emitField(0x31, 1, insn->tex.liveOnly);
2466 emitField(0x23, 1, insn->tex.derivAll);
2467 emitField(0x1f, 4, insn->tex.mask);
2468 emitField(0x1d, 2, insn->tex.target.isCube() ? 3 :
2469 insn->tex.target.getDim() - 1);
2470 emitField(0x1c, 1, insn->tex.target.isArray());
2471 emitTEXs (0x14);
2472 emitGPR (0x08, insn->src(0));
2473 emitGPR (0x00, insn->def(0));
2474 }
2475
2476 void
2477 CodeEmitterGM107::emitTXD()
2478 {
2479 const TexInstruction *insn = this->insn->asTex();
2480
2481 if (insn->tex.rIndirectSrc >= 0) {
2482 emitInsn (0xde780000);
2483 } else {
2484 emitInsn (0xde380000);
2485 emitField(0x24, 13, insn->tex.r);
2486 }
2487
2488 emitField(0x31, 1, insn->tex.liveOnly);
2489 emitField(0x23, 1, insn->tex.useOffsets == 1);
2490 emitField(0x1f, 4, insn->tex.mask);
2491 emitField(0x1d, 2, insn->tex.target.isCube() ? 3 :
2492 insn->tex.target.getDim() - 1);
2493 emitField(0x1c, 1, insn->tex.target.isArray());
2494 emitTEXs (0x14);
2495 emitGPR (0x08, insn->src(0));
2496 emitGPR (0x00, insn->def(0));
2497 }
2498
2499 void
2500 CodeEmitterGM107::emitTMML()
2501 {
2502 const TexInstruction *insn = this->insn->asTex();
2503
2504 if (insn->tex.rIndirectSrc >= 0) {
2505 emitInsn (0xdf600000);
2506 } else {
2507 emitInsn (0xdf580000);
2508 emitField(0x24, 13, insn->tex.r);
2509 }
2510
2511 emitField(0x31, 1, insn->tex.liveOnly);
2512 emitField(0x23, 1, insn->tex.derivAll);
2513 emitField(0x1f, 4, insn->tex.mask);
2514 emitField(0x1d, 2, insn->tex.target.isCube() ? 3 :
2515 insn->tex.target.getDim() - 1);
2516 emitField(0x1c, 1, insn->tex.target.isArray());
2517 emitTEXs (0x14);
2518 emitGPR (0x08, insn->src(0));
2519 emitGPR (0x00, insn->def(0));
2520 }
2521
2522 void
2523 CodeEmitterGM107::emitTXQ()
2524 {
2525 const TexInstruction *insn = this->insn->asTex();
2526 int type = 0;
2527
2528 switch (insn->tex.query) {
2529 case TXQ_DIMS : type = 0x01; break;
2530 case TXQ_TYPE : type = 0x02; break;
2531 case TXQ_SAMPLE_POSITION: type = 0x05; break;
2532 case TXQ_FILTER : type = 0x10; break;
2533 case TXQ_LOD : type = 0x12; break;
2534 case TXQ_WRAP : type = 0x14; break;
2535 case TXQ_BORDER_COLOUR : type = 0x16; break;
2536 default:
2537 assert(!"invalid txq query");
2538 break;
2539 }
2540
2541 if (insn->tex.rIndirectSrc >= 0) {
2542 emitInsn (0xdf500000);
2543 } else {
2544 emitInsn (0xdf480000);
2545 emitField(0x24, 13, insn->tex.r);
2546 }
2547
2548 emitField(0x31, 1, insn->tex.liveOnly);
2549 emitField(0x1f, 4, insn->tex.mask);
2550 emitField(0x16, 6, type);
2551 emitGPR (0x08, insn->src(0));
2552 emitGPR (0x00, insn->def(0));
2553 }
2554
2555 void
2556 CodeEmitterGM107::emitDEPBAR()
2557 {
2558 emitInsn (0xf0f00000);
2559 emitField(0x1d, 1, 1); /* le */
2560 emitField(0x1a, 3, 5);
2561 emitField(0x14, 6, insn->subOp);
2562 emitField(0x00, 6, insn->subOp);
2563 }
2564
2565 /*******************************************************************************
2566 * misc
2567 ******************************************************************************/
2568
2569 void
2570 CodeEmitterGM107::emitNOP()
2571 {
2572 emitInsn(0x50b00000);
2573 }
2574
2575 void
2576 CodeEmitterGM107::emitKIL()
2577 {
2578 emitInsn (0xe3300000);
2579 emitCond5(0x00, CC_TR);
2580 }
2581
2582 void
2583 CodeEmitterGM107::emitOUT()
2584 {
2585 const int cut = insn->op == OP_RESTART || insn->subOp;
2586 const int emit = insn->op == OP_EMIT;
2587
2588 switch (insn->src(1).getFile()) {
2589 case FILE_GPR:
2590 emitInsn(0xfbe00000);
2591 emitGPR (0x14, insn->src(1));
2592 break;
2593 case FILE_IMMEDIATE:
2594 emitInsn(0xf6e00000);
2595 emitIMMD(0x14, 19, insn->src(1));
2596 break;
2597 case FILE_MEMORY_CONST:
2598 emitInsn(0xebe00000);
2599 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
2600 break;
2601 default:
2602 assert(!"bad src1 file");
2603 break;
2604 }
2605
2606 emitField(0x27, 2, (cut << 1) | emit);
2607 emitGPR (0x08, insn->src(0));
2608 emitGPR (0x00, insn->def(0));
2609 }
2610
2611 /*******************************************************************************
2612 * assembler front-end
2613 ******************************************************************************/
2614
2615 bool
2616 CodeEmitterGM107::emitInstruction(Instruction *i)
2617 {
2618 const unsigned int size = (writeIssueDelays && !(codeSize & 0x1f)) ? 16 : 8;
2619 bool ret = true;
2620
2621 insn = i;
2622
2623 if (insn->encSize != 8) {
2624 ERROR("skipping undecodable instruction: "); insn->print();
2625 return false;
2626 } else
2627 if (codeSize + size > codeSizeLimit) {
2628 ERROR("code emitter output buffer too small\n");
2629 return false;
2630 }
2631
2632 if (writeIssueDelays) {
2633 int n = ((codeSize & 0x1f) / 8) - 1;
2634 if (n < 0) {
2635 data = code;
2636 data[0] = 0x00000000;
2637 data[1] = 0x00000000;
2638 code += 2;
2639 codeSize += 8;
2640 n++;
2641 }
2642
2643 emitField(data, n * 21, 21, insn->sched);
2644 }
2645
2646 switch (insn->op) {
2647 case OP_EXIT:
2648 emitEXIT();
2649 break;
2650 case OP_BRA:
2651 emitBRA();
2652 break;
2653 case OP_CALL:
2654 emitCAL();
2655 break;
2656 case OP_PRECONT:
2657 emitPCNT();
2658 break;
2659 case OP_CONT:
2660 emitCONT();
2661 break;
2662 case OP_PREBREAK:
2663 emitPBK();
2664 break;
2665 case OP_BREAK:
2666 emitBRK();
2667 break;
2668 case OP_PRERET:
2669 emitPRET();
2670 break;
2671 case OP_RET:
2672 emitRET();
2673 break;
2674 case OP_JOINAT:
2675 emitSSY();
2676 break;
2677 case OP_JOIN:
2678 emitSYNC();
2679 break;
2680 case OP_QUADON:
2681 emitSAM();
2682 break;
2683 case OP_QUADPOP:
2684 emitRAM();
2685 break;
2686 case OP_MOV:
2687 if (insn->def(0).getFile() == FILE_GPR &&
2688 insn->src(0).getFile() != FILE_PREDICATE)
2689 emitMOV();
2690 else
2691 assert(!"R2P/P2R");
2692 break;
2693 case OP_RDSV:
2694 emitS2R();
2695 break;
2696 case OP_ABS:
2697 case OP_NEG:
2698 case OP_SAT:
2699 case OP_FLOOR:
2700 case OP_CEIL:
2701 case OP_TRUNC:
2702 case OP_CVT:
2703 if (isFloatType(insn->dType)) {
2704 if (isFloatType(insn->sType))
2705 emitF2F();
2706 else
2707 emitI2F();
2708 } else {
2709 if (isFloatType(insn->sType))
2710 emitF2I();
2711 else
2712 emitI2I();
2713 }
2714 break;
2715 case OP_SHFL:
2716 emitSHFL();
2717 break;
2718 case OP_ADD:
2719 case OP_SUB:
2720 if (isFloatType(insn->dType)) {
2721 if (insn->dType == TYPE_F64)
2722 emitDADD();
2723 else
2724 emitFADD();
2725 } else {
2726 emitIADD();
2727 }
2728 break;
2729 case OP_MUL:
2730 if (isFloatType(insn->dType)) {
2731 if (insn->dType == TYPE_F64)
2732 emitDMUL();
2733 else
2734 emitFMUL();
2735 } else {
2736 emitIMUL();
2737 }
2738 break;
2739 case OP_MAD:
2740 case OP_FMA:
2741 if (isFloatType(insn->dType)) {
2742 if (insn->dType == TYPE_F64)
2743 emitDFMA();
2744 else
2745 emitFFMA();
2746 } else {
2747 emitIMAD();
2748 }
2749 break;
2750 case OP_MIN:
2751 case OP_MAX:
2752 if (isFloatType(insn->dType)) {
2753 if (insn->dType == TYPE_F64)
2754 emitDMNMX();
2755 else
2756 emitFMNMX();
2757 } else {
2758 emitIMNMX();
2759 }
2760 break;
2761 case OP_SHL:
2762 emitSHL();
2763 break;
2764 case OP_SHR:
2765 emitSHR();
2766 break;
2767 case OP_POPCNT:
2768 emitPOPC();
2769 break;
2770 case OP_INSBF:
2771 emitBFI();
2772 break;
2773 case OP_EXTBF:
2774 emitBFE();
2775 break;
2776 case OP_BFIND:
2777 emitFLO();
2778 break;
2779 case OP_SLCT:
2780 if (isFloatType(insn->dType))
2781 emitFCMP();
2782 else
2783 emitICMP();
2784 break;
2785 case OP_SET:
2786 case OP_SET_AND:
2787 case OP_SET_OR:
2788 case OP_SET_XOR:
2789 if (insn->def(0).getFile() != FILE_PREDICATE) {
2790 if (isFloatType(insn->sType))
2791 if (insn->sType == TYPE_F64)
2792 emitDSET();
2793 else
2794 emitFSET();
2795 else
2796 emitISET();
2797 } else {
2798 if (isFloatType(insn->sType))
2799 if (insn->sType == TYPE_F64)
2800 emitDSETP();
2801 else
2802 emitFSETP();
2803 else
2804 emitISETP();
2805 }
2806 break;
2807 case OP_PRESIN:
2808 case OP_PREEX2:
2809 emitRRO();
2810 break;
2811 case OP_COS:
2812 case OP_SIN:
2813 case OP_EX2:
2814 case OP_LG2:
2815 case OP_RCP:
2816 case OP_RSQ:
2817 emitMUFU();
2818 break;
2819 case OP_AND:
2820 case OP_OR:
2821 case OP_XOR:
2822 emitLOP();
2823 break;
2824 case OP_NOT:
2825 emitNOT();
2826 break;
2827 case OP_LOAD:
2828 switch (insn->src(0).getFile()) {
2829 case FILE_MEMORY_CONST : emitLDC(); break;
2830 case FILE_MEMORY_LOCAL : emitLDL(); break;
2831 case FILE_MEMORY_SHARED: emitLDS(); break;
2832 case FILE_MEMORY_GLOBAL: emitLD(); break;
2833 default:
2834 assert(!"invalid load");
2835 emitNOP();
2836 break;
2837 }
2838 break;
2839 case OP_STORE:
2840 switch (insn->src(0).getFile()) {
2841 case FILE_MEMORY_LOCAL : emitSTL(); break;
2842 case FILE_MEMORY_SHARED: emitSTS(); break;
2843 case FILE_MEMORY_GLOBAL: emitST(); break;
2844 default:
2845 assert(!"invalid load");
2846 emitNOP();
2847 break;
2848 }
2849 break;
2850 case OP_ATOM:
2851 emitATOM();
2852 break;
2853 case OP_CCTL:
2854 emitCCTL();
2855 break;
2856 case OP_VFETCH:
2857 emitALD();
2858 break;
2859 case OP_EXPORT:
2860 emitAST();
2861 break;
2862 case OP_PFETCH:
2863 emitISBERD();
2864 break;
2865 case OP_AFETCH:
2866 emitAL2P();
2867 break;
2868 case OP_LINTERP:
2869 case OP_PINTERP:
2870 emitIPA();
2871 break;
2872 case OP_PIXLD:
2873 emitPIXLD();
2874 break;
2875 case OP_TEX:
2876 case OP_TXB:
2877 case OP_TXL:
2878 emitTEX();
2879 break;
2880 case OP_TXF:
2881 emitTLD();
2882 break;
2883 case OP_TXG:
2884 emitTLD4();
2885 break;
2886 case OP_TXD:
2887 emitTXD();
2888 break;
2889 case OP_TXQ:
2890 emitTXQ();
2891 break;
2892 case OP_TXLQ:
2893 emitTMML();
2894 break;
2895 case OP_TEXBAR:
2896 emitDEPBAR();
2897 break;
2898 case OP_QUADOP:
2899 emitFSWZADD();
2900 break;
2901 case OP_NOP:
2902 emitNOP();
2903 break;
2904 case OP_DISCARD:
2905 emitKIL();
2906 break;
2907 case OP_EMIT:
2908 case OP_RESTART:
2909 emitOUT();
2910 break;
2911 default:
2912 assert(!"invalid opcode");
2913 emitNOP();
2914 ret = false;
2915 break;
2916 }
2917
2918 if (insn->join) {
2919 /*XXX*/
2920 }
2921
2922 code += 2;
2923 codeSize += 8;
2924 return ret;
2925 }
2926
2927 uint32_t
2928 CodeEmitterGM107::getMinEncodingSize(const Instruction *i) const
2929 {
2930 return 8;
2931 }
2932
2933 /*******************************************************************************
2934 * sched data calculator
2935 ******************************************************************************/
2936
2937 class SchedDataCalculatorGM107 : public Pass
2938 {
2939 public:
2940 SchedDataCalculatorGM107(const Target *targ) : targ(targ) {}
2941 private:
2942 const Target *targ;
2943 bool visit(BasicBlock *bb);
2944 };
2945
2946 bool
2947 SchedDataCalculatorGM107::visit(BasicBlock *bb)
2948 {
2949 for (Instruction *insn = bb->getEntry(); insn; insn = insn->next) {
2950 /*XXX*/
2951 insn->sched = 0x7e0;
2952 }
2953
2954 return true;
2955 }
2956
2957 /*******************************************************************************
2958 * main
2959 ******************************************************************************/
2960
2961 void
2962 CodeEmitterGM107::prepareEmission(Function *func)
2963 {
2964 SchedDataCalculatorGM107 sched(targ);
2965 CodeEmitter::prepareEmission(func);
2966 sched.run(func, true, true);
2967 }
2968
2969 static inline uint32_t sizeToBundlesGM107(uint32_t size)
2970 {
2971 return (size + 23) / 24;
2972 }
2973
2974 void
2975 CodeEmitterGM107::prepareEmission(Program *prog)
2976 {
2977 for (ArrayList::Iterator fi = prog->allFuncs.iterator();
2978 !fi.end(); fi.next()) {
2979 Function *func = reinterpret_cast<Function *>(fi.get());
2980 func->binPos = prog->binSize;
2981 prepareEmission(func);
2982
2983 // adjust sizes & positions for schedulding info:
2984 if (prog->getTarget()->hasSWSched) {
2985 uint32_t adjPos = func->binPos;
2986 BasicBlock *bb = NULL;
2987 for (int i = 0; i < func->bbCount; ++i) {
2988 bb = func->bbArray[i];
2989 int32_t adjSize = bb->binSize;
2990 if (adjPos % 32) {
2991 adjSize -= 32 - adjPos % 32;
2992 if (adjSize < 0)
2993 adjSize = 0;
2994 }
2995 adjSize = bb->binSize + sizeToBundlesGM107(adjSize) * 8;
2996 bb->binPos = adjPos;
2997 bb->binSize = adjSize;
2998 adjPos += adjSize;
2999 }
3000 if (bb)
3001 func->binSize = adjPos - func->binPos;
3002 }
3003
3004 prog->binSize += func->binSize;
3005 }
3006 }
3007
3008 CodeEmitterGM107::CodeEmitterGM107(const TargetGM107 *target)
3009 : CodeEmitter(target),
3010 targGM107(target),
3011 writeIssueDelays(target->hasSWSched)
3012 {
3013 code = NULL;
3014 codeSize = codeSizeLimit = 0;
3015 relocInfo = NULL;
3016 }
3017
3018 CodeEmitter *
3019 TargetGM107::createCodeEmitterGM107(Program::Type type)
3020 {
3021 CodeEmitterGM107 *emit = new CodeEmitterGM107(this);
3022 emit->setProgramType(type);
3023 return emit;
3024 }
3025
3026 } // namespace nv50_ir