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