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