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