nvc0/ir: Properly handle a "split form" of predicate destination
[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 //#define GM107_DEBUG_SCHED_DATA
28
29 namespace nv50_ir {
30
31 class CodeEmitterGM107 : public CodeEmitter
32 {
33 public:
34 CodeEmitterGM107(const TargetGM107 *);
35
36 virtual bool emitInstruction(Instruction *);
37 virtual uint32_t getMinEncodingSize(const Instruction *) const;
38
39 virtual void prepareEmission(Program *);
40 virtual void prepareEmission(Function *);
41
42 inline void setProgramType(Program::Type pType) { progType = pType; }
43
44 private:
45 const TargetGM107 *targGM107;
46
47 Program::Type progType;
48
49 const Instruction *insn;
50 const bool writeIssueDelays;
51 uint32_t *data;
52
53 private:
54 inline void emitField(uint32_t *, int, int, uint32_t);
55 inline void emitField(int b, int s, uint32_t v) { emitField(code, b, s, v); }
56
57 inline void emitInsn(uint32_t, bool);
58 inline void emitInsn(uint32_t o) { emitInsn(o, true); }
59 inline void emitPred();
60 inline void emitGPR(int, const Value *);
61 inline void emitGPR(int pos) {
62 emitGPR(pos, (const Value *)NULL);
63 }
64 inline void emitGPR(int pos, const ValueRef &ref) {
65 emitGPR(pos, ref.get() ? ref.rep() : (const Value *)NULL);
66 }
67 inline void emitGPR(int pos, const ValueRef *ref) {
68 emitGPR(pos, ref ? ref->rep() : (const Value *)NULL);
69 }
70 inline void emitGPR(int pos, const ValueDef &def) {
71 emitGPR(pos, def.get() ? def.rep() : (const Value *)NULL);
72 }
73 inline void emitSYS(int, const Value *);
74 inline void emitSYS(int pos, const ValueRef &ref) {
75 emitSYS(pos, ref.get() ? ref.rep() : (const Value *)NULL);
76 }
77 inline void emitPRED(int, const Value *);
78 inline void emitPRED(int pos) {
79 emitPRED(pos, (const Value *)NULL);
80 }
81 inline void emitPRED(int pos, const ValueRef &ref) {
82 emitPRED(pos, ref.get() ? ref.rep() : (const Value *)NULL);
83 }
84 inline void emitPRED(int pos, const ValueDef &def) {
85 emitPRED(pos, def.get() ? def.rep() : (const Value *)NULL);
86 }
87 inline void emitADDR(int, int, int, int, const ValueRef &);
88 inline void emitCBUF(int, int, int, int, int, const ValueRef &);
89 inline bool longIMMD(const ValueRef &);
90 inline void emitIMMD(int, int, const ValueRef &);
91
92 void emitCond3(int, CondCode);
93 void emitCond4(int, CondCode);
94 void emitCond5(int pos, CondCode cc) { emitCond4(pos, cc); }
95 inline void emitO(int);
96 inline void emitP(int);
97 inline void emitSAT(int);
98 inline void emitCC(int);
99 inline void emitX(int);
100 inline void emitABS(int, const ValueRef &);
101 inline void emitNEG(int, const ValueRef &);
102 inline void emitNEG2(int, const ValueRef &, const ValueRef &);
103 inline void emitFMZ(int, int);
104 inline void emitRND(int, RoundMode, int);
105 inline void emitRND(int pos) {
106 emitRND(pos, insn->rnd, -1);
107 }
108 inline void emitPDIV(int);
109 inline void emitINV(int, const ValueRef &);
110
111 void emitEXIT();
112 void emitBRA();
113 void emitCAL();
114 void emitPCNT();
115 void emitCONT();
116 void emitPBK();
117 void emitBRK();
118 void emitPRET();
119 void emitRET();
120 void emitSSY();
121 void emitSYNC();
122 void emitSAM();
123 void emitRAM();
124
125 void emitMOV();
126 void emitS2R();
127 void emitF2F();
128 void emitF2I();
129 void emitI2F();
130 void emitI2I();
131 void emitSEL();
132 void emitSHFL();
133
134 void emitDADD();
135 void emitDMUL();
136 void emitDFMA();
137 void emitDMNMX();
138 void emitDSET();
139 void emitDSETP();
140
141 void emitFADD();
142 void emitFMUL();
143 void emitFFMA();
144 void emitMUFU();
145 void emitFMNMX();
146 void emitRRO();
147 void emitFCMP();
148 void emitFSET();
149 void emitFSETP();
150 void emitFSWZADD();
151
152 void emitLOP();
153 void emitNOT();
154 void emitIADD();
155 void emitIMUL();
156 void emitIMAD();
157 void emitISCADD();
158 void emitIMNMX();
159 void emitICMP();
160 void emitISET();
161 void emitISETP();
162 void emitSHL();
163 void emitSHR();
164 void emitSHF();
165 void emitPOPC();
166 void emitBFI();
167 void emitBFE();
168 void emitFLO();
169
170 void emitLDSTs(int, DataType);
171 void emitLDSTc(int);
172 void emitLDC();
173 void emitLDL();
174 void emitLDS();
175 void emitLD();
176 void emitSTL();
177 void emitSTS();
178 void emitST();
179 void emitALD();
180 void emitAST();
181 void emitISBERD();
182 void emitAL2P();
183 void emitIPA();
184 void emitATOM();
185 void emitATOMS();
186 void emitRED();
187 void emitCCTL();
188
189 void emitPIXLD();
190
191 void emitTEXs(int);
192 void emitTEX();
193 void emitTLD();
194 void emitTLD4();
195 void emitTXD();
196 void emitTXQ();
197 void emitTMML();
198 void emitDEPBAR();
199
200 void emitNOP();
201 void emitKIL();
202 void emitOUT();
203
204 void emitBAR();
205 void emitMEMBAR();
206
207 void emitVOTE();
208
209 void emitSUTarget();
210 void emitSUHandle(const int s);
211 void emitSUSTx();
212 void emitSULDx();
213 void emitSUREDx();
214 };
215
216 /*******************************************************************************
217 * general instruction layout/fields
218 ******************************************************************************/
219
220 void
221 CodeEmitterGM107::emitField(uint32_t *data, int b, int s, uint32_t v)
222 {
223 if (b >= 0) {
224 uint32_t m = ((1ULL << s) - 1);
225 uint64_t d = (uint64_t)(v & m) << b;
226 assert(!(v & ~m) || (v & ~m) == ~m);
227 data[1] |= d >> 32;
228 data[0] |= d;
229 }
230 }
231
232 void
233 CodeEmitterGM107::emitPred()
234 {
235 if (insn->predSrc >= 0) {
236 emitField(16, 3, insn->getSrc(insn->predSrc)->rep()->reg.data.id);
237 emitField(19, 1, insn->cc == CC_NOT_P);
238 } else {
239 emitField(16, 3, 7);
240 }
241 }
242
243 void
244 CodeEmitterGM107::emitInsn(uint32_t hi, bool pred)
245 {
246 code[0] = 0x00000000;
247 code[1] = hi;
248 if (pred)
249 emitPred();
250 }
251
252 void
253 CodeEmitterGM107::emitGPR(int pos, const Value *val)
254 {
255 emitField(pos, 8, val && !val->inFile(FILE_FLAGS) ?
256 val->reg.data.id : 255);
257 }
258
259 void
260 CodeEmitterGM107::emitSYS(int pos, const Value *val)
261 {
262 int id = val ? val->reg.data.id : -1;
263
264 switch (id) {
265 case SV_LANEID : id = 0x00; break;
266 case SV_VERTEX_COUNT : id = 0x10; break;
267 case SV_INVOCATION_ID : id = 0x11; break;
268 case SV_THREAD_KILL : id = 0x13; break;
269 case SV_INVOCATION_INFO: id = 0x1d; break;
270 case SV_TID : id = 0x21 + val->reg.data.sv.index; break;
271 case SV_CTAID : id = 0x25 + val->reg.data.sv.index; break;
272 case SV_CLOCK : id = 0x50 + val->reg.data.sv.index; break;
273 default:
274 assert(!"invalid system value");
275 id = 0;
276 break;
277 }
278
279 emitField(pos, 8, id);
280 }
281
282 void
283 CodeEmitterGM107::emitPRED(int pos, const Value *val)
284 {
285 emitField(pos, 3, val ? val->reg.data.id : 7);
286 }
287
288 void
289 CodeEmitterGM107::emitADDR(int gpr, int off, int len, int shr,
290 const ValueRef &ref)
291 {
292 const Value *v = ref.get();
293 assert(!(v->reg.data.offset & ((1 << shr) - 1)));
294 if (gpr >= 0)
295 emitGPR(gpr, ref.getIndirect(0));
296 emitField(off, len, v->reg.data.offset >> shr);
297 }
298
299 void
300 CodeEmitterGM107::emitCBUF(int buf, int gpr, int off, int len, int shr,
301 const ValueRef &ref)
302 {
303 const Value *v = ref.get();
304 const Symbol *s = v->asSym();
305
306 assert(!(s->reg.data.offset & ((1 << shr) - 1)));
307
308 emitField(buf, 5, v->reg.fileIndex);
309 if (gpr >= 0)
310 emitGPR(gpr, ref.getIndirect(0));
311 emitField(off, 16, s->reg.data.offset >> shr);
312 }
313
314 bool
315 CodeEmitterGM107::longIMMD(const ValueRef &ref)
316 {
317 if (ref.getFile() == FILE_IMMEDIATE) {
318 const ImmediateValue *imm = ref.get()->asImm();
319 if (isFloatType(insn->sType)) {
320 if ((imm->reg.data.u32 & 0x00000fff) != 0x00000000)
321 return true;
322 } else {
323 if ((imm->reg.data.u32 & 0xfff00000) != 0x00000000 &&
324 (imm->reg.data.u32 & 0xfff00000) != 0xfff00000)
325 return true;
326 }
327 }
328 return false;
329 }
330
331 void
332 CodeEmitterGM107::emitIMMD(int pos, int len, const ValueRef &ref)
333 {
334 const ImmediateValue *imm = ref.get()->asImm();
335 uint32_t val = imm->reg.data.u32;
336
337 if (len == 19) {
338 if (insn->sType == TYPE_F32 || insn->sType == TYPE_F16) {
339 assert(!(val & 0x00000fff));
340 val >>= 12;
341 } else if (insn->sType == TYPE_F64) {
342 assert(!(imm->reg.data.u64 & 0x00000fffffffffffULL));
343 val = imm->reg.data.u64 >> 44;
344 }
345 assert(!(val & 0xfff00000) || (val & 0xfff00000) == 0xfff00000);
346 emitField( 56, 1, (val & 0x80000) >> 19);
347 emitField(pos, len, (val & 0x7ffff));
348 } else {
349 emitField(pos, len, val);
350 }
351 }
352
353 /*******************************************************************************
354 * modifiers
355 ******************************************************************************/
356
357 void
358 CodeEmitterGM107::emitCond3(int pos, CondCode code)
359 {
360 int data = 0;
361
362 switch (code) {
363 case CC_FL : data = 0x00; break;
364 case CC_LTU:
365 case CC_LT : data = 0x01; break;
366 case CC_EQU:
367 case CC_EQ : data = 0x02; break;
368 case CC_LEU:
369 case CC_LE : data = 0x03; break;
370 case CC_GTU:
371 case CC_GT : data = 0x04; break;
372 case CC_NEU:
373 case CC_NE : data = 0x05; break;
374 case CC_GEU:
375 case CC_GE : data = 0x06; break;
376 case CC_TR : data = 0x07; break;
377 default:
378 assert(!"invalid cond3");
379 break;
380 }
381
382 emitField(pos, 3, data);
383 }
384
385 void
386 CodeEmitterGM107::emitCond4(int pos, CondCode code)
387 {
388 int data = 0;
389
390 switch (code) {
391 case CC_FL: data = 0x00; break;
392 case CC_LT: data = 0x01; break;
393 case CC_EQ: data = 0x02; break;
394 case CC_LE: data = 0x03; break;
395 case CC_GT: data = 0x04; break;
396 case CC_NE: data = 0x05; break;
397 case CC_GE: data = 0x06; break;
398 // case CC_NUM: data = 0x07; break;
399 // case CC_NAN: data = 0x08; break;
400 case CC_LTU: data = 0x09; break;
401 case CC_EQU: data = 0x0a; break;
402 case CC_LEU: data = 0x0b; break;
403 case CC_GTU: data = 0x0c; break;
404 case CC_NEU: data = 0x0d; break;
405 case CC_GEU: data = 0x0e; break;
406 case CC_TR: data = 0x0f; break;
407 default:
408 assert(!"invalid cond4");
409 break;
410 }
411
412 emitField(pos, 4, data);
413 }
414
415 void
416 CodeEmitterGM107::emitO(int pos)
417 {
418 emitField(pos, 1, insn->getSrc(0)->reg.file == FILE_SHADER_OUTPUT);
419 }
420
421 void
422 CodeEmitterGM107::emitP(int pos)
423 {
424 emitField(pos, 1, insn->perPatch);
425 }
426
427 void
428 CodeEmitterGM107::emitSAT(int pos)
429 {
430 emitField(pos, 1, insn->saturate);
431 }
432
433 void
434 CodeEmitterGM107::emitCC(int pos)
435 {
436 emitField(pos, 1, insn->flagsDef >= 0);
437 }
438
439 void
440 CodeEmitterGM107::emitX(int pos)
441 {
442 emitField(pos, 1, insn->flagsSrc >= 0);
443 }
444
445 void
446 CodeEmitterGM107::emitABS(int pos, const ValueRef &ref)
447 {
448 emitField(pos, 1, ref.mod.abs());
449 }
450
451 void
452 CodeEmitterGM107::emitNEG(int pos, const ValueRef &ref)
453 {
454 emitField(pos, 1, ref.mod.neg());
455 }
456
457 void
458 CodeEmitterGM107::emitNEG2(int pos, const ValueRef &a, const ValueRef &b)
459 {
460 emitField(pos, 1, a.mod.neg() ^ b.mod.neg());
461 }
462
463 void
464 CodeEmitterGM107::emitFMZ(int pos, int len)
465 {
466 emitField(pos, len, insn->dnz << 1 | insn->ftz);
467 }
468
469 void
470 CodeEmitterGM107::emitRND(int rmp, RoundMode rnd, int rip)
471 {
472 int rm = 0, ri = 0;
473 switch (rnd) {
474 case ROUND_NI: ri = 1;
475 case ROUND_N : rm = 0; break;
476 case ROUND_MI: ri = 1;
477 case ROUND_M : rm = 1; break;
478 case ROUND_PI: ri = 1;
479 case ROUND_P : rm = 2; break;
480 case ROUND_ZI: ri = 1;
481 case ROUND_Z : rm = 3; break;
482 default:
483 assert(!"invalid round mode");
484 break;
485 }
486 emitField(rip, 1, ri);
487 emitField(rmp, 2, rm);
488 }
489
490 void
491 CodeEmitterGM107::emitPDIV(int pos)
492 {
493 assert(insn->postFactor >= -3 && insn->postFactor <= 3);
494 if (insn->postFactor > 0)
495 emitField(pos, 3, 7 - insn->postFactor);
496 else
497 emitField(pos, 3, 0 - insn->postFactor);
498 }
499
500 void
501 CodeEmitterGM107::emitINV(int pos, const ValueRef &ref)
502 {
503 emitField(pos, 1, !!(ref.mod & Modifier(NV50_IR_MOD_NOT)));
504 }
505
506 /*******************************************************************************
507 * control flow
508 ******************************************************************************/
509
510 void
511 CodeEmitterGM107::emitEXIT()
512 {
513 emitInsn (0xe3000000);
514 emitCond5(0x00, CC_TR);
515 }
516
517 void
518 CodeEmitterGM107::emitBRA()
519 {
520 const FlowInstruction *insn = this->insn->asFlow();
521 int gpr = -1;
522
523 if (insn->indirect) {
524 if (insn->absolute)
525 emitInsn(0xe2000000); // JMX
526 else
527 emitInsn(0xe2500000); // BRX
528 gpr = 0x08;
529 } else {
530 if (insn->absolute)
531 emitInsn(0xe2100000); // JMP
532 else
533 emitInsn(0xe2400000); // BRA
534 emitField(0x07, 1, insn->allWarp);
535 }
536
537 emitField(0x06, 1, insn->limit);
538 emitCond5(0x00, CC_TR);
539
540 if (!insn->srcExists(0) || insn->src(0).getFile() != FILE_MEMORY_CONST) {
541 int32_t pos = insn->target.bb->binPos;
542 if (writeIssueDelays && !(pos & 0x1f))
543 pos += 8;
544 if (!insn->absolute)
545 emitField(0x14, 24, pos - (codeSize + 8));
546 else
547 emitField(0x14, 32, pos);
548 } else {
549 emitCBUF (0x24, gpr, 20, 16, 0, insn->src(0));
550 emitField(0x05, 1, 1);
551 }
552 }
553
554 void
555 CodeEmitterGM107::emitCAL()
556 {
557 const FlowInstruction *insn = this->insn->asFlow();
558
559 if (insn->absolute) {
560 emitInsn(0xe2200000, 0); // JCAL
561 } else {
562 emitInsn(0xe2600000, 0); // CAL
563 }
564
565 if (!insn->srcExists(0) || insn->src(0).getFile() != FILE_MEMORY_CONST) {
566 if (!insn->absolute)
567 emitField(0x14, 24, insn->target.bb->binPos - (codeSize + 8));
568 else {
569 if (insn->builtin) {
570 int pcAbs = targGM107->getBuiltinOffset(insn->target.builtin);
571 addReloc(RelocEntry::TYPE_BUILTIN, 0, pcAbs, 0xfff00000, 20);
572 addReloc(RelocEntry::TYPE_BUILTIN, 1, pcAbs, 0x000fffff, -12);
573 } else {
574 emitField(0x14, 32, insn->target.bb->binPos);
575 }
576 }
577 } else {
578 emitCBUF (0x24, -1, 20, 16, 0, insn->src(0));
579 emitField(0x05, 1, 1);
580 }
581 }
582
583 void
584 CodeEmitterGM107::emitPCNT()
585 {
586 const FlowInstruction *insn = this->insn->asFlow();
587
588 emitInsn(0xe2b00000, 0);
589
590 if (!insn->srcExists(0) || insn->src(0).getFile() != FILE_MEMORY_CONST) {
591 emitField(0x14, 24, insn->target.bb->binPos - (codeSize + 8));
592 } else {
593 emitCBUF (0x24, -1, 20, 16, 0, insn->src(0));
594 emitField(0x05, 1, 1);
595 }
596 }
597
598 void
599 CodeEmitterGM107::emitCONT()
600 {
601 emitInsn (0xe3500000);
602 emitCond5(0x00, CC_TR);
603 }
604
605 void
606 CodeEmitterGM107::emitPBK()
607 {
608 const FlowInstruction *insn = this->insn->asFlow();
609
610 emitInsn(0xe2a00000, 0);
611
612 if (!insn->srcExists(0) || insn->src(0).getFile() != FILE_MEMORY_CONST) {
613 emitField(0x14, 24, insn->target.bb->binPos - (codeSize + 8));
614 } else {
615 emitCBUF (0x24, -1, 20, 16, 0, insn->src(0));
616 emitField(0x05, 1, 1);
617 }
618 }
619
620 void
621 CodeEmitterGM107::emitBRK()
622 {
623 emitInsn (0xe3400000);
624 emitCond5(0x00, CC_TR);
625 }
626
627 void
628 CodeEmitterGM107::emitPRET()
629 {
630 const FlowInstruction *insn = this->insn->asFlow();
631
632 emitInsn(0xe2700000, 0);
633
634 if (!insn->srcExists(0) || insn->src(0).getFile() != FILE_MEMORY_CONST) {
635 emitField(0x14, 24, insn->target.bb->binPos - (codeSize + 8));
636 } else {
637 emitCBUF (0x24, -1, 20, 16, 0, insn->src(0));
638 emitField(0x05, 1, 1);
639 }
640 }
641
642 void
643 CodeEmitterGM107::emitRET()
644 {
645 emitInsn (0xe3200000);
646 emitCond5(0x00, CC_TR);
647 }
648
649 void
650 CodeEmitterGM107::emitSSY()
651 {
652 const FlowInstruction *insn = this->insn->asFlow();
653
654 emitInsn(0xe2900000, 0);
655
656 if (!insn->srcExists(0) || insn->src(0).getFile() != FILE_MEMORY_CONST) {
657 emitField(0x14, 24, insn->target.bb->binPos - (codeSize + 8));
658 } else {
659 emitCBUF (0x24, -1, 20, 16, 0, insn->src(0));
660 emitField(0x05, 1, 1);
661 }
662 }
663
664 void
665 CodeEmitterGM107::emitSYNC()
666 {
667 emitInsn (0xf0f80000);
668 emitCond5(0x00, CC_TR);
669 }
670
671 void
672 CodeEmitterGM107::emitSAM()
673 {
674 emitInsn(0xe3700000, 0);
675 }
676
677 void
678 CodeEmitterGM107::emitRAM()
679 {
680 emitInsn(0xe3800000, 0);
681 }
682
683 /*******************************************************************************
684 * predicate/cc
685 ******************************************************************************/
686
687 /*******************************************************************************
688 * movement / conversion
689 ******************************************************************************/
690
691 void
692 CodeEmitterGM107::emitMOV()
693 {
694 if (insn->src(0).getFile() != FILE_IMMEDIATE) {
695 switch (insn->src(0).getFile()) {
696 case FILE_GPR:
697 if (insn->def(0).getFile() == FILE_PREDICATE) {
698 emitInsn(0x5b6a0000);
699 emitGPR (0x08);
700 } else {
701 emitInsn(0x5c980000);
702 }
703 emitGPR (0x14, insn->src(0));
704 break;
705 case FILE_MEMORY_CONST:
706 emitInsn(0x4c980000);
707 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
708 break;
709 case FILE_IMMEDIATE:
710 emitInsn(0x38980000);
711 emitIMMD(0x14, 19, insn->src(0));
712 break;
713 case FILE_PREDICATE:
714 emitInsn(0x50880000);
715 emitPRED(0x0c, insn->src(0));
716 emitPRED(0x1d);
717 emitPRED(0x27);
718 break;
719 default:
720 assert(!"bad src file");
721 break;
722 }
723 if (insn->def(0).getFile() != FILE_PREDICATE &&
724 insn->src(0).getFile() != FILE_PREDICATE)
725 emitField(0x27, 4, insn->lanes);
726 } else {
727 emitInsn (0x01000000);
728 emitIMMD (0x14, 32, insn->src(0));
729 emitField(0x0c, 4, insn->lanes);
730 }
731
732 if (insn->def(0).getFile() == FILE_PREDICATE) {
733 emitPRED(0x27);
734 emitPRED(0x03, insn->def(0));
735 emitPRED(0x00);
736 } else {
737 emitGPR(0x00, insn->def(0));
738 }
739 }
740
741 void
742 CodeEmitterGM107::emitS2R()
743 {
744 emitInsn(0xf0c80000);
745 emitSYS (0x14, insn->src(0));
746 emitGPR (0x00, insn->def(0));
747 }
748
749 void
750 CodeEmitterGM107::emitF2F()
751 {
752 RoundMode rnd = insn->rnd;
753
754 switch (insn->op) {
755 case OP_FLOOR: rnd = ROUND_MI; break;
756 case OP_CEIL : rnd = ROUND_PI; break;
757 case OP_TRUNC: rnd = ROUND_ZI; break;
758 default:
759 break;
760 }
761
762 switch (insn->src(0).getFile()) {
763 case FILE_GPR:
764 emitInsn(0x5ca80000);
765 emitGPR (0x14, insn->src(0));
766 break;
767 case FILE_MEMORY_CONST:
768 emitInsn(0x4ca80000);
769 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
770 break;
771 case FILE_IMMEDIATE:
772 emitInsn(0x38a80000);
773 emitIMMD(0x14, 19, insn->src(0));
774 break;
775 default:
776 assert(!"bad src0 file");
777 break;
778 }
779
780 emitField(0x32, 1, (insn->op == OP_SAT) || insn->saturate);
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 emitField(0x29, 1, insn->subOp);
786 emitRND (0x27, rnd, 0x2a);
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::emitF2I()
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(0x5cb00000);
808 emitGPR (0x14, insn->src(0));
809 break;
810 case FILE_MEMORY_CONST:
811 emitInsn(0x4cb00000);
812 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
813 break;
814 case FILE_IMMEDIATE:
815 emitInsn(0x38b00000);
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 emitFMZ (0x2c, 1);
827 emitRND (0x27, rnd, 0x2a);
828 emitField(0x0c, 1, isSignedType(insn->dType));
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::emitI2F()
836 {
837 RoundMode rnd = insn->rnd;
838
839 switch (insn->op) {
840 case OP_FLOOR: rnd = ROUND_M; break;
841 case OP_CEIL : rnd = ROUND_P; break;
842 case OP_TRUNC: rnd = ROUND_Z; break;
843 default:
844 break;
845 }
846
847 switch (insn->src(0).getFile()) {
848 case FILE_GPR:
849 emitInsn(0x5cb80000);
850 emitGPR (0x14, insn->src(0));
851 break;
852 case FILE_MEMORY_CONST:
853 emitInsn(0x4cb80000);
854 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
855 break;
856 case FILE_IMMEDIATE:
857 emitInsn(0x38b80000);
858 emitIMMD(0x14, 19, insn->src(0));
859 break;
860 default:
861 assert(!"bad src0 file");
862 break;
863 }
864
865 emitField(0x31, 1, (insn->op == OP_ABS) || insn->src(0).mod.abs());
866 emitCC (0x2f);
867 emitField(0x2d, 1, (insn->op == OP_NEG) || insn->src(0).mod.neg());
868 emitField(0x29, 2, insn->subOp);
869 emitRND (0x27, rnd, -1);
870 emitField(0x0d, 1, isSignedType(insn->sType));
871 emitField(0x0a, 2, util_logbase2(typeSizeof(insn->sType)));
872 emitField(0x08, 2, util_logbase2(typeSizeof(insn->dType)));
873 emitGPR (0x00, insn->def(0));
874 }
875
876 void
877 CodeEmitterGM107::emitI2I()
878 {
879 switch (insn->src(0).getFile()) {
880 case FILE_GPR:
881 emitInsn(0x5ce00000);
882 emitGPR (0x14, insn->src(0));
883 break;
884 case FILE_MEMORY_CONST:
885 emitInsn(0x4ce00000);
886 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
887 break;
888 case FILE_IMMEDIATE:
889 emitInsn(0x38e00000);
890 emitIMMD(0x14, 19, insn->src(0));
891 break;
892 default:
893 assert(!"bad src0 file");
894 break;
895 }
896
897 emitSAT (0x32);
898 emitField(0x31, 1, (insn->op == OP_ABS) || insn->src(0).mod.abs());
899 emitCC (0x2f);
900 emitField(0x2d, 1, (insn->op == OP_NEG) || insn->src(0).mod.neg());
901 emitField(0x29, 2, insn->subOp);
902 emitField(0x0d, 1, isSignedType(insn->sType));
903 emitField(0x0c, 1, isSignedType(insn->dType));
904 emitField(0x0a, 2, util_logbase2(typeSizeof(insn->sType)));
905 emitField(0x08, 2, util_logbase2(typeSizeof(insn->dType)));
906 emitGPR (0x00, insn->def(0));
907 }
908
909 static void
910 selpFlip(const FixupEntry *entry, uint32_t *code, const FixupData& data)
911 {
912 int loc = entry->loc;
913 if (data.force_persample_interp)
914 code[loc + 1] |= 1 << 10;
915 else
916 code[loc + 1] &= ~(1 << 10);
917 }
918
919 void
920 CodeEmitterGM107::emitSEL()
921 {
922 switch (insn->src(1).getFile()) {
923 case FILE_GPR:
924 emitInsn(0x5ca00000);
925 emitGPR (0x14, insn->src(1));
926 break;
927 case FILE_MEMORY_CONST:
928 emitInsn(0x4ca00000);
929 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
930 break;
931 case FILE_IMMEDIATE:
932 emitInsn(0x38a00000);
933 emitIMMD(0x14, 19, insn->src(1));
934 break;
935 default:
936 assert(!"bad src1 file");
937 break;
938 }
939
940 emitINV (0x2a, insn->src(2));
941 emitPRED(0x27, insn->src(2));
942 emitGPR (0x08, insn->src(0));
943 emitGPR (0x00, insn->def(0));
944
945 if (insn->subOp == 1) {
946 addInterp(0, 0, selpFlip);
947 }
948 }
949
950 void
951 CodeEmitterGM107::emitSHFL()
952 {
953 int type = 0;
954
955 emitInsn (0xef100000);
956
957 switch (insn->src(1).getFile()) {
958 case FILE_GPR:
959 emitGPR(0x14, insn->src(1));
960 break;
961 case FILE_IMMEDIATE:
962 emitIMMD(0x14, 5, insn->src(1));
963 type |= 1;
964 break;
965 default:
966 assert(!"invalid src1 file");
967 break;
968 }
969
970 switch (insn->src(2).getFile()) {
971 case FILE_GPR:
972 emitGPR(0x27, insn->src(2));
973 break;
974 case FILE_IMMEDIATE:
975 emitIMMD(0x22, 13, insn->src(2));
976 type |= 2;
977 break;
978 default:
979 assert(!"invalid src2 file");
980 break;
981 }
982
983 if (!insn->defExists(1))
984 emitPRED(0x30);
985 else {
986 assert(insn->def(1).getFile() == FILE_PREDICATE);
987 emitPRED(0x30, insn->def(1));
988 }
989
990 emitField(0x1e, 2, insn->subOp);
991 emitField(0x1c, 2, type);
992 emitGPR (0x08, insn->src(0));
993 emitGPR (0x00, insn->def(0));
994 }
995
996 /*******************************************************************************
997 * double
998 ******************************************************************************/
999
1000 void
1001 CodeEmitterGM107::emitDADD()
1002 {
1003 switch (insn->src(1).getFile()) {
1004 case FILE_GPR:
1005 emitInsn(0x5c700000);
1006 emitGPR (0x14, insn->src(1));
1007 break;
1008 case FILE_MEMORY_CONST:
1009 emitInsn(0x4c700000);
1010 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1011 break;
1012 case FILE_IMMEDIATE:
1013 emitInsn(0x38700000);
1014 emitIMMD(0x14, 19, insn->src(1));
1015 break;
1016 default:
1017 assert(!"bad src1 file");
1018 break;
1019 }
1020 emitABS(0x31, insn->src(1));
1021 emitNEG(0x30, insn->src(0));
1022 emitCC (0x2f);
1023 emitABS(0x2e, insn->src(0));
1024 emitNEG(0x2d, insn->src(1));
1025
1026 if (insn->op == OP_SUB)
1027 code[1] ^= 0x00002000;
1028
1029 emitGPR(0x08, insn->src(0));
1030 emitGPR(0x00, insn->def(0));
1031 }
1032
1033 void
1034 CodeEmitterGM107::emitDMUL()
1035 {
1036 switch (insn->src(1).getFile()) {
1037 case FILE_GPR:
1038 emitInsn(0x5c800000);
1039 emitGPR (0x14, insn->src(1));
1040 break;
1041 case FILE_MEMORY_CONST:
1042 emitInsn(0x4c800000);
1043 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1044 break;
1045 case FILE_IMMEDIATE:
1046 emitInsn(0x38800000);
1047 emitIMMD(0x14, 19, insn->src(1));
1048 break;
1049 default:
1050 assert(!"bad src1 file");
1051 break;
1052 }
1053
1054 emitNEG2(0x30, insn->src(0), insn->src(1));
1055 emitCC (0x2f);
1056 emitRND (0x27);
1057 emitGPR (0x08, insn->src(0));
1058 emitGPR (0x00, insn->def(0));
1059 }
1060
1061 void
1062 CodeEmitterGM107::emitDFMA()
1063 {
1064 switch(insn->src(2).getFile()) {
1065 case FILE_GPR:
1066 switch (insn->src(1).getFile()) {
1067 case FILE_GPR:
1068 emitInsn(0x5b700000);
1069 emitGPR (0x14, insn->src(1));
1070 break;
1071 case FILE_MEMORY_CONST:
1072 emitInsn(0x4b700000);
1073 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1074 break;
1075 case FILE_IMMEDIATE:
1076 emitInsn(0x36700000);
1077 emitIMMD(0x14, 19, insn->src(1));
1078 break;
1079 default:
1080 assert(!"bad src1 file");
1081 break;
1082 }
1083 emitGPR (0x27, insn->src(2));
1084 break;
1085 case FILE_MEMORY_CONST:
1086 emitInsn(0x53700000);
1087 emitGPR (0x27, insn->src(1));
1088 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(2));
1089 break;
1090 default:
1091 assert(!"bad src2 file");
1092 break;
1093 }
1094
1095 emitRND (0x32);
1096 emitNEG (0x31, insn->src(2));
1097 emitNEG2(0x30, insn->src(0), insn->src(1));
1098 emitCC (0x2f);
1099 emitGPR (0x08, insn->src(0));
1100 emitGPR (0x00, insn->def(0));
1101 }
1102
1103 void
1104 CodeEmitterGM107::emitDMNMX()
1105 {
1106 switch (insn->src(1).getFile()) {
1107 case FILE_GPR:
1108 emitInsn(0x5c500000);
1109 emitGPR (0x14, insn->src(1));
1110 break;
1111 case FILE_MEMORY_CONST:
1112 emitInsn(0x4c500000);
1113 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1114 break;
1115 case FILE_IMMEDIATE:
1116 emitInsn(0x38500000);
1117 emitIMMD(0x14, 19, insn->src(1));
1118 break;
1119 default:
1120 assert(!"bad src1 file");
1121 break;
1122 }
1123
1124 emitABS (0x31, insn->src(1));
1125 emitNEG (0x30, insn->src(0));
1126 emitCC (0x2f);
1127 emitABS (0x2e, insn->src(0));
1128 emitNEG (0x2d, insn->src(1));
1129 emitField(0x2a, 1, insn->op == OP_MAX);
1130 emitPRED (0x27);
1131 emitGPR (0x08, insn->src(0));
1132 emitGPR (0x00, insn->def(0));
1133 }
1134
1135 void
1136 CodeEmitterGM107::emitDSET()
1137 {
1138 const CmpInstruction *insn = this->insn->asCmp();
1139
1140 switch (insn->src(1).getFile()) {
1141 case FILE_GPR:
1142 emitInsn(0x59000000);
1143 emitGPR (0x14, insn->src(1));
1144 break;
1145 case FILE_MEMORY_CONST:
1146 emitInsn(0x49000000);
1147 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1148 break;
1149 case FILE_IMMEDIATE:
1150 emitInsn(0x32000000);
1151 emitIMMD(0x14, 19, insn->src(1));
1152 break;
1153 default:
1154 assert(!"bad src1 file");
1155 break;
1156 }
1157
1158 if (insn->op != OP_SET) {
1159 switch (insn->op) {
1160 case OP_SET_AND: emitField(0x2d, 2, 0); break;
1161 case OP_SET_OR : emitField(0x2d, 2, 1); break;
1162 case OP_SET_XOR: emitField(0x2d, 2, 2); break;
1163 default:
1164 assert(!"invalid set op");
1165 break;
1166 }
1167 emitPRED(0x27, insn->src(2));
1168 } else {
1169 emitPRED(0x27);
1170 }
1171
1172 emitABS (0x36, insn->src(0));
1173 emitNEG (0x35, insn->src(1));
1174 emitField(0x34, 1, insn->dType == TYPE_F32);
1175 emitCond4(0x30, insn->setCond);
1176 emitCC (0x2f);
1177 emitABS (0x2c, insn->src(1));
1178 emitNEG (0x2b, insn->src(0));
1179 emitGPR (0x08, insn->src(0));
1180 emitGPR (0x00, insn->def(0));
1181 }
1182
1183 void
1184 CodeEmitterGM107::emitDSETP()
1185 {
1186 const CmpInstruction *insn = this->insn->asCmp();
1187
1188 switch (insn->src(1).getFile()) {
1189 case FILE_GPR:
1190 emitInsn(0x5b800000);
1191 emitGPR (0x14, insn->src(1));
1192 break;
1193 case FILE_MEMORY_CONST:
1194 emitInsn(0x4b800000);
1195 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1196 break;
1197 case FILE_IMMEDIATE:
1198 emitInsn(0x36800000);
1199 emitIMMD(0x14, 19, insn->src(1));
1200 break;
1201 default:
1202 assert(!"bad src1 file");
1203 break;
1204 }
1205
1206 if (insn->op != OP_SET) {
1207 switch (insn->op) {
1208 case OP_SET_AND: emitField(0x2d, 2, 0); break;
1209 case OP_SET_OR : emitField(0x2d, 2, 1); break;
1210 case OP_SET_XOR: emitField(0x2d, 2, 2); break;
1211 default:
1212 assert(!"invalid set op");
1213 break;
1214 }
1215 emitPRED(0x27, insn->src(2));
1216 } else {
1217 emitPRED(0x27);
1218 }
1219
1220 emitCond4(0x30, insn->setCond);
1221 emitABS (0x2c, insn->src(1));
1222 emitNEG (0x2b, insn->src(0));
1223 emitGPR (0x08, insn->src(0));
1224 emitABS (0x07, insn->src(0));
1225 emitNEG (0x06, insn->src(1));
1226 emitPRED (0x03, insn->def(0));
1227 if (insn->defExists(1))
1228 emitPRED(0x00, insn->def(1));
1229 else
1230 emitPRED(0x00);
1231 }
1232
1233 /*******************************************************************************
1234 * float
1235 ******************************************************************************/
1236
1237 void
1238 CodeEmitterGM107::emitFADD()
1239 {
1240 if (!longIMMD(insn->src(1))) {
1241 switch (insn->src(1).getFile()) {
1242 case FILE_GPR:
1243 emitInsn(0x5c580000);
1244 emitGPR (0x14, insn->src(1));
1245 break;
1246 case FILE_MEMORY_CONST:
1247 emitInsn(0x4c580000);
1248 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1249 break;
1250 case FILE_IMMEDIATE:
1251 emitInsn(0x38580000);
1252 emitIMMD(0x14, 19, insn->src(1));
1253 break;
1254 default:
1255 assert(!"bad src1 file");
1256 break;
1257 }
1258 emitSAT(0x32);
1259 emitABS(0x31, insn->src(1));
1260 emitNEG(0x30, insn->src(0));
1261 emitCC (0x2f);
1262 emitABS(0x2e, insn->src(0));
1263 emitNEG(0x2d, insn->src(1));
1264 emitFMZ(0x2c, 1);
1265
1266 if (insn->op == OP_SUB)
1267 code[1] ^= 0x00002000;
1268 } else {
1269 emitInsn(0x08000000);
1270 emitABS(0x39, insn->src(1));
1271 emitNEG(0x38, insn->src(0));
1272 emitFMZ(0x37, 1);
1273 emitABS(0x36, insn->src(0));
1274 emitNEG(0x35, insn->src(1));
1275 emitCC (0x34);
1276 emitIMMD(0x14, 32, insn->src(1));
1277
1278 if (insn->op == OP_SUB)
1279 code[1] ^= 0x00080000;
1280 }
1281
1282 emitGPR(0x08, insn->src(0));
1283 emitGPR(0x00, insn->def(0));
1284 }
1285
1286 void
1287 CodeEmitterGM107::emitFMUL()
1288 {
1289 if (!longIMMD(insn->src(1))) {
1290 switch (insn->src(1).getFile()) {
1291 case FILE_GPR:
1292 emitInsn(0x5c680000);
1293 emitGPR (0x14, insn->src(1));
1294 break;
1295 case FILE_MEMORY_CONST:
1296 emitInsn(0x4c680000);
1297 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1298 break;
1299 case FILE_IMMEDIATE:
1300 emitInsn(0x38680000);
1301 emitIMMD(0x14, 19, insn->src(1));
1302 break;
1303 default:
1304 assert(!"bad src1 file");
1305 break;
1306 }
1307 emitSAT (0x32);
1308 emitNEG2(0x30, insn->src(0), insn->src(1));
1309 emitCC (0x2f);
1310 emitFMZ (0x2c, 2);
1311 emitPDIV(0x29);
1312 emitRND (0x27);
1313 } else {
1314 emitInsn(0x1e000000);
1315 emitSAT (0x37);
1316 emitFMZ (0x35, 2);
1317 emitCC (0x34);
1318 emitIMMD(0x14, 32, insn->src(1));
1319 if (insn->src(0).mod.neg() ^ insn->src(1).mod.neg())
1320 code[1] ^= 0x00080000; /* flip immd sign bit */
1321 }
1322
1323 emitGPR(0x08, insn->src(0));
1324 emitGPR(0x00, insn->def(0));
1325 }
1326
1327 void
1328 CodeEmitterGM107::emitFFMA()
1329 {
1330 bool isLongIMMD = false;
1331 switch(insn->src(2).getFile()) {
1332 case FILE_GPR:
1333 switch (insn->src(1).getFile()) {
1334 case FILE_GPR:
1335 emitInsn(0x59800000);
1336 emitGPR (0x14, insn->src(1));
1337 break;
1338 case FILE_MEMORY_CONST:
1339 emitInsn(0x49800000);
1340 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1341 break;
1342 case FILE_IMMEDIATE:
1343 if (longIMMD(insn->getSrc(1))) {
1344 assert(insn->getDef(0)->reg.data.id == insn->getSrc(2)->reg.data.id);
1345 isLongIMMD = true;
1346 emitInsn(0x0c000000);
1347 emitIMMD(0x14, 32, insn->src(1));
1348 } else {
1349 emitInsn(0x32800000);
1350 emitIMMD(0x14, 19, insn->src(1));
1351 }
1352 break;
1353 default:
1354 assert(!"bad src1 file");
1355 break;
1356 }
1357 if (!isLongIMMD)
1358 emitGPR (0x27, insn->src(2));
1359 break;
1360 case FILE_MEMORY_CONST:
1361 emitInsn(0x51800000);
1362 emitGPR (0x27, insn->src(1));
1363 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(2));
1364 break;
1365 default:
1366 assert(!"bad src2 file");
1367 break;
1368 }
1369
1370 if (isLongIMMD) {
1371 emitNEG (0x39, insn->src(2));
1372 emitNEG2(0x38, insn->src(0), insn->src(1));
1373 emitSAT (0x37);
1374 emitCC (0x34);
1375 } else {
1376 emitRND (0x33);
1377 emitSAT (0x32);
1378 emitNEG (0x31, insn->src(2));
1379 emitNEG2(0x30, insn->src(0), insn->src(1));
1380 emitCC (0x2f);
1381 }
1382
1383 emitFMZ(0x35, 2);
1384 emitGPR(0x08, insn->src(0));
1385 emitGPR(0x00, insn->def(0));
1386 }
1387
1388 void
1389 CodeEmitterGM107::emitMUFU()
1390 {
1391 int mufu = 0;
1392
1393 switch (insn->op) {
1394 case OP_COS: mufu = 0; break;
1395 case OP_SIN: mufu = 1; break;
1396 case OP_EX2: mufu = 2; break;
1397 case OP_LG2: mufu = 3; break;
1398 case OP_RCP: mufu = 4 + 2 * insn->subOp; break;
1399 case OP_RSQ: mufu = 5 + 2 * insn->subOp; break;
1400 default:
1401 assert(!"invalid mufu");
1402 break;
1403 }
1404
1405 emitInsn (0x50800000);
1406 emitSAT (0x32);
1407 emitNEG (0x30, insn->src(0));
1408 emitABS (0x2e, insn->src(0));
1409 emitField(0x14, 3, mufu);
1410 emitGPR (0x08, insn->src(0));
1411 emitGPR (0x00, insn->def(0));
1412 }
1413
1414 void
1415 CodeEmitterGM107::emitFMNMX()
1416 {
1417 switch (insn->src(1).getFile()) {
1418 case FILE_GPR:
1419 emitInsn(0x5c600000);
1420 emitGPR (0x14, insn->src(1));
1421 break;
1422 case FILE_MEMORY_CONST:
1423 emitInsn(0x4c600000);
1424 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1425 break;
1426 case FILE_IMMEDIATE:
1427 emitInsn(0x38600000);
1428 emitIMMD(0x14, 19, insn->src(1));
1429 break;
1430 default:
1431 assert(!"bad src1 file");
1432 break;
1433 }
1434
1435 emitField(0x2a, 1, insn->op == OP_MAX);
1436 emitPRED (0x27);
1437
1438 emitABS(0x31, insn->src(1));
1439 emitNEG(0x30, insn->src(0));
1440 emitCC (0x2f);
1441 emitABS(0x2e, insn->src(0));
1442 emitNEG(0x2d, insn->src(1));
1443 emitFMZ(0x2c, 1);
1444 emitGPR(0x08, insn->src(0));
1445 emitGPR(0x00, insn->def(0));
1446 }
1447
1448 void
1449 CodeEmitterGM107::emitRRO()
1450 {
1451 switch (insn->src(0).getFile()) {
1452 case FILE_GPR:
1453 emitInsn(0x5c900000);
1454 emitGPR (0x14, insn->src(0));
1455 break;
1456 case FILE_MEMORY_CONST:
1457 emitInsn(0x4c900000);
1458 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
1459 break;
1460 case FILE_IMMEDIATE:
1461 emitInsn(0x38900000);
1462 emitIMMD(0x14, 19, insn->src(0));
1463 break;
1464 default:
1465 assert(!"bad src file");
1466 break;
1467 }
1468
1469 emitABS (0x31, insn->src(0));
1470 emitNEG (0x2d, insn->src(0));
1471 emitField(0x27, 1, insn->op == OP_PREEX2);
1472 emitGPR (0x00, insn->def(0));
1473 }
1474
1475 void
1476 CodeEmitterGM107::emitFCMP()
1477 {
1478 const CmpInstruction *insn = this->insn->asCmp();
1479 CondCode cc = insn->setCond;
1480
1481 if (insn->src(2).mod.neg())
1482 cc = reverseCondCode(cc);
1483
1484 switch(insn->src(2).getFile()) {
1485 case FILE_GPR:
1486 switch (insn->src(1).getFile()) {
1487 case FILE_GPR:
1488 emitInsn(0x5ba00000);
1489 emitGPR (0x14, insn->src(1));
1490 break;
1491 case FILE_MEMORY_CONST:
1492 emitInsn(0x4ba00000);
1493 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1494 break;
1495 case FILE_IMMEDIATE:
1496 emitInsn(0x36a00000);
1497 emitIMMD(0x14, 19, insn->src(1));
1498 break;
1499 default:
1500 assert(!"bad src1 file");
1501 break;
1502 }
1503 emitGPR (0x27, insn->src(2));
1504 break;
1505 case FILE_MEMORY_CONST:
1506 emitInsn(0x53a00000);
1507 emitGPR (0x27, insn->src(1));
1508 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(2));
1509 break;
1510 default:
1511 assert(!"bad src2 file");
1512 break;
1513 }
1514
1515 emitCond4(0x30, cc);
1516 emitFMZ (0x2f, 1);
1517 emitGPR (0x08, insn->src(0));
1518 emitGPR (0x00, insn->def(0));
1519 }
1520
1521 void
1522 CodeEmitterGM107::emitFSET()
1523 {
1524 const CmpInstruction *insn = this->insn->asCmp();
1525
1526 switch (insn->src(1).getFile()) {
1527 case FILE_GPR:
1528 emitInsn(0x58000000);
1529 emitGPR (0x14, insn->src(1));
1530 break;
1531 case FILE_MEMORY_CONST:
1532 emitInsn(0x48000000);
1533 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1534 break;
1535 case FILE_IMMEDIATE:
1536 emitInsn(0x30000000);
1537 emitIMMD(0x14, 19, insn->src(1));
1538 break;
1539 default:
1540 assert(!"bad src1 file");
1541 break;
1542 }
1543
1544 if (insn->op != OP_SET) {
1545 switch (insn->op) {
1546 case OP_SET_AND: emitField(0x2d, 2, 0); break;
1547 case OP_SET_OR : emitField(0x2d, 2, 1); break;
1548 case OP_SET_XOR: emitField(0x2d, 2, 2); break;
1549 default:
1550 assert(!"invalid set op");
1551 break;
1552 }
1553 emitPRED(0x27, insn->src(2));
1554 } else {
1555 emitPRED(0x27);
1556 }
1557
1558 emitFMZ (0x37, 1);
1559 emitABS (0x36, insn->src(0));
1560 emitNEG (0x35, insn->src(1));
1561 emitField(0x34, 1, insn->dType == TYPE_F32);
1562 emitCond4(0x30, insn->setCond);
1563 emitCC (0x2f);
1564 emitABS (0x2c, insn->src(1));
1565 emitNEG (0x2b, insn->src(0));
1566 emitGPR (0x08, insn->src(0));
1567 emitGPR (0x00, insn->def(0));
1568 }
1569
1570 void
1571 CodeEmitterGM107::emitFSETP()
1572 {
1573 const CmpInstruction *insn = this->insn->asCmp();
1574
1575 switch (insn->src(1).getFile()) {
1576 case FILE_GPR:
1577 emitInsn(0x5bb00000);
1578 emitGPR (0x14, insn->src(1));
1579 break;
1580 case FILE_MEMORY_CONST:
1581 emitInsn(0x4bb00000);
1582 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1583 break;
1584 case FILE_IMMEDIATE:
1585 emitInsn(0x36b00000);
1586 emitIMMD(0x14, 19, insn->src(1));
1587 break;
1588 default:
1589 assert(!"bad src1 file");
1590 break;
1591 }
1592
1593 if (insn->op != OP_SET) {
1594 switch (insn->op) {
1595 case OP_SET_AND: emitField(0x2d, 2, 0); break;
1596 case OP_SET_OR : emitField(0x2d, 2, 1); break;
1597 case OP_SET_XOR: emitField(0x2d, 2, 2); break;
1598 default:
1599 assert(!"invalid set op");
1600 break;
1601 }
1602 emitPRED(0x27, insn->src(2));
1603 } else {
1604 emitPRED(0x27);
1605 }
1606
1607 emitCond4(0x30, insn->setCond);
1608 emitFMZ (0x2f, 1);
1609 emitABS (0x2c, insn->src(1));
1610 emitNEG (0x2b, insn->src(0));
1611 emitGPR (0x08, insn->src(0));
1612 emitABS (0x07, insn->src(0));
1613 emitNEG (0x06, insn->src(1));
1614 emitPRED (0x03, insn->def(0));
1615 if (insn->defExists(1))
1616 emitPRED(0x00, insn->def(1));
1617 else
1618 emitPRED(0x00);
1619 }
1620
1621 void
1622 CodeEmitterGM107::emitFSWZADD()
1623 {
1624 emitInsn (0x50f80000);
1625 emitCC (0x2f);
1626 emitFMZ (0x2c, 1);
1627 emitRND (0x27);
1628 emitField(0x26, 1, insn->lanes); /* abused for .ndv */
1629 emitField(0x1c, 8, insn->subOp);
1630 if (insn->predSrc != 1)
1631 emitGPR (0x14, insn->src(1));
1632 else
1633 emitGPR (0x14);
1634 emitGPR (0x08, insn->src(0));
1635 emitGPR (0x00, insn->def(0));
1636 }
1637
1638 /*******************************************************************************
1639 * integer
1640 ******************************************************************************/
1641
1642 void
1643 CodeEmitterGM107::emitLOP()
1644 {
1645 int lop = 0;
1646
1647 switch (insn->op) {
1648 case OP_AND: lop = 0; break;
1649 case OP_OR : lop = 1; break;
1650 case OP_XOR: lop = 2; break;
1651 default:
1652 assert(!"invalid lop");
1653 break;
1654 }
1655
1656 if (insn->src(1).getFile() != FILE_IMMEDIATE) {
1657 switch (insn->src(1).getFile()) {
1658 case FILE_GPR:
1659 emitInsn(0x5c400000);
1660 emitGPR (0x14, insn->src(1));
1661 break;
1662 case FILE_MEMORY_CONST:
1663 emitInsn(0x4c400000);
1664 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1665 break;
1666 case FILE_IMMEDIATE:
1667 emitInsn(0x38400000);
1668 emitIMMD(0x14, 19, insn->src(1));
1669 break;
1670 default:
1671 assert(!"bad src1 file");
1672 break;
1673 }
1674 emitPRED (0x30);
1675 emitCC (0x2f);
1676 emitX (0x2b);
1677 emitField(0x29, 2, lop);
1678 emitINV (0x28, insn->src(1));
1679 emitINV (0x27, insn->src(0));
1680 } else {
1681 emitInsn (0x04000000);
1682 emitX (0x39);
1683 emitINV (0x38, insn->src(1));
1684 emitINV (0x37, insn->src(0));
1685 emitField(0x35, 2, lop);
1686 emitCC (0x34);
1687 emitIMMD (0x14, 32, insn->src(1));
1688 }
1689
1690 emitGPR (0x08, insn->src(0));
1691 emitGPR (0x00, insn->def(0));
1692 }
1693
1694 /* special-case of emitLOP(): lop pass_b dst 0 ~src */
1695 void
1696 CodeEmitterGM107::emitNOT()
1697 {
1698 if (!longIMMD(insn->src(0))) {
1699 switch (insn->src(0).getFile()) {
1700 case FILE_GPR:
1701 emitInsn(0x5c400700);
1702 emitGPR (0x14, insn->src(0));
1703 break;
1704 case FILE_MEMORY_CONST:
1705 emitInsn(0x4c400700);
1706 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
1707 break;
1708 case FILE_IMMEDIATE:
1709 emitInsn(0x38400700);
1710 emitIMMD(0x14, 19, insn->src(0));
1711 break;
1712 default:
1713 assert(!"bad src1 file");
1714 break;
1715 }
1716 emitPRED (0x30);
1717 } else {
1718 emitInsn (0x05600000);
1719 emitIMMD (0x14, 32, insn->src(1));
1720 }
1721
1722 emitGPR(0x08);
1723 emitGPR(0x00, insn->def(0));
1724 }
1725
1726 void
1727 CodeEmitterGM107::emitIADD()
1728 {
1729 if (insn->src(1).getFile() != FILE_IMMEDIATE) {
1730 switch (insn->src(1).getFile()) {
1731 case FILE_GPR:
1732 emitInsn(0x5c100000);
1733 emitGPR (0x14, insn->src(1));
1734 break;
1735 case FILE_MEMORY_CONST:
1736 emitInsn(0x4c100000);
1737 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1738 break;
1739 case FILE_IMMEDIATE:
1740 emitInsn(0x38100000);
1741 emitIMMD(0x14, 19, insn->src(1));
1742 break;
1743 default:
1744 assert(!"bad src1 file");
1745 break;
1746 }
1747 emitSAT(0x32);
1748 emitNEG(0x31, insn->src(0));
1749 emitNEG(0x30, insn->src(1));
1750 emitCC (0x2f);
1751 emitX (0x2b);
1752 } else {
1753 emitInsn(0x1c000000);
1754 emitNEG (0x38, insn->src(0));
1755 emitSAT (0x36);
1756 emitX (0x35);
1757 emitCC (0x34);
1758 emitIMMD(0x14, 32, insn->src(1));
1759 }
1760
1761 if (insn->op == OP_SUB)
1762 code[1] ^= 0x00010000;
1763
1764 emitGPR(0x08, insn->src(0));
1765 emitGPR(0x00, insn->def(0));
1766 }
1767
1768 void
1769 CodeEmitterGM107::emitIMUL()
1770 {
1771 if (insn->src(1).getFile() != FILE_IMMEDIATE) {
1772 switch (insn->src(1).getFile()) {
1773 case FILE_GPR:
1774 emitInsn(0x5c380000);
1775 emitGPR (0x14, insn->src(1));
1776 break;
1777 case FILE_MEMORY_CONST:
1778 emitInsn(0x4c380000);
1779 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1780 break;
1781 case FILE_IMMEDIATE:
1782 emitInsn(0x38380000);
1783 emitIMMD(0x14, 19, insn->src(1));
1784 break;
1785 default:
1786 assert(!"bad src1 file");
1787 break;
1788 }
1789 emitCC (0x2f);
1790 emitField(0x29, 1, isSignedType(insn->sType));
1791 emitField(0x28, 1, isSignedType(insn->dType));
1792 emitField(0x27, 1, insn->subOp == NV50_IR_SUBOP_MUL_HIGH);
1793 } else {
1794 emitInsn (0x1f000000);
1795 emitField(0x37, 1, isSignedType(insn->sType));
1796 emitField(0x36, 1, isSignedType(insn->dType));
1797 emitField(0x35, 1, insn->subOp == NV50_IR_SUBOP_MUL_HIGH);
1798 emitCC (0x34);
1799 emitIMMD (0x14, 32, insn->src(1));
1800 }
1801
1802 emitGPR(0x08, insn->src(0));
1803 emitGPR(0x00, insn->def(0));
1804 }
1805
1806 void
1807 CodeEmitterGM107::emitIMAD()
1808 {
1809 /*XXX: imad32i exists, but not using it as third src overlaps dst */
1810 switch(insn->src(2).getFile()) {
1811 case FILE_GPR:
1812 switch (insn->src(1).getFile()) {
1813 case FILE_GPR:
1814 emitInsn(0x5a000000);
1815 emitGPR (0x14, insn->src(1));
1816 break;
1817 case FILE_MEMORY_CONST:
1818 emitInsn(0x4a000000);
1819 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1820 break;
1821 case FILE_IMMEDIATE:
1822 emitInsn(0x34000000);
1823 emitIMMD(0x14, 19, insn->src(1));
1824 break;
1825 default:
1826 assert(!"bad src1 file");
1827 break;
1828 }
1829 emitGPR (0x27, insn->src(2));
1830 break;
1831 case FILE_MEMORY_CONST:
1832 emitInsn(0x52000000);
1833 emitGPR (0x27, insn->src(1));
1834 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(2));
1835 break;
1836 default:
1837 assert(!"bad src2 file");
1838 break;
1839 }
1840
1841 emitField(0x36, 1, insn->subOp == NV50_IR_SUBOP_MUL_HIGH);
1842 emitField(0x35, 1, isSignedType(insn->sType));
1843 emitNEG (0x34, insn->src(2));
1844 emitNEG2 (0x33, insn->src(0), insn->src(1));
1845 emitSAT (0x32);
1846 emitX (0x31);
1847 emitField(0x30, 1, isSignedType(insn->dType));
1848 emitCC (0x2f);
1849 emitGPR (0x08, insn->src(0));
1850 emitGPR (0x00, insn->def(0));
1851 }
1852
1853 void
1854 CodeEmitterGM107::emitISCADD()
1855 {
1856 switch (insn->src(2).getFile()) {
1857 case FILE_GPR:
1858 emitInsn(0x5c180000);
1859 emitGPR (0x14, insn->src(2));
1860 break;
1861 case FILE_MEMORY_CONST:
1862 emitInsn(0x4c180000);
1863 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(2));
1864 break;
1865 case FILE_IMMEDIATE:
1866 emitInsn(0x38180000);
1867 emitIMMD(0x14, 19, insn->src(2));
1868 break;
1869 default:
1870 assert(!"bad src1 file");
1871 break;
1872 }
1873 emitNEG (0x31, insn->src(0));
1874 emitNEG (0x30, insn->src(2));
1875 emitCC (0x2f);
1876 emitIMMD(0x27, 5, insn->src(1));
1877 emitGPR (0x08, insn->src(0));
1878 emitGPR (0x00, insn->def(0));
1879 }
1880
1881 void
1882 CodeEmitterGM107::emitIMNMX()
1883 {
1884 switch (insn->src(1).getFile()) {
1885 case FILE_GPR:
1886 emitInsn(0x5c200000);
1887 emitGPR (0x14, insn->src(1));
1888 break;
1889 case FILE_MEMORY_CONST:
1890 emitInsn(0x4c200000);
1891 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1892 break;
1893 case FILE_IMMEDIATE:
1894 emitInsn(0x38200000);
1895 emitIMMD(0x14, 19, insn->src(1));
1896 break;
1897 default:
1898 assert(!"bad src1 file");
1899 break;
1900 }
1901
1902 emitField(0x30, 1, isSignedType(insn->dType));
1903 emitCC (0x2f);
1904 emitField(0x2b, 2, insn->subOp);
1905 emitField(0x2a, 1, insn->op == OP_MAX);
1906 emitPRED (0x27);
1907 emitGPR (0x08, insn->src(0));
1908 emitGPR (0x00, insn->def(0));
1909 }
1910
1911 void
1912 CodeEmitterGM107::emitICMP()
1913 {
1914 const CmpInstruction *insn = this->insn->asCmp();
1915 CondCode cc = insn->setCond;
1916
1917 if (insn->src(2).mod.neg())
1918 cc = reverseCondCode(cc);
1919
1920 switch(insn->src(2).getFile()) {
1921 case FILE_GPR:
1922 switch (insn->src(1).getFile()) {
1923 case FILE_GPR:
1924 emitInsn(0x5b400000);
1925 emitGPR (0x14, insn->src(1));
1926 break;
1927 case FILE_MEMORY_CONST:
1928 emitInsn(0x4b400000);
1929 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1930 break;
1931 case FILE_IMMEDIATE:
1932 emitInsn(0x36400000);
1933 emitIMMD(0x14, 19, insn->src(1));
1934 break;
1935 default:
1936 assert(!"bad src1 file");
1937 break;
1938 }
1939 emitGPR (0x27, insn->src(2));
1940 break;
1941 case FILE_MEMORY_CONST:
1942 emitInsn(0x53400000);
1943 emitGPR (0x27, insn->src(1));
1944 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(2));
1945 break;
1946 default:
1947 assert(!"bad src2 file");
1948 break;
1949 }
1950
1951 emitCond3(0x31, cc);
1952 emitField(0x30, 1, isSignedType(insn->sType));
1953 emitGPR (0x08, insn->src(0));
1954 emitGPR (0x00, insn->def(0));
1955 }
1956
1957 void
1958 CodeEmitterGM107::emitISET()
1959 {
1960 const CmpInstruction *insn = this->insn->asCmp();
1961
1962 switch (insn->src(1).getFile()) {
1963 case FILE_GPR:
1964 emitInsn(0x5b500000);
1965 emitGPR (0x14, insn->src(1));
1966 break;
1967 case FILE_MEMORY_CONST:
1968 emitInsn(0x4b500000);
1969 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1970 break;
1971 case FILE_IMMEDIATE:
1972 emitInsn(0x36500000);
1973 emitIMMD(0x14, 19, insn->src(1));
1974 break;
1975 default:
1976 assert(!"bad src1 file");
1977 break;
1978 }
1979
1980 if (insn->op != OP_SET) {
1981 switch (insn->op) {
1982 case OP_SET_AND: emitField(0x2d, 2, 0); break;
1983 case OP_SET_OR : emitField(0x2d, 2, 1); break;
1984 case OP_SET_XOR: emitField(0x2d, 2, 2); break;
1985 default:
1986 assert(!"invalid set op");
1987 break;
1988 }
1989 emitPRED(0x27, insn->src(2));
1990 } else {
1991 emitPRED(0x27);
1992 }
1993
1994 emitCond3(0x31, insn->setCond);
1995 emitField(0x30, 1, isSignedType(insn->sType));
1996 emitCC (0x2f);
1997 emitField(0x2c, 1, insn->dType == TYPE_F32);
1998 emitX (0x2b);
1999 emitGPR (0x08, insn->src(0));
2000 emitGPR (0x00, insn->def(0));
2001 }
2002
2003 void
2004 CodeEmitterGM107::emitISETP()
2005 {
2006 const CmpInstruction *insn = this->insn->asCmp();
2007
2008 switch (insn->src(1).getFile()) {
2009 case FILE_GPR:
2010 emitInsn(0x5b600000);
2011 emitGPR (0x14, insn->src(1));
2012 break;
2013 case FILE_MEMORY_CONST:
2014 emitInsn(0x4b600000);
2015 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
2016 break;
2017 case FILE_IMMEDIATE:
2018 emitInsn(0x36600000);
2019 emitIMMD(0x14, 19, insn->src(1));
2020 break;
2021 default:
2022 assert(!"bad src1 file");
2023 break;
2024 }
2025
2026 if (insn->op != OP_SET) {
2027 switch (insn->op) {
2028 case OP_SET_AND: emitField(0x2d, 2, 0); break;
2029 case OP_SET_OR : emitField(0x2d, 2, 1); break;
2030 case OP_SET_XOR: emitField(0x2d, 2, 2); break;
2031 default:
2032 assert(!"invalid set op");
2033 break;
2034 }
2035 emitPRED(0x27, insn->src(2));
2036 } else {
2037 emitPRED(0x27);
2038 }
2039
2040 emitCond3(0x31, insn->setCond);
2041 emitField(0x30, 1, isSignedType(insn->sType));
2042 emitX (0x2b);
2043 emitGPR (0x08, insn->src(0));
2044 emitPRED (0x03, insn->def(0));
2045 if (insn->defExists(1))
2046 emitPRED(0x00, insn->def(1));
2047 else
2048 emitPRED(0x00);
2049 }
2050
2051 void
2052 CodeEmitterGM107::emitSHL()
2053 {
2054 switch (insn->src(1).getFile()) {
2055 case FILE_GPR:
2056 emitInsn(0x5c480000);
2057 emitGPR (0x14, insn->src(1));
2058 break;
2059 case FILE_MEMORY_CONST:
2060 emitInsn(0x4c480000);
2061 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
2062 break;
2063 case FILE_IMMEDIATE:
2064 emitInsn(0x38480000);
2065 emitIMMD(0x14, 19, insn->src(1));
2066 break;
2067 default:
2068 assert(!"bad src1 file");
2069 break;
2070 }
2071
2072 emitCC (0x2f);
2073 emitX (0x2b);
2074 emitField(0x27, 1, insn->subOp == NV50_IR_SUBOP_SHIFT_WRAP);
2075 emitGPR (0x08, insn->src(0));
2076 emitGPR (0x00, insn->def(0));
2077 }
2078
2079 void
2080 CodeEmitterGM107::emitSHR()
2081 {
2082 switch (insn->src(1).getFile()) {
2083 case FILE_GPR:
2084 emitInsn(0x5c280000);
2085 emitGPR (0x14, insn->src(1));
2086 break;
2087 case FILE_MEMORY_CONST:
2088 emitInsn(0x4c280000);
2089 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
2090 break;
2091 case FILE_IMMEDIATE:
2092 emitInsn(0x38280000);
2093 emitIMMD(0x14, 19, insn->src(1));
2094 break;
2095 default:
2096 assert(!"bad src1 file");
2097 break;
2098 }
2099
2100 emitField(0x30, 1, isSignedType(insn->dType));
2101 emitCC (0x2f);
2102 emitX (0x2c);
2103 emitField(0x27, 1, insn->subOp == NV50_IR_SUBOP_SHIFT_WRAP);
2104 emitGPR (0x08, insn->src(0));
2105 emitGPR (0x00, insn->def(0));
2106 }
2107
2108 void
2109 CodeEmitterGM107::emitSHF()
2110 {
2111 unsigned type;
2112
2113 switch (insn->src(1).getFile()) {
2114 case FILE_GPR:
2115 emitInsn(insn->op == OP_SHL ? 0x5bf80000 : 0x5cf80000);
2116 emitGPR(0x14, insn->src(1));
2117 break;
2118 case FILE_IMMEDIATE:
2119 emitInsn(insn->op == OP_SHL ? 0x36f80000 : 0x38f80000);
2120 emitIMMD(0x14, 19, insn->src(1));
2121 break;
2122 default:
2123 assert(!"bad src1 file");
2124 break;
2125 }
2126
2127 switch (insn->sType) {
2128 case TYPE_U64:
2129 type = 2;
2130 break;
2131 case TYPE_S64:
2132 type = 3;
2133 break;
2134 default:
2135 type = 0;
2136 break;
2137 }
2138
2139 emitField(0x32, 1, !!(insn->subOp & NV50_IR_SUBOP_SHIFT_WRAP));
2140 emitX (0x31);
2141 emitField(0x30, 1, !!(insn->subOp & NV50_IR_SUBOP_SHIFT_HIGH));
2142 emitCC (0x2f);
2143 emitGPR (0x27, insn->src(2));
2144 emitField(0x25, 2, type);
2145 emitGPR (0x08, insn->src(0));
2146 emitGPR (0x00, insn->def(0));
2147 }
2148
2149 void
2150 CodeEmitterGM107::emitPOPC()
2151 {
2152 switch (insn->src(0).getFile()) {
2153 case FILE_GPR:
2154 emitInsn(0x5c080000);
2155 emitGPR (0x14, insn->src(0));
2156 break;
2157 case FILE_MEMORY_CONST:
2158 emitInsn(0x4c080000);
2159 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
2160 break;
2161 case FILE_IMMEDIATE:
2162 emitInsn(0x38080000);
2163 emitIMMD(0x14, 19, insn->src(0));
2164 break;
2165 default:
2166 assert(!"bad src1 file");
2167 break;
2168 }
2169
2170 emitINV(0x28, insn->src(0));
2171 emitGPR(0x00, insn->def(0));
2172 }
2173
2174 void
2175 CodeEmitterGM107::emitBFI()
2176 {
2177 switch(insn->src(2).getFile()) {
2178 case FILE_GPR:
2179 switch (insn->src(1).getFile()) {
2180 case FILE_GPR:
2181 emitInsn(0x5bf00000);
2182 emitGPR (0x14, insn->src(1));
2183 break;
2184 case FILE_MEMORY_CONST:
2185 emitInsn(0x4bf00000);
2186 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
2187 break;
2188 case FILE_IMMEDIATE:
2189 emitInsn(0x36f00000);
2190 emitIMMD(0x14, 19, insn->src(1));
2191 break;
2192 default:
2193 assert(!"bad src1 file");
2194 break;
2195 }
2196 emitGPR (0x27, insn->src(2));
2197 break;
2198 case FILE_MEMORY_CONST:
2199 emitInsn(0x53f00000);
2200 emitGPR (0x27, insn->src(1));
2201 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(2));
2202 break;
2203 default:
2204 assert(!"bad src2 file");
2205 break;
2206 }
2207
2208 emitCC (0x2f);
2209 emitGPR (0x08, insn->src(0));
2210 emitGPR (0x00, insn->def(0));
2211 }
2212
2213 void
2214 CodeEmitterGM107::emitBFE()
2215 {
2216 switch (insn->src(1).getFile()) {
2217 case FILE_GPR:
2218 emitInsn(0x5c000000);
2219 emitGPR (0x14, insn->src(1));
2220 break;
2221 case FILE_MEMORY_CONST:
2222 emitInsn(0x4c000000);
2223 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
2224 break;
2225 case FILE_IMMEDIATE:
2226 emitInsn(0x38000000);
2227 emitIMMD(0x14, 19, insn->src(1));
2228 break;
2229 default:
2230 assert(!"bad src1 file");
2231 break;
2232 }
2233
2234 emitField(0x30, 1, isSignedType(insn->dType));
2235 emitCC (0x2f);
2236 emitField(0x28, 1, insn->subOp == NV50_IR_SUBOP_EXTBF_REV);
2237 emitGPR (0x08, insn->src(0));
2238 emitGPR (0x00, insn->def(0));
2239 }
2240
2241 void
2242 CodeEmitterGM107::emitFLO()
2243 {
2244 switch (insn->src(0).getFile()) {
2245 case FILE_GPR:
2246 emitInsn(0x5c300000);
2247 emitGPR (0x14, insn->src(0));
2248 break;
2249 case FILE_MEMORY_CONST:
2250 emitInsn(0x4c300000);
2251 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
2252 break;
2253 case FILE_IMMEDIATE:
2254 emitInsn(0x38300000);
2255 emitIMMD(0x14, 19, insn->src(0));
2256 break;
2257 default:
2258 assert(!"bad src1 file");
2259 break;
2260 }
2261
2262 emitField(0x30, 1, isSignedType(insn->dType));
2263 emitCC (0x2f);
2264 emitField(0x29, 1, insn->subOp == NV50_IR_SUBOP_BFIND_SAMT);
2265 emitINV (0x28, insn->src(0));
2266 emitGPR (0x00, insn->def(0));
2267 }
2268
2269 /*******************************************************************************
2270 * memory
2271 ******************************************************************************/
2272
2273 void
2274 CodeEmitterGM107::emitLDSTs(int pos, DataType type)
2275 {
2276 int data = 0;
2277
2278 switch (typeSizeof(type)) {
2279 case 1: data = isSignedType(type) ? 1 : 0; break;
2280 case 2: data = isSignedType(type) ? 3 : 2; break;
2281 case 4: data = 4; break;
2282 case 8: data = 5; break;
2283 case 16: data = 6; break;
2284 default:
2285 assert(!"bad type");
2286 break;
2287 }
2288
2289 emitField(pos, 3, data);
2290 }
2291
2292 void
2293 CodeEmitterGM107::emitLDSTc(int pos)
2294 {
2295 int mode = 0;
2296
2297 switch (insn->cache) {
2298 case CACHE_CA: mode = 0; break;
2299 case CACHE_CG: mode = 1; break;
2300 case CACHE_CS: mode = 2; break;
2301 case CACHE_CV: mode = 3; break;
2302 default:
2303 assert(!"invalid caching mode");
2304 break;
2305 }
2306
2307 emitField(pos, 2, mode);
2308 }
2309
2310 void
2311 CodeEmitterGM107::emitLDC()
2312 {
2313 emitInsn (0xef900000);
2314 emitLDSTs(0x30, insn->dType);
2315 emitField(0x2c, 2, insn->subOp);
2316 emitCBUF (0x24, 0x08, 0x14, 16, 0, insn->src(0));
2317 emitGPR (0x00, insn->def(0));
2318 }
2319
2320 void
2321 CodeEmitterGM107::emitLDL()
2322 {
2323 emitInsn (0xef400000);
2324 emitLDSTs(0x30, insn->dType);
2325 emitLDSTc(0x2c);
2326 emitADDR (0x08, 0x14, 24, 0, insn->src(0));
2327 emitGPR (0x00, insn->def(0));
2328 }
2329
2330 void
2331 CodeEmitterGM107::emitLDS()
2332 {
2333 emitInsn (0xef480000);
2334 emitLDSTs(0x30, insn->dType);
2335 emitADDR (0x08, 0x14, 24, 0, insn->src(0));
2336 emitGPR (0x00, insn->def(0));
2337 }
2338
2339 void
2340 CodeEmitterGM107::emitLD()
2341 {
2342 emitInsn (0x80000000);
2343 emitPRED (0x3a);
2344 emitLDSTc(0x38);
2345 emitLDSTs(0x35, insn->dType);
2346 emitField(0x34, 1, insn->src(0).getIndirect(0)->getSize() == 8);
2347 emitADDR (0x08, 0x14, 32, 0, insn->src(0));
2348 emitGPR (0x00, insn->def(0));
2349 }
2350
2351 void
2352 CodeEmitterGM107::emitSTL()
2353 {
2354 emitInsn (0xef500000);
2355 emitLDSTs(0x30, insn->dType);
2356 emitLDSTc(0x2c);
2357 emitADDR (0x08, 0x14, 24, 0, insn->src(0));
2358 emitGPR (0x00, insn->src(1));
2359 }
2360
2361 void
2362 CodeEmitterGM107::emitSTS()
2363 {
2364 emitInsn (0xef580000);
2365 emitLDSTs(0x30, insn->dType);
2366 emitADDR (0x08, 0x14, 24, 0, insn->src(0));
2367 emitGPR (0x00, insn->src(1));
2368 }
2369
2370 void
2371 CodeEmitterGM107::emitST()
2372 {
2373 emitInsn (0xa0000000);
2374 emitPRED (0x3a);
2375 emitLDSTc(0x38);
2376 emitLDSTs(0x35, insn->dType);
2377 emitField(0x34, 1, insn->src(0).getIndirect(0)->getSize() == 8);
2378 emitADDR (0x08, 0x14, 32, 0, insn->src(0));
2379 emitGPR (0x00, insn->src(1));
2380 }
2381
2382 void
2383 CodeEmitterGM107::emitALD()
2384 {
2385 emitInsn (0xefd80000);
2386 emitField(0x2f, 2, (insn->getDef(0)->reg.size / 4) - 1);
2387 emitGPR (0x27, insn->src(0).getIndirect(1));
2388 emitO (0x20);
2389 emitP (0x1f);
2390 emitADDR (0x08, 20, 10, 0, insn->src(0));
2391 emitGPR (0x00, insn->def(0));
2392 }
2393
2394 void
2395 CodeEmitterGM107::emitAST()
2396 {
2397 emitInsn (0xeff00000);
2398 emitField(0x2f, 2, (typeSizeof(insn->dType) / 4) - 1);
2399 emitGPR (0x27, insn->src(0).getIndirect(1));
2400 emitP (0x1f);
2401 emitADDR (0x08, 20, 10, 0, insn->src(0));
2402 emitGPR (0x00, insn->src(1));
2403 }
2404
2405 void
2406 CodeEmitterGM107::emitISBERD()
2407 {
2408 emitInsn(0xefd00000);
2409 emitGPR (0x08, insn->src(0));
2410 emitGPR (0x00, insn->def(0));
2411 }
2412
2413 void
2414 CodeEmitterGM107::emitAL2P()
2415 {
2416 emitInsn (0xefa00000);
2417 emitField(0x2f, 2, (insn->getDef(0)->reg.size / 4) - 1);
2418 emitPRED (0x2c);
2419 emitO (0x20);
2420 emitField(0x14, 11, insn->src(0).get()->reg.data.offset);
2421 emitGPR (0x08, insn->src(0).getIndirect(0));
2422 emitGPR (0x00, insn->def(0));
2423 }
2424
2425 static void
2426 interpApply(const FixupEntry *entry, uint32_t *code, const FixupData& data)
2427 {
2428 int ipa = entry->ipa;
2429 int reg = entry->reg;
2430 int loc = entry->loc;
2431
2432 if (data.flatshade &&
2433 (ipa & NV50_IR_INTERP_MODE_MASK) == NV50_IR_INTERP_SC) {
2434 ipa = NV50_IR_INTERP_FLAT;
2435 reg = 0xff;
2436 } else if (data.force_persample_interp &&
2437 (ipa & NV50_IR_INTERP_SAMPLE_MASK) == NV50_IR_INTERP_DEFAULT &&
2438 (ipa & NV50_IR_INTERP_MODE_MASK) != NV50_IR_INTERP_FLAT) {
2439 ipa |= NV50_IR_INTERP_CENTROID;
2440 }
2441 code[loc + 1] &= ~(0xf << 0x14);
2442 code[loc + 1] |= (ipa & 0x3) << 0x16;
2443 code[loc + 1] |= (ipa & 0xc) << (0x14 - 2);
2444 code[loc + 0] &= ~(0xff << 0x14);
2445 code[loc + 0] |= reg << 0x14;
2446 }
2447
2448 void
2449 CodeEmitterGM107::emitIPA()
2450 {
2451 int ipam = 0, ipas = 0;
2452
2453 switch (insn->getInterpMode()) {
2454 case NV50_IR_INTERP_LINEAR : ipam = 0; break;
2455 case NV50_IR_INTERP_PERSPECTIVE: ipam = 1; break;
2456 case NV50_IR_INTERP_FLAT : ipam = 2; break;
2457 case NV50_IR_INTERP_SC : ipam = 3; break;
2458 default:
2459 assert(!"invalid ipa mode");
2460 break;
2461 }
2462
2463 switch (insn->getSampleMode()) {
2464 case NV50_IR_INTERP_DEFAULT : ipas = 0; break;
2465 case NV50_IR_INTERP_CENTROID: ipas = 1; break;
2466 case NV50_IR_INTERP_OFFSET : ipas = 2; break;
2467 default:
2468 assert(!"invalid ipa sample mode");
2469 break;
2470 }
2471
2472 emitInsn (0xe0000000);
2473 emitField(0x36, 2, ipam);
2474 emitField(0x34, 2, ipas);
2475 emitSAT (0x33);
2476 emitField(0x2f, 3, 7);
2477 emitADDR (0x08, 0x1c, 10, 0, insn->src(0));
2478 if ((code[0] & 0x0000ff00) != 0x0000ff00)
2479 code[1] |= 0x00000040; /* .idx */
2480 emitGPR(0x00, insn->def(0));
2481
2482 if (insn->op == OP_PINTERP) {
2483 emitGPR(0x14, insn->src(1));
2484 if (insn->getSampleMode() == NV50_IR_INTERP_OFFSET)
2485 emitGPR(0x27, insn->src(2));
2486 addInterp(insn->ipa, insn->getSrc(1)->reg.data.id, interpApply);
2487 } else {
2488 if (insn->getSampleMode() == NV50_IR_INTERP_OFFSET)
2489 emitGPR(0x27, insn->src(1));
2490 emitGPR(0x14);
2491 addInterp(insn->ipa, 0xff, interpApply);
2492 }
2493
2494 if (insn->getSampleMode() != NV50_IR_INTERP_OFFSET)
2495 emitGPR(0x27);
2496 }
2497
2498 void
2499 CodeEmitterGM107::emitATOM()
2500 {
2501 unsigned dType, subOp;
2502
2503 if (insn->subOp == NV50_IR_SUBOP_ATOM_CAS) {
2504 switch (insn->dType) {
2505 case TYPE_U32: dType = 0; break;
2506 case TYPE_U64: dType = 1; break;
2507 default: assert(!"unexpected dType"); dType = 0; break;
2508 }
2509 subOp = 15;
2510
2511 emitInsn (0xee000000);
2512 } else {
2513 switch (insn->dType) {
2514 case TYPE_U32: dType = 0; break;
2515 case TYPE_S32: dType = 1; break;
2516 case TYPE_U64: dType = 2; break;
2517 case TYPE_F32: dType = 3; break;
2518 case TYPE_B128: dType = 4; break;
2519 case TYPE_S64: dType = 5; break;
2520 default: assert(!"unexpected dType"); dType = 0; break;
2521 }
2522 if (insn->subOp == NV50_IR_SUBOP_ATOM_EXCH)
2523 subOp = 8;
2524 else
2525 subOp = insn->subOp;
2526
2527 emitInsn (0xed000000);
2528 }
2529
2530 emitField(0x34, 4, subOp);
2531 emitField(0x31, 3, dType);
2532 emitField(0x30, 1, insn->src(0).getIndirect(0)->getSize() == 8);
2533 emitGPR (0x14, insn->src(1));
2534 emitADDR (0x08, 0x1c, 20, 0, insn->src(0));
2535 emitGPR (0x00, insn->def(0));
2536 }
2537
2538 void
2539 CodeEmitterGM107::emitATOMS()
2540 {
2541 unsigned dType, subOp;
2542
2543 if (insn->subOp == NV50_IR_SUBOP_ATOM_CAS) {
2544 switch (insn->dType) {
2545 case TYPE_U32: dType = 0; break;
2546 case TYPE_U64: dType = 1; break;
2547 default: assert(!"unexpected dType"); dType = 0; break;
2548 }
2549 subOp = 4;
2550
2551 emitInsn (0xee000000);
2552 emitField(0x34, 1, dType);
2553 } else {
2554 switch (insn->dType) {
2555 case TYPE_U32: dType = 0; break;
2556 case TYPE_S32: dType = 1; break;
2557 case TYPE_U64: dType = 2; break;
2558 case TYPE_S64: dType = 3; break;
2559 default: assert(!"unexpected dType"); dType = 0; break;
2560 }
2561
2562 if (insn->subOp == NV50_IR_SUBOP_ATOM_EXCH)
2563 subOp = 8;
2564 else
2565 subOp = insn->subOp;
2566
2567 emitInsn (0xec000000);
2568 emitField(0x1c, 3, dType);
2569 }
2570
2571 emitField(0x34, 4, subOp);
2572 emitGPR (0x14, insn->src(1));
2573 emitADDR (0x08, 0x1e, 22, 2, insn->src(0));
2574 emitGPR (0x00, insn->def(0));
2575 }
2576
2577 void
2578 CodeEmitterGM107::emitRED()
2579 {
2580 unsigned dType;
2581
2582 switch (insn->dType) {
2583 case TYPE_U32: dType = 0; break;
2584 case TYPE_S32: dType = 1; break;
2585 case TYPE_U64: dType = 2; break;
2586 case TYPE_F32: dType = 3; break;
2587 case TYPE_B128: dType = 4; break;
2588 case TYPE_S64: dType = 5; break;
2589 default: assert(!"unexpected dType"); dType = 0; break;
2590 }
2591
2592 emitInsn (0xebf80000);
2593 emitField(0x30, 1, insn->src(0).getIndirect(0)->getSize() == 8);
2594 emitField(0x17, 3, insn->subOp);
2595 emitField(0x14, 3, dType);
2596 emitADDR (0x08, 0x1c, 20, 0, insn->src(0));
2597 emitGPR (0x00, insn->src(1));
2598 }
2599
2600 void
2601 CodeEmitterGM107::emitCCTL()
2602 {
2603 unsigned width;
2604 if (insn->src(0).getFile() == FILE_MEMORY_GLOBAL) {
2605 emitInsn(0xef600000);
2606 width = 30;
2607 } else {
2608 emitInsn(0xef800000);
2609 width = 22;
2610 }
2611 emitField(0x34, 1, insn->src(0).getIndirect(0)->getSize() == 8);
2612 emitADDR (0x08, 0x16, width, 2, insn->src(0));
2613 emitField(0x00, 4, insn->subOp);
2614 }
2615
2616 /*******************************************************************************
2617 * surface
2618 ******************************************************************************/
2619
2620 void
2621 CodeEmitterGM107::emitPIXLD()
2622 {
2623 emitInsn (0xefe80000);
2624 emitPRED (0x2d);
2625 emitField(0x1f, 3, insn->subOp);
2626 emitGPR (0x08, insn->src(0));
2627 emitGPR (0x00, insn->def(0));
2628 }
2629
2630 /*******************************************************************************
2631 * texture
2632 ******************************************************************************/
2633
2634 void
2635 CodeEmitterGM107::emitTEXs(int pos)
2636 {
2637 int src1 = insn->predSrc == 1 ? 2 : 1;
2638 if (insn->srcExists(src1))
2639 emitGPR(pos, insn->src(src1));
2640 else
2641 emitGPR(pos);
2642 }
2643
2644 void
2645 CodeEmitterGM107::emitTEX()
2646 {
2647 const TexInstruction *insn = this->insn->asTex();
2648 int lodm = 0;
2649
2650 if (!insn->tex.levelZero) {
2651 switch (insn->op) {
2652 case OP_TEX: lodm = 0; break;
2653 case OP_TXB: lodm = 2; break;
2654 case OP_TXL: lodm = 3; break;
2655 default:
2656 assert(!"invalid tex op");
2657 break;
2658 }
2659 } else {
2660 lodm = 1;
2661 }
2662
2663 if (insn->tex.rIndirectSrc >= 0) {
2664 emitInsn (0xdeb80000);
2665 emitField(0x25, 2, lodm);
2666 emitField(0x24, 1, insn->tex.useOffsets == 1);
2667 } else {
2668 emitInsn (0xc0380000);
2669 emitField(0x37, 2, lodm);
2670 emitField(0x36, 1, insn->tex.useOffsets == 1);
2671 emitField(0x24, 13, insn->tex.r);
2672 }
2673
2674 emitField(0x32, 1, insn->tex.target.isShadow());
2675 emitField(0x31, 1, insn->tex.liveOnly);
2676 emitField(0x23, 1, insn->tex.derivAll);
2677 emitField(0x1f, 4, insn->tex.mask);
2678 emitField(0x1d, 2, insn->tex.target.isCube() ? 3 :
2679 insn->tex.target.getDim() - 1);
2680 emitField(0x1c, 1, insn->tex.target.isArray());
2681 emitTEXs (0x14);
2682 emitGPR (0x08, insn->src(0));
2683 emitGPR (0x00, insn->def(0));
2684 }
2685
2686 void
2687 CodeEmitterGM107::emitTLD()
2688 {
2689 const TexInstruction *insn = this->insn->asTex();
2690
2691 if (insn->tex.rIndirectSrc >= 0) {
2692 emitInsn (0xdd380000);
2693 } else {
2694 emitInsn (0xdc380000);
2695 emitField(0x24, 13, insn->tex.r);
2696 }
2697
2698 emitField(0x37, 1, insn->tex.levelZero == 0);
2699 emitField(0x32, 1, insn->tex.target.isMS());
2700 emitField(0x31, 1, insn->tex.liveOnly);
2701 emitField(0x23, 1, insn->tex.useOffsets == 1);
2702 emitField(0x1f, 4, insn->tex.mask);
2703 emitField(0x1d, 2, insn->tex.target.isCube() ? 3 :
2704 insn->tex.target.getDim() - 1);
2705 emitField(0x1c, 1, insn->tex.target.isArray());
2706 emitTEXs (0x14);
2707 emitGPR (0x08, insn->src(0));
2708 emitGPR (0x00, insn->def(0));
2709 }
2710
2711 void
2712 CodeEmitterGM107::emitTLD4()
2713 {
2714 const TexInstruction *insn = this->insn->asTex();
2715
2716 if (insn->tex.rIndirectSrc >= 0) {
2717 emitInsn (0xdef80000);
2718 emitField(0x26, 2, insn->tex.gatherComp);
2719 emitField(0x25, 2, insn->tex.useOffsets == 4);
2720 emitField(0x24, 2, insn->tex.useOffsets == 1);
2721 } else {
2722 emitInsn (0xc8380000);
2723 emitField(0x38, 2, insn->tex.gatherComp);
2724 emitField(0x37, 2, insn->tex.useOffsets == 4);
2725 emitField(0x36, 2, insn->tex.useOffsets == 1);
2726 emitField(0x24, 13, insn->tex.r);
2727 }
2728
2729 emitField(0x32, 1, insn->tex.target.isShadow());
2730 emitField(0x31, 1, insn->tex.liveOnly);
2731 emitField(0x23, 1, insn->tex.derivAll);
2732 emitField(0x1f, 4, insn->tex.mask);
2733 emitField(0x1d, 2, insn->tex.target.isCube() ? 3 :
2734 insn->tex.target.getDim() - 1);
2735 emitField(0x1c, 1, insn->tex.target.isArray());
2736 emitTEXs (0x14);
2737 emitGPR (0x08, insn->src(0));
2738 emitGPR (0x00, insn->def(0));
2739 }
2740
2741 void
2742 CodeEmitterGM107::emitTXD()
2743 {
2744 const TexInstruction *insn = this->insn->asTex();
2745
2746 if (insn->tex.rIndirectSrc >= 0) {
2747 emitInsn (0xde780000);
2748 } else {
2749 emitInsn (0xde380000);
2750 emitField(0x24, 13, insn->tex.r);
2751 }
2752
2753 emitField(0x31, 1, insn->tex.liveOnly);
2754 emitField(0x23, 1, insn->tex.useOffsets == 1);
2755 emitField(0x1f, 4, insn->tex.mask);
2756 emitField(0x1d, 2, insn->tex.target.isCube() ? 3 :
2757 insn->tex.target.getDim() - 1);
2758 emitField(0x1c, 1, insn->tex.target.isArray());
2759 emitTEXs (0x14);
2760 emitGPR (0x08, insn->src(0));
2761 emitGPR (0x00, insn->def(0));
2762 }
2763
2764 void
2765 CodeEmitterGM107::emitTMML()
2766 {
2767 const TexInstruction *insn = this->insn->asTex();
2768
2769 if (insn->tex.rIndirectSrc >= 0) {
2770 emitInsn (0xdf600000);
2771 } else {
2772 emitInsn (0xdf580000);
2773 emitField(0x24, 13, insn->tex.r);
2774 }
2775
2776 emitField(0x31, 1, insn->tex.liveOnly);
2777 emitField(0x23, 1, insn->tex.derivAll);
2778 emitField(0x1f, 4, insn->tex.mask);
2779 emitField(0x1d, 2, insn->tex.target.isCube() ? 3 :
2780 insn->tex.target.getDim() - 1);
2781 emitField(0x1c, 1, insn->tex.target.isArray());
2782 emitTEXs (0x14);
2783 emitGPR (0x08, insn->src(0));
2784 emitGPR (0x00, insn->def(0));
2785 }
2786
2787 void
2788 CodeEmitterGM107::emitTXQ()
2789 {
2790 const TexInstruction *insn = this->insn->asTex();
2791 int type = 0;
2792
2793 switch (insn->tex.query) {
2794 case TXQ_DIMS : type = 0x01; break;
2795 case TXQ_TYPE : type = 0x02; break;
2796 case TXQ_SAMPLE_POSITION: type = 0x05; break;
2797 case TXQ_FILTER : type = 0x10; break;
2798 case TXQ_LOD : type = 0x12; break;
2799 case TXQ_WRAP : type = 0x14; break;
2800 case TXQ_BORDER_COLOUR : type = 0x16; break;
2801 default:
2802 assert(!"invalid txq query");
2803 break;
2804 }
2805
2806 if (insn->tex.rIndirectSrc >= 0) {
2807 emitInsn (0xdf500000);
2808 } else {
2809 emitInsn (0xdf480000);
2810 emitField(0x24, 13, insn->tex.r);
2811 }
2812
2813 emitField(0x31, 1, insn->tex.liveOnly);
2814 emitField(0x1f, 4, insn->tex.mask);
2815 emitField(0x16, 6, type);
2816 emitGPR (0x08, insn->src(0));
2817 emitGPR (0x00, insn->def(0));
2818 }
2819
2820 void
2821 CodeEmitterGM107::emitDEPBAR()
2822 {
2823 emitInsn (0xf0f00000);
2824 emitField(0x1d, 1, 1); /* le */
2825 emitField(0x1a, 3, 5);
2826 emitField(0x14, 6, insn->subOp);
2827 emitField(0x00, 6, insn->subOp);
2828 }
2829
2830 /*******************************************************************************
2831 * misc
2832 ******************************************************************************/
2833
2834 void
2835 CodeEmitterGM107::emitNOP()
2836 {
2837 emitInsn(0x50b00000);
2838 }
2839
2840 void
2841 CodeEmitterGM107::emitKIL()
2842 {
2843 emitInsn (0xe3300000);
2844 emitCond5(0x00, CC_TR);
2845 }
2846
2847 void
2848 CodeEmitterGM107::emitOUT()
2849 {
2850 const int cut = insn->op == OP_RESTART || insn->subOp;
2851 const int emit = insn->op == OP_EMIT;
2852
2853 switch (insn->src(1).getFile()) {
2854 case FILE_GPR:
2855 emitInsn(0xfbe00000);
2856 emitGPR (0x14, insn->src(1));
2857 break;
2858 case FILE_IMMEDIATE:
2859 emitInsn(0xf6e00000);
2860 emitIMMD(0x14, 19, insn->src(1));
2861 break;
2862 case FILE_MEMORY_CONST:
2863 emitInsn(0xebe00000);
2864 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
2865 break;
2866 default:
2867 assert(!"bad src1 file");
2868 break;
2869 }
2870
2871 emitField(0x27, 2, (cut << 1) | emit);
2872 emitGPR (0x08, insn->src(0));
2873 emitGPR (0x00, insn->def(0));
2874 }
2875
2876 void
2877 CodeEmitterGM107::emitBAR()
2878 {
2879 uint8_t subop;
2880
2881 emitInsn (0xf0a80000);
2882
2883 switch (insn->subOp) {
2884 case NV50_IR_SUBOP_BAR_RED_POPC: subop = 0x02; break;
2885 case NV50_IR_SUBOP_BAR_RED_AND: subop = 0x0a; break;
2886 case NV50_IR_SUBOP_BAR_RED_OR: subop = 0x12; break;
2887 case NV50_IR_SUBOP_BAR_ARRIVE: subop = 0x81; break;
2888 default:
2889 subop = 0x80;
2890 assert(insn->subOp == NV50_IR_SUBOP_BAR_SYNC);
2891 break;
2892 }
2893
2894 emitField(0x20, 8, subop);
2895
2896 // barrier id
2897 if (insn->src(0).getFile() == FILE_GPR) {
2898 emitGPR(0x08, insn->src(0));
2899 } else {
2900 ImmediateValue *imm = insn->getSrc(0)->asImm();
2901 assert(imm);
2902 emitField(0x08, 8, imm->reg.data.u32);
2903 emitField(0x2b, 1, 1);
2904 }
2905
2906 // thread count
2907 if (insn->src(1).getFile() == FILE_GPR) {
2908 emitGPR(0x14, insn->src(1));
2909 } else {
2910 ImmediateValue *imm = insn->getSrc(0)->asImm();
2911 assert(imm);
2912 emitField(0x14, 12, imm->reg.data.u32);
2913 emitField(0x2c, 1, 1);
2914 }
2915
2916 if (insn->srcExists(2) && (insn->predSrc != 2)) {
2917 emitPRED (0x27, insn->src(2));
2918 emitField(0x2a, 1, insn->src(2).mod == Modifier(NV50_IR_MOD_NOT));
2919 } else {
2920 emitField(0x27, 3, 7);
2921 }
2922 }
2923
2924 void
2925 CodeEmitterGM107::emitMEMBAR()
2926 {
2927 emitInsn (0xef980000);
2928 emitField(0x08, 2, insn->subOp >> 2);
2929 }
2930
2931 void
2932 CodeEmitterGM107::emitVOTE()
2933 {
2934 assert(insn->src(0).getFile() == FILE_PREDICATE);
2935
2936 int r = -1, p = -1;
2937 for (int i = 0; insn->defExists(i); i++) {
2938 if (insn->def(i).getFile() == FILE_GPR)
2939 r = i;
2940 else if (insn->def(i).getFile() == FILE_PREDICATE)
2941 p = i;
2942 }
2943
2944 emitInsn (0x50d80000);
2945 emitField(0x30, 2, insn->subOp);
2946 if (r >= 0)
2947 emitGPR (0x00, insn->def(r));
2948 else
2949 emitGPR (0x00);
2950 if (p >= 0)
2951 emitPRED (0x2d, insn->def(p));
2952 else
2953 emitPRED (0x2d);
2954 emitField(0x2a, 1, insn->src(0).mod == Modifier(NV50_IR_MOD_NOT));
2955 emitPRED (0x27, insn->src(0));
2956 }
2957
2958 void
2959 CodeEmitterGM107::emitSUTarget()
2960 {
2961 const TexInstruction *insn = this->insn->asTex();
2962 int target = 0;
2963
2964 assert(insn->op >= OP_SULDB && insn->op <= OP_SUREDP);
2965
2966 if (insn->tex.target == TEX_TARGET_BUFFER) {
2967 target = 2;
2968 } else if (insn->tex.target == TEX_TARGET_1D_ARRAY) {
2969 target = 4;
2970 } else if (insn->tex.target == TEX_TARGET_2D ||
2971 insn->tex.target == TEX_TARGET_RECT) {
2972 target = 6;
2973 } else if (insn->tex.target == TEX_TARGET_2D_ARRAY ||
2974 insn->tex.target == TEX_TARGET_CUBE ||
2975 insn->tex.target == TEX_TARGET_CUBE_ARRAY) {
2976 target = 8;
2977 } else if (insn->tex.target == TEX_TARGET_3D) {
2978 target = 10;
2979 } else {
2980 assert(insn->tex.target == TEX_TARGET_1D);
2981 }
2982 emitField(0x20, 4, target);
2983 }
2984
2985 void
2986 CodeEmitterGM107::emitSUHandle(const int s)
2987 {
2988 const TexInstruction *insn = this->insn->asTex();
2989
2990 assert(insn->op >= OP_SULDB && insn->op <= OP_SUREDP);
2991
2992 if (insn->src(s).getFile() == FILE_GPR) {
2993 emitGPR(0x27, insn->src(s));
2994 } else {
2995 ImmediateValue *imm = insn->getSrc(s)->asImm();
2996 assert(imm);
2997 emitField(0x33, 1, 1);
2998 emitField(0x24, 13, imm->reg.data.u32);
2999 }
3000 }
3001
3002 void
3003 CodeEmitterGM107::emitSUSTx()
3004 {
3005 const TexInstruction *insn = this->insn->asTex();
3006
3007 emitInsn(0xeb200000);
3008 if (insn->op == OP_SUSTB)
3009 emitField(0x34, 1, 1);
3010 emitSUTarget();
3011
3012 emitLDSTc(0x18);
3013 emitField(0x14, 4, 0xf); // rgba
3014 emitGPR (0x08, insn->src(0));
3015 emitGPR (0x00, insn->src(1));
3016
3017 emitSUHandle(2);
3018 }
3019
3020 void
3021 CodeEmitterGM107::emitSULDx()
3022 {
3023 const TexInstruction *insn = this->insn->asTex();
3024 int type = 0;
3025
3026 emitInsn(0xeb000000);
3027 if (insn->op == OP_SULDB)
3028 emitField(0x34, 1, 1);
3029 emitSUTarget();
3030
3031 switch (insn->dType) {
3032 case TYPE_S8: type = 1; break;
3033 case TYPE_U16: type = 2; break;
3034 case TYPE_S16: type = 3; break;
3035 case TYPE_U32: type = 4; break;
3036 case TYPE_U64: type = 5; break;
3037 case TYPE_B128: type = 6; break;
3038 default:
3039 assert(insn->dType == TYPE_U8);
3040 break;
3041 }
3042 emitLDSTc(0x18);
3043 emitField(0x14, 3, type);
3044 emitGPR (0x00, insn->def(0));
3045 emitGPR (0x08, insn->src(0));
3046
3047 emitSUHandle(1);
3048 }
3049
3050 void
3051 CodeEmitterGM107::emitSUREDx()
3052 {
3053 const TexInstruction *insn = this->insn->asTex();
3054 uint8_t type = 0, subOp;
3055
3056 if (insn->subOp == NV50_IR_SUBOP_ATOM_CAS)
3057 emitInsn(0xeac00000);
3058 else
3059 emitInsn(0xea600000);
3060
3061 if (insn->op == OP_SUREDB)
3062 emitField(0x34, 1, 1);
3063 emitSUTarget();
3064
3065 // destination type
3066 switch (insn->dType) {
3067 case TYPE_S32: type = 1; break;
3068 case TYPE_U64: type = 2; break;
3069 case TYPE_F32: type = 3; break;
3070 case TYPE_S64: type = 5; break;
3071 default:
3072 assert(insn->dType == TYPE_U32);
3073 break;
3074 }
3075
3076 // atomic operation
3077 if (insn->subOp == NV50_IR_SUBOP_ATOM_CAS) {
3078 subOp = 0;
3079 } else if (insn->subOp == NV50_IR_SUBOP_ATOM_EXCH) {
3080 subOp = 8;
3081 } else {
3082 subOp = insn->subOp;
3083 }
3084
3085 emitField(0x24, 3, type);
3086 emitField(0x1d, 4, subOp);
3087 emitGPR (0x14, insn->src(1));
3088 emitGPR (0x08, insn->src(0));
3089 emitGPR (0x00, insn->def(0));
3090
3091 emitSUHandle(2);
3092 }
3093
3094 /*******************************************************************************
3095 * assembler front-end
3096 ******************************************************************************/
3097
3098 bool
3099 CodeEmitterGM107::emitInstruction(Instruction *i)
3100 {
3101 const unsigned int size = (writeIssueDelays && !(codeSize & 0x1f)) ? 16 : 8;
3102 bool ret = true;
3103
3104 insn = i;
3105
3106 if (insn->encSize != 8) {
3107 ERROR("skipping undecodable instruction: "); insn->print();
3108 return false;
3109 } else
3110 if (codeSize + size > codeSizeLimit) {
3111 ERROR("code emitter output buffer too small\n");
3112 return false;
3113 }
3114
3115 if (writeIssueDelays) {
3116 int n = ((codeSize & 0x1f) / 8) - 1;
3117 if (n < 0) {
3118 data = code;
3119 data[0] = 0x00000000;
3120 data[1] = 0x00000000;
3121 code += 2;
3122 codeSize += 8;
3123 n++;
3124 }
3125
3126 emitField(data, n * 21, 21, insn->sched);
3127 }
3128
3129 switch (insn->op) {
3130 case OP_EXIT:
3131 emitEXIT();
3132 break;
3133 case OP_BRA:
3134 emitBRA();
3135 break;
3136 case OP_CALL:
3137 emitCAL();
3138 break;
3139 case OP_PRECONT:
3140 emitPCNT();
3141 break;
3142 case OP_CONT:
3143 emitCONT();
3144 break;
3145 case OP_PREBREAK:
3146 emitPBK();
3147 break;
3148 case OP_BREAK:
3149 emitBRK();
3150 break;
3151 case OP_PRERET:
3152 emitPRET();
3153 break;
3154 case OP_RET:
3155 emitRET();
3156 break;
3157 case OP_JOINAT:
3158 emitSSY();
3159 break;
3160 case OP_JOIN:
3161 emitSYNC();
3162 break;
3163 case OP_QUADON:
3164 emitSAM();
3165 break;
3166 case OP_QUADPOP:
3167 emitRAM();
3168 break;
3169 case OP_MOV:
3170 emitMOV();
3171 break;
3172 case OP_RDSV:
3173 emitS2R();
3174 break;
3175 case OP_ABS:
3176 case OP_NEG:
3177 case OP_SAT:
3178 case OP_FLOOR:
3179 case OP_CEIL:
3180 case OP_TRUNC:
3181 case OP_CVT:
3182 if (insn->op == OP_CVT && (insn->def(0).getFile() == FILE_PREDICATE ||
3183 insn->src(0).getFile() == FILE_PREDICATE)) {
3184 emitMOV();
3185 } else if (isFloatType(insn->dType)) {
3186 if (isFloatType(insn->sType))
3187 emitF2F();
3188 else
3189 emitI2F();
3190 } else {
3191 if (isFloatType(insn->sType))
3192 emitF2I();
3193 else
3194 emitI2I();
3195 }
3196 break;
3197 case OP_SHFL:
3198 emitSHFL();
3199 break;
3200 case OP_ADD:
3201 case OP_SUB:
3202 if (isFloatType(insn->dType)) {
3203 if (insn->dType == TYPE_F64)
3204 emitDADD();
3205 else
3206 emitFADD();
3207 } else {
3208 emitIADD();
3209 }
3210 break;
3211 case OP_MUL:
3212 if (isFloatType(insn->dType)) {
3213 if (insn->dType == TYPE_F64)
3214 emitDMUL();
3215 else
3216 emitFMUL();
3217 } else {
3218 emitIMUL();
3219 }
3220 break;
3221 case OP_MAD:
3222 case OP_FMA:
3223 if (isFloatType(insn->dType)) {
3224 if (insn->dType == TYPE_F64)
3225 emitDFMA();
3226 else
3227 emitFFMA();
3228 } else {
3229 emitIMAD();
3230 }
3231 break;
3232 case OP_SHLADD:
3233 emitISCADD();
3234 break;
3235 case OP_MIN:
3236 case OP_MAX:
3237 if (isFloatType(insn->dType)) {
3238 if (insn->dType == TYPE_F64)
3239 emitDMNMX();
3240 else
3241 emitFMNMX();
3242 } else {
3243 emitIMNMX();
3244 }
3245 break;
3246 case OP_SHL:
3247 if (typeSizeof(insn->sType) == 8)
3248 emitSHF();
3249 else
3250 emitSHL();
3251 break;
3252 case OP_SHR:
3253 if (typeSizeof(insn->sType) == 8)
3254 emitSHF();
3255 else
3256 emitSHR();
3257 break;
3258 case OP_POPCNT:
3259 emitPOPC();
3260 break;
3261 case OP_INSBF:
3262 emitBFI();
3263 break;
3264 case OP_EXTBF:
3265 emitBFE();
3266 break;
3267 case OP_BFIND:
3268 emitFLO();
3269 break;
3270 case OP_SLCT:
3271 if (isFloatType(insn->dType))
3272 emitFCMP();
3273 else
3274 emitICMP();
3275 break;
3276 case OP_SET:
3277 case OP_SET_AND:
3278 case OP_SET_OR:
3279 case OP_SET_XOR:
3280 if (insn->def(0).getFile() != FILE_PREDICATE) {
3281 if (isFloatType(insn->sType))
3282 if (insn->sType == TYPE_F64)
3283 emitDSET();
3284 else
3285 emitFSET();
3286 else
3287 emitISET();
3288 } else {
3289 if (isFloatType(insn->sType))
3290 if (insn->sType == TYPE_F64)
3291 emitDSETP();
3292 else
3293 emitFSETP();
3294 else
3295 emitISETP();
3296 }
3297 break;
3298 case OP_SELP:
3299 emitSEL();
3300 break;
3301 case OP_PRESIN:
3302 case OP_PREEX2:
3303 emitRRO();
3304 break;
3305 case OP_COS:
3306 case OP_SIN:
3307 case OP_EX2:
3308 case OP_LG2:
3309 case OP_RCP:
3310 case OP_RSQ:
3311 emitMUFU();
3312 break;
3313 case OP_AND:
3314 case OP_OR:
3315 case OP_XOR:
3316 emitLOP();
3317 break;
3318 case OP_NOT:
3319 emitNOT();
3320 break;
3321 case OP_LOAD:
3322 switch (insn->src(0).getFile()) {
3323 case FILE_MEMORY_CONST : emitLDC(); break;
3324 case FILE_MEMORY_LOCAL : emitLDL(); break;
3325 case FILE_MEMORY_SHARED: emitLDS(); break;
3326 case FILE_MEMORY_GLOBAL: emitLD(); break;
3327 default:
3328 assert(!"invalid load");
3329 emitNOP();
3330 break;
3331 }
3332 break;
3333 case OP_STORE:
3334 switch (insn->src(0).getFile()) {
3335 case FILE_MEMORY_LOCAL : emitSTL(); break;
3336 case FILE_MEMORY_SHARED: emitSTS(); break;
3337 case FILE_MEMORY_GLOBAL: emitST(); break;
3338 default:
3339 assert(!"invalid store");
3340 emitNOP();
3341 break;
3342 }
3343 break;
3344 case OP_ATOM:
3345 if (insn->src(0).getFile() == FILE_MEMORY_SHARED)
3346 emitATOMS();
3347 else
3348 if (!insn->defExists(0) && insn->subOp < NV50_IR_SUBOP_ATOM_CAS)
3349 emitRED();
3350 else
3351 emitATOM();
3352 break;
3353 case OP_CCTL:
3354 emitCCTL();
3355 break;
3356 case OP_VFETCH:
3357 emitALD();
3358 break;
3359 case OP_EXPORT:
3360 emitAST();
3361 break;
3362 case OP_PFETCH:
3363 emitISBERD();
3364 break;
3365 case OP_AFETCH:
3366 emitAL2P();
3367 break;
3368 case OP_LINTERP:
3369 case OP_PINTERP:
3370 emitIPA();
3371 break;
3372 case OP_PIXLD:
3373 emitPIXLD();
3374 break;
3375 case OP_TEX:
3376 case OP_TXB:
3377 case OP_TXL:
3378 emitTEX();
3379 break;
3380 case OP_TXF:
3381 emitTLD();
3382 break;
3383 case OP_TXG:
3384 emitTLD4();
3385 break;
3386 case OP_TXD:
3387 emitTXD();
3388 break;
3389 case OP_TXQ:
3390 emitTXQ();
3391 break;
3392 case OP_TXLQ:
3393 emitTMML();
3394 break;
3395 case OP_TEXBAR:
3396 emitDEPBAR();
3397 break;
3398 case OP_QUADOP:
3399 emitFSWZADD();
3400 break;
3401 case OP_NOP:
3402 emitNOP();
3403 break;
3404 case OP_DISCARD:
3405 emitKIL();
3406 break;
3407 case OP_EMIT:
3408 case OP_RESTART:
3409 emitOUT();
3410 break;
3411 case OP_BAR:
3412 emitBAR();
3413 break;
3414 case OP_MEMBAR:
3415 emitMEMBAR();
3416 break;
3417 case OP_VOTE:
3418 emitVOTE();
3419 break;
3420 case OP_SUSTB:
3421 case OP_SUSTP:
3422 emitSUSTx();
3423 break;
3424 case OP_SULDB:
3425 case OP_SULDP:
3426 emitSULDx();
3427 break;
3428 case OP_SUREDB:
3429 case OP_SUREDP:
3430 emitSUREDx();
3431 break;
3432 default:
3433 assert(!"invalid opcode");
3434 emitNOP();
3435 ret = false;
3436 break;
3437 }
3438
3439 if (insn->join) {
3440 /*XXX*/
3441 }
3442
3443 code += 2;
3444 codeSize += 8;
3445 return ret;
3446 }
3447
3448 uint32_t
3449 CodeEmitterGM107::getMinEncodingSize(const Instruction *i) const
3450 {
3451 return 8;
3452 }
3453
3454 /*******************************************************************************
3455 * sched data calculator
3456 ******************************************************************************/
3457
3458 class SchedDataCalculatorGM107 : public Pass
3459 {
3460 public:
3461 SchedDataCalculatorGM107(const TargetGM107 *targ) : targ(targ) {}
3462
3463 private:
3464 struct RegScores
3465 {
3466 struct ScoreData {
3467 int r[256];
3468 int p[8];
3469 int c;
3470 } rd, wr;
3471 int base;
3472
3473 void rebase(const int base)
3474 {
3475 const int delta = this->base - base;
3476 if (!delta)
3477 return;
3478 this->base = 0;
3479
3480 for (int i = 0; i < 256; ++i) {
3481 rd.r[i] += delta;
3482 wr.r[i] += delta;
3483 }
3484 for (int i = 0; i < 8; ++i) {
3485 rd.p[i] += delta;
3486 wr.p[i] += delta;
3487 }
3488 rd.c += delta;
3489 wr.c += delta;
3490 }
3491 void wipe()
3492 {
3493 memset(&rd, 0, sizeof(rd));
3494 memset(&wr, 0, sizeof(wr));
3495 }
3496 int getLatest(const ScoreData& d) const
3497 {
3498 int max = 0;
3499 for (int i = 0; i < 256; ++i)
3500 if (d.r[i] > max)
3501 max = d.r[i];
3502 for (int i = 0; i < 8; ++i)
3503 if (d.p[i] > max)
3504 max = d.p[i];
3505 if (d.c > max)
3506 max = d.c;
3507 return max;
3508 }
3509 inline int getLatestRd() const
3510 {
3511 return getLatest(rd);
3512 }
3513 inline int getLatestWr() const
3514 {
3515 return getLatest(wr);
3516 }
3517 inline int getLatest() const
3518 {
3519 return MAX2(getLatestRd(), getLatestWr());
3520 }
3521 void setMax(const RegScores *that)
3522 {
3523 for (int i = 0; i < 256; ++i) {
3524 rd.r[i] = MAX2(rd.r[i], that->rd.r[i]);
3525 wr.r[i] = MAX2(wr.r[i], that->wr.r[i]);
3526 }
3527 for (int i = 0; i < 8; ++i) {
3528 rd.p[i] = MAX2(rd.p[i], that->rd.p[i]);
3529 wr.p[i] = MAX2(wr.p[i], that->wr.p[i]);
3530 }
3531 rd.c = MAX2(rd.c, that->rd.c);
3532 wr.c = MAX2(wr.c, that->wr.c);
3533 }
3534 void print(int cycle)
3535 {
3536 for (int i = 0; i < 256; ++i) {
3537 if (rd.r[i] > cycle)
3538 INFO("rd $r%i @ %i\n", i, rd.r[i]);
3539 if (wr.r[i] > cycle)
3540 INFO("wr $r%i @ %i\n", i, wr.r[i]);
3541 }
3542 for (int i = 0; i < 8; ++i) {
3543 if (rd.p[i] > cycle)
3544 INFO("rd $p%i @ %i\n", i, rd.p[i]);
3545 if (wr.p[i] > cycle)
3546 INFO("wr $p%i @ %i\n", i, wr.p[i]);
3547 }
3548 if (rd.c > cycle)
3549 INFO("rd $c @ %i\n", rd.c);
3550 if (wr.c > cycle)
3551 INFO("wr $c @ %i\n", wr.c);
3552 }
3553 };
3554
3555 RegScores *score; // for current BB
3556 std::vector<RegScores> scoreBoards;
3557
3558 const TargetGM107 *targ;
3559 bool visit(Function *);
3560 bool visit(BasicBlock *);
3561
3562 void commitInsn(const Instruction *, int);
3563 int calcDelay(const Instruction *, int) const;
3564 void setDelay(Instruction *, int, const Instruction *);
3565 void recordWr(const Value *, int, int);
3566 void checkRd(const Value *, int, int&) const;
3567
3568 inline void emitYield(Instruction *);
3569 inline void emitStall(Instruction *, uint8_t);
3570 inline void emitReuse(Instruction *, uint8_t);
3571 inline void emitWrDepBar(Instruction *, uint8_t);
3572 inline void emitRdDepBar(Instruction *, uint8_t);
3573 inline void emitWtDepBar(Instruction *, uint8_t);
3574
3575 inline int getStall(const Instruction *) const;
3576 inline int getWrDepBar(const Instruction *) const;
3577 inline int getRdDepBar(const Instruction *) const;
3578 inline int getWtDepBar(const Instruction *) const;
3579
3580 void setReuseFlag(Instruction *);
3581
3582 inline void printSchedInfo(int, const Instruction *) const;
3583
3584 struct LiveBarUse {
3585 LiveBarUse(Instruction *insn, Instruction *usei)
3586 : insn(insn), usei(usei) { }
3587 Instruction *insn;
3588 Instruction *usei;
3589 };
3590
3591 struct LiveBarDef {
3592 LiveBarDef(Instruction *insn, Instruction *defi)
3593 : insn(insn), defi(defi) { }
3594 Instruction *insn;
3595 Instruction *defi;
3596 };
3597
3598 bool insertBarriers(BasicBlock *);
3599
3600 Instruction *findFirstUse(const Instruction *) const;
3601 Instruction *findFirstDef(const Instruction *) const;
3602
3603 bool needRdDepBar(const Instruction *) const;
3604 bool needWrDepBar(const Instruction *) const;
3605 };
3606
3607 inline void
3608 SchedDataCalculatorGM107::emitStall(Instruction *insn, uint8_t cnt)
3609 {
3610 assert(cnt < 16);
3611 insn->sched |= cnt;
3612 }
3613
3614 inline void
3615 SchedDataCalculatorGM107::emitYield(Instruction *insn)
3616 {
3617 insn->sched |= 1 << 4;
3618 }
3619
3620 inline void
3621 SchedDataCalculatorGM107::emitWrDepBar(Instruction *insn, uint8_t id)
3622 {
3623 assert(id < 6);
3624 if ((insn->sched & 0xe0) == 0xe0)
3625 insn->sched ^= 0xe0;
3626 insn->sched |= id << 5;
3627 }
3628
3629 inline void
3630 SchedDataCalculatorGM107::emitRdDepBar(Instruction *insn, uint8_t id)
3631 {
3632 assert(id < 6);
3633 if ((insn->sched & 0x700) == 0x700)
3634 insn->sched ^= 0x700;
3635 insn->sched |= id << 8;
3636 }
3637
3638 inline void
3639 SchedDataCalculatorGM107::emitWtDepBar(Instruction *insn, uint8_t id)
3640 {
3641 assert(id < 6);
3642 insn->sched |= 1 << (11 + id);
3643 }
3644
3645 inline void
3646 SchedDataCalculatorGM107::emitReuse(Instruction *insn, uint8_t id)
3647 {
3648 assert(id < 4);
3649 insn->sched |= 1 << (17 + id);
3650 }
3651
3652 inline void
3653 SchedDataCalculatorGM107::printSchedInfo(int cycle,
3654 const Instruction *insn) const
3655 {
3656 uint8_t st, yl, wr, rd, wt, ru;
3657
3658 st = (insn->sched & 0x00000f) >> 0;
3659 yl = (insn->sched & 0x000010) >> 4;
3660 wr = (insn->sched & 0x0000e0) >> 5;
3661 rd = (insn->sched & 0x000700) >> 8;
3662 wt = (insn->sched & 0x01f800) >> 11;
3663 ru = (insn->sched & 0x1e0000) >> 17;
3664
3665 INFO("cycle %i, (st 0x%x, yl 0x%x, wr 0x%x, rd 0x%x, wt 0x%x, ru 0x%x)\n",
3666 cycle, st, yl, wr, rd, wt, ru);
3667 }
3668
3669 inline int
3670 SchedDataCalculatorGM107::getStall(const Instruction *insn) const
3671 {
3672 return insn->sched & 0xf;
3673 }
3674
3675 inline int
3676 SchedDataCalculatorGM107::getWrDepBar(const Instruction *insn) const
3677 {
3678 return (insn->sched & 0x0000e0) >> 5;
3679 }
3680
3681 inline int
3682 SchedDataCalculatorGM107::getRdDepBar(const Instruction *insn) const
3683 {
3684 return (insn->sched & 0x000700) >> 8;
3685 }
3686
3687 inline int
3688 SchedDataCalculatorGM107::getWtDepBar(const Instruction *insn) const
3689 {
3690 return (insn->sched & 0x01f800) >> 11;
3691 }
3692
3693 // Emit the reuse flag which allows to make use of the new memory hierarchy
3694 // introduced since Maxwell, the operand reuse cache.
3695 //
3696 // It allows to reduce bank conflicts by caching operands. Each time you issue
3697 // an instruction, that flag can tell the hw which operands are going to be
3698 // re-used by the next instruction. Note that the next instruction has to use
3699 // the same GPR id in the same operand slot.
3700 void
3701 SchedDataCalculatorGM107::setReuseFlag(Instruction *insn)
3702 {
3703 Instruction *next = insn->next;
3704 BitSet defs(255, 1);
3705
3706 if (!targ->isReuseSupported(insn))
3707 return;
3708
3709 for (int d = 0; insn->defExists(d); ++d) {
3710 const Value *def = insn->def(d).rep();
3711 if (insn->def(d).getFile() != FILE_GPR)
3712 continue;
3713 if (typeSizeof(insn->dType) != 4 || def->reg.data.id == 255)
3714 continue;
3715 defs.set(def->reg.data.id);
3716 }
3717
3718 for (int s = 0; insn->srcExists(s); s++) {
3719 const Value *src = insn->src(s).rep();
3720 if (insn->src(s).getFile() != FILE_GPR)
3721 continue;
3722 if (typeSizeof(insn->sType) != 4 || src->reg.data.id == 255)
3723 continue;
3724 if (defs.test(src->reg.data.id))
3725 continue;
3726 if (!next->srcExists(s) || next->src(s).getFile() != FILE_GPR)
3727 continue;
3728 if (src->reg.data.id != next->getSrc(s)->reg.data.id)
3729 continue;
3730 assert(s < 4);
3731 emitReuse(insn, s);
3732 }
3733 }
3734
3735 void
3736 SchedDataCalculatorGM107::recordWr(const Value *v, int cycle, int ready)
3737 {
3738 int a = v->reg.data.id, b;
3739
3740 switch (v->reg.file) {
3741 case FILE_GPR:
3742 b = a + v->reg.size / 4;
3743 for (int r = a; r < b; ++r)
3744 score->rd.r[r] = ready;
3745 break;
3746 case FILE_PREDICATE:
3747 // To immediately use a predicate set by any instructions, the minimum
3748 // number of stall counts is 13.
3749 score->rd.p[a] = cycle + 13;
3750 break;
3751 case FILE_FLAGS:
3752 score->rd.c = ready;
3753 break;
3754 default:
3755 break;
3756 }
3757 }
3758
3759 void
3760 SchedDataCalculatorGM107::checkRd(const Value *v, int cycle, int &delay) const
3761 {
3762 int a = v->reg.data.id, b;
3763 int ready = cycle;
3764
3765 switch (v->reg.file) {
3766 case FILE_GPR:
3767 b = a + v->reg.size / 4;
3768 for (int r = a; r < b; ++r)
3769 ready = MAX2(ready, score->rd.r[r]);
3770 break;
3771 case FILE_PREDICATE:
3772 ready = MAX2(ready, score->rd.p[a]);
3773 break;
3774 case FILE_FLAGS:
3775 ready = MAX2(ready, score->rd.c);
3776 break;
3777 default:
3778 break;
3779 }
3780 if (cycle < ready)
3781 delay = MAX2(delay, ready - cycle);
3782 }
3783
3784 void
3785 SchedDataCalculatorGM107::commitInsn(const Instruction *insn, int cycle)
3786 {
3787 const int ready = cycle + targ->getLatency(insn);
3788
3789 for (int d = 0; insn->defExists(d); ++d)
3790 recordWr(insn->getDef(d), cycle, ready);
3791
3792 #ifdef GM107_DEBUG_SCHED_DATA
3793 score->print(cycle);
3794 #endif
3795 }
3796
3797 #define GM107_MIN_ISSUE_DELAY 0x1
3798 #define GM107_MAX_ISSUE_DELAY 0xf
3799
3800 int
3801 SchedDataCalculatorGM107::calcDelay(const Instruction *insn, int cycle) const
3802 {
3803 int delay = 0, ready = cycle;
3804
3805 for (int s = 0; insn->srcExists(s); ++s)
3806 checkRd(insn->getSrc(s), cycle, delay);
3807
3808 // TODO: make use of getReadLatency()!
3809
3810 return MAX2(delay, ready - cycle);
3811 }
3812
3813 void
3814 SchedDataCalculatorGM107::setDelay(Instruction *insn, int delay,
3815 const Instruction *next)
3816 {
3817 const OpClass cl = targ->getOpClass(insn->op);
3818 int wr, rd;
3819
3820 if (insn->op == OP_EXIT ||
3821 insn->op == OP_BAR ||
3822 insn->op == OP_MEMBAR) {
3823 delay = GM107_MAX_ISSUE_DELAY;
3824 } else
3825 if (insn->op == OP_QUADON ||
3826 insn->op == OP_QUADPOP) {
3827 delay = 0xd;
3828 } else
3829 if (cl == OPCLASS_FLOW || insn->join) {
3830 delay = 0xd;
3831 }
3832
3833 if (!next || !targ->canDualIssue(insn, next)) {
3834 delay = CLAMP(delay, GM107_MIN_ISSUE_DELAY, GM107_MAX_ISSUE_DELAY);
3835 } else {
3836 delay = 0x0; // dual-issue
3837 }
3838
3839 wr = getWrDepBar(insn);
3840 rd = getRdDepBar(insn);
3841
3842 if (delay == GM107_MIN_ISSUE_DELAY && (wr & rd) != 7) {
3843 // Barriers take one additional clock cycle to become active on top of
3844 // the clock consumed by the instruction producing it.
3845 if (!next || insn->bb != next->bb) {
3846 delay = 0x2;
3847 } else {
3848 int wt = getWtDepBar(next);
3849 if ((wt & (1 << wr)) | (wt & (1 << rd)))
3850 delay = 0x2;
3851 }
3852 }
3853
3854 emitStall(insn, delay);
3855 }
3856
3857
3858 // Return true when the given instruction needs to emit a read dependency
3859 // barrier (for WaR hazards) because it doesn't operate at a fixed latency, and
3860 // setting the maximum number of stall counts is not enough.
3861 bool
3862 SchedDataCalculatorGM107::needRdDepBar(const Instruction *insn) const
3863 {
3864 BitSet srcs(255, 1), defs(255, 1);
3865 int a, b;
3866
3867 if (!targ->isBarrierRequired(insn))
3868 return false;
3869
3870 // Do not emit a read dependency barrier when the instruction doesn't use
3871 // any GPR (like st s[0x4] 0x0) as input because it's unnecessary.
3872 for (int s = 0; insn->srcExists(s); ++s) {
3873 const Value *src = insn->src(s).rep();
3874 if (insn->src(s).getFile() != FILE_GPR)
3875 continue;
3876 if (src->reg.data.id == 255)
3877 continue;
3878
3879 a = src->reg.data.id;
3880 b = a + src->reg.size / 4;
3881 for (int r = a; r < b; ++r)
3882 srcs.set(r);
3883 }
3884
3885 if (!srcs.popCount())
3886 return false;
3887
3888 // Do not emit a read dependency barrier when the output GPRs are equal to
3889 // the input GPRs (like rcp $r0 $r0) because a write dependency barrier will
3890 // be produced and WaR hazards are prevented.
3891 for (int d = 0; insn->defExists(d); ++d) {
3892 const Value *def = insn->def(d).rep();
3893 if (insn->def(d).getFile() != FILE_GPR)
3894 continue;
3895 if (def->reg.data.id == 255)
3896 continue;
3897
3898 a = def->reg.data.id;
3899 b = a + def->reg.size / 4;
3900 for (int r = a; r < b; ++r)
3901 defs.set(r);
3902 }
3903
3904 srcs.andNot(defs);
3905 if (!srcs.popCount())
3906 return false;
3907
3908 return true;
3909 }
3910
3911 // Return true when the given instruction needs to emit a write dependency
3912 // barrier (for RaW hazards) because it doesn't operate at a fixed latency, and
3913 // setting the maximum number of stall counts is not enough. This is only legal
3914 // if the instruction output something.
3915 bool
3916 SchedDataCalculatorGM107::needWrDepBar(const Instruction *insn) const
3917 {
3918 if (!targ->isBarrierRequired(insn))
3919 return false;
3920
3921 for (int d = 0; insn->defExists(d); ++d) {
3922 if (insn->def(d).getFile() == FILE_GPR ||
3923 insn->def(d).getFile() == FILE_PREDICATE)
3924 return true;
3925 }
3926 return false;
3927 }
3928
3929 // Find the next instruction inside the same basic block which uses the output
3930 // of the given instruction in order to avoid RaW hazards.
3931 Instruction *
3932 SchedDataCalculatorGM107::findFirstUse(const Instruction *bari) const
3933 {
3934 Instruction *insn, *next;
3935 int minGPR, maxGPR;
3936
3937 if (!bari->defExists(0))
3938 return NULL;
3939
3940 minGPR = bari->def(0).rep()->reg.data.id;
3941 maxGPR = minGPR + bari->def(0).rep()->reg.size / 4 - 1;
3942
3943 for (insn = bari->next; insn != NULL; insn = next) {
3944 next = insn->next;
3945
3946 for (int s = 0; insn->srcExists(s); ++s) {
3947 const Value *src = insn->src(s).rep();
3948 if (bari->def(0).getFile() == FILE_GPR) {
3949 if (insn->src(s).getFile() != FILE_GPR ||
3950 src->reg.data.id + src->reg.size / 4 - 1 < minGPR ||
3951 src->reg.data.id > maxGPR)
3952 continue;
3953 return insn;
3954 } else
3955 if (bari->def(0).getFile() == FILE_PREDICATE) {
3956 if (insn->src(s).getFile() != FILE_PREDICATE ||
3957 src->reg.data.id != minGPR)
3958 continue;
3959 return insn;
3960 }
3961 }
3962 }
3963 return NULL;
3964 }
3965
3966 // Find the next instruction inside the same basic block which overwrites, at
3967 // least, one source of the given instruction in order to avoid WaR hazards.
3968 Instruction *
3969 SchedDataCalculatorGM107::findFirstDef(const Instruction *bari) const
3970 {
3971 Instruction *insn, *next;
3972 int minGPR, maxGPR;
3973
3974 for (insn = bari->next; insn != NULL; insn = next) {
3975 next = insn->next;
3976
3977 for (int d = 0; insn->defExists(d); ++d) {
3978 const Value *def = insn->def(d).rep();
3979 if (insn->def(d).getFile() != FILE_GPR)
3980 continue;
3981
3982 minGPR = def->reg.data.id;
3983 maxGPR = minGPR + def->reg.size / 4 - 1;
3984
3985 for (int s = 0; bari->srcExists(s); ++s) {
3986 const Value *src = bari->src(s).rep();
3987 if (bari->src(s).getFile() != FILE_GPR ||
3988 src->reg.data.id + src->reg.size / 4 - 1 < minGPR ||
3989 src->reg.data.id > maxGPR)
3990 continue;
3991 return insn;
3992 }
3993 }
3994 }
3995 return NULL;
3996 }
3997
3998 // Dependency barriers:
3999 // This pass is a bit ugly and could probably be improved by performing a
4000 // better allocation.
4001 //
4002 // The main idea is to avoid WaR and RaW hazards by emitting read/write
4003 // dependency barriers using the control codes.
4004 bool
4005 SchedDataCalculatorGM107::insertBarriers(BasicBlock *bb)
4006 {
4007 std::list<LiveBarUse> live_uses;
4008 std::list<LiveBarDef> live_defs;
4009 Instruction *insn, *next;
4010 BitSet bars(6, 1);
4011 int bar_id;
4012
4013 for (insn = bb->getEntry(); insn != NULL; insn = next) {
4014 Instruction *usei = NULL, *defi = NULL;
4015 bool need_wr_bar, need_rd_bar;
4016
4017 next = insn->next;
4018
4019 // Expire old barrier uses.
4020 for (std::list<LiveBarUse>::iterator it = live_uses.begin();
4021 it != live_uses.end();) {
4022 if (insn->serial >= it->usei->serial) {
4023 int wr = getWrDepBar(it->insn);
4024 emitWtDepBar(insn, wr);
4025 bars.clr(wr); // free barrier
4026 it = live_uses.erase(it);
4027 continue;
4028 }
4029 ++it;
4030 }
4031
4032 // Expire old barrier defs.
4033 for (std::list<LiveBarDef>::iterator it = live_defs.begin();
4034 it != live_defs.end();) {
4035 if (insn->serial >= it->defi->serial) {
4036 int rd = getRdDepBar(it->insn);
4037 emitWtDepBar(insn, rd);
4038 bars.clr(rd); // free barrier
4039 it = live_defs.erase(it);
4040 continue;
4041 }
4042 ++it;
4043 }
4044
4045 need_wr_bar = needWrDepBar(insn);
4046 need_rd_bar = needRdDepBar(insn);
4047
4048 if (need_wr_bar) {
4049 // When the instruction requires to emit a write dependency barrier
4050 // (all which write something at a variable latency), find the next
4051 // instruction which reads the outputs.
4052 usei = findFirstUse(insn);
4053
4054 // Allocate and emit a new barrier.
4055 bar_id = bars.findFreeRange(1);
4056 if (bar_id == -1)
4057 bar_id = 5;
4058 bars.set(bar_id);
4059 emitWrDepBar(insn, bar_id);
4060 if (usei)
4061 live_uses.push_back(LiveBarUse(insn, usei));
4062 }
4063
4064 if (need_rd_bar) {
4065 // When the instruction requires to emit a read dependency barrier
4066 // (all which read something at a variable latency), find the next
4067 // instruction which will write the inputs.
4068 defi = findFirstDef(insn);
4069
4070 if (usei && defi && usei->serial <= defi->serial)
4071 continue;
4072
4073 // Allocate and emit a new barrier.
4074 bar_id = bars.findFreeRange(1);
4075 if (bar_id == -1)
4076 bar_id = 5;
4077 bars.set(bar_id);
4078 emitRdDepBar(insn, bar_id);
4079 if (defi)
4080 live_defs.push_back(LiveBarDef(insn, defi));
4081 }
4082 }
4083
4084 // Remove unnecessary barrier waits.
4085 BitSet alive_bars(6, 1);
4086 for (insn = bb->getEntry(); insn != NULL; insn = next) {
4087 int wr, rd, wt;
4088
4089 next = insn->next;
4090
4091 wr = getWrDepBar(insn);
4092 rd = getRdDepBar(insn);
4093 wt = getWtDepBar(insn);
4094
4095 for (int idx = 0; idx < 6; ++idx) {
4096 if (!(wt & (1 << idx)))
4097 continue;
4098 if (!alive_bars.test(idx)) {
4099 insn->sched &= ~(1 << (11 + idx));
4100 } else {
4101 alive_bars.clr(idx);
4102 }
4103 }
4104
4105 if (wr < 6)
4106 alive_bars.set(wr);
4107 if (rd < 6)
4108 alive_bars.set(rd);
4109 }
4110
4111 return true;
4112 }
4113
4114 bool
4115 SchedDataCalculatorGM107::visit(Function *func)
4116 {
4117 ArrayList insns;
4118
4119 func->orderInstructions(insns);
4120
4121 scoreBoards.resize(func->cfg.getSize());
4122 for (size_t i = 0; i < scoreBoards.size(); ++i)
4123 scoreBoards[i].wipe();
4124 return true;
4125 }
4126
4127 bool
4128 SchedDataCalculatorGM107::visit(BasicBlock *bb)
4129 {
4130 Instruction *insn, *next = NULL;
4131 int cycle = 0;
4132
4133 for (Instruction *insn = bb->getEntry(); insn; insn = insn->next) {
4134 /*XXX*/
4135 insn->sched = 0x7e0;
4136 }
4137
4138 if (!debug_get_bool_option("NV50_PROG_SCHED", true))
4139 return true;
4140
4141 // Insert read/write dependency barriers for instructions which don't
4142 // operate at a fixed latency.
4143 insertBarriers(bb);
4144
4145 score = &scoreBoards.at(bb->getId());
4146
4147 for (Graph::EdgeIterator ei = bb->cfg.incident(); !ei.end(); ei.next()) {
4148 // back branches will wait until all target dependencies are satisfied
4149 if (ei.getType() == Graph::Edge::BACK) // sched would be uninitialized
4150 continue;
4151 BasicBlock *in = BasicBlock::get(ei.getNode());
4152 score->setMax(&scoreBoards.at(in->getId()));
4153 }
4154
4155 #ifdef GM107_DEBUG_SCHED_DATA
4156 INFO("=== BB:%i initial scores\n", bb->getId());
4157 score->print(cycle);
4158 #endif
4159
4160 // Because barriers are allocated locally (intra-BB), we have to make sure
4161 // that all produced barriers have been consumed before entering inside a
4162 // new basic block. The best way is to do a global allocation pre RA but
4163 // it's really more difficult, especially because of the phi nodes. Anyways,
4164 // it seems like that waiting on a barrier which has already been consumed
4165 // doesn't add any additional cost, it's just not elegant!
4166 Instruction *start = bb->getEntry();
4167 if (start && bb->cfg.incidentCount() > 0) {
4168 for (int b = 0; b < 6; b++)
4169 emitWtDepBar(start, b);
4170 }
4171
4172 for (insn = bb->getEntry(); insn && insn->next; insn = insn->next) {
4173 next = insn->next;
4174
4175 commitInsn(insn, cycle);
4176 int delay = calcDelay(next, cycle);
4177 setDelay(insn, delay, next);
4178 cycle += getStall(insn);
4179
4180 setReuseFlag(insn);
4181
4182 // XXX: The yield flag seems to destroy a bunch of things when it is
4183 // set on every instruction, need investigation.
4184 //emitYield(insn);
4185
4186 #ifdef GM107_DEBUG_SCHED_DATA
4187 printSchedInfo(cycle, insn);
4188 insn->print();
4189 next->print();
4190 #endif
4191 }
4192
4193 if (!insn)
4194 return true;
4195 commitInsn(insn, cycle);
4196
4197 int bbDelay = -1;
4198
4199 #ifdef GM107_DEBUG_SCHED_DATA
4200 fprintf(stderr, "last instruction is : ");
4201 insn->print();
4202 fprintf(stderr, "cycle=%d\n", cycle);
4203 #endif
4204
4205 for (Graph::EdgeIterator ei = bb->cfg.outgoing(); !ei.end(); ei.next()) {
4206 BasicBlock *out = BasicBlock::get(ei.getNode());
4207
4208 if (ei.getType() != Graph::Edge::BACK) {
4209 // Only test the first instruction of the outgoing block.
4210 next = out->getEntry();
4211 if (next) {
4212 bbDelay = MAX2(bbDelay, calcDelay(next, cycle));
4213 } else {
4214 // When the outgoing BB is empty, make sure to set the number of
4215 // stall counts needed by the instruction because we don't know the
4216 // next instruction.
4217 bbDelay = MAX2(bbDelay, targ->getLatency(insn));
4218 }
4219 } else {
4220 // Wait until all dependencies are satisfied.
4221 const int regsFree = score->getLatest();
4222 next = out->getFirst();
4223 for (int c = cycle; next && c < regsFree; next = next->next) {
4224 bbDelay = MAX2(bbDelay, calcDelay(next, c));
4225 c += getStall(next);
4226 }
4227 next = NULL;
4228 }
4229 }
4230 if (bb->cfg.outgoingCount() != 1)
4231 next = NULL;
4232 setDelay(insn, bbDelay, next);
4233 cycle += getStall(insn);
4234
4235 score->rebase(cycle); // common base for initializing out blocks' scores
4236 return true;
4237 }
4238
4239 /*******************************************************************************
4240 * main
4241 ******************************************************************************/
4242
4243 void
4244 CodeEmitterGM107::prepareEmission(Function *func)
4245 {
4246 SchedDataCalculatorGM107 sched(targGM107);
4247 CodeEmitter::prepareEmission(func);
4248 sched.run(func, true, true);
4249 }
4250
4251 static inline uint32_t sizeToBundlesGM107(uint32_t size)
4252 {
4253 return (size + 23) / 24;
4254 }
4255
4256 void
4257 CodeEmitterGM107::prepareEmission(Program *prog)
4258 {
4259 for (ArrayList::Iterator fi = prog->allFuncs.iterator();
4260 !fi.end(); fi.next()) {
4261 Function *func = reinterpret_cast<Function *>(fi.get());
4262 func->binPos = prog->binSize;
4263 prepareEmission(func);
4264
4265 // adjust sizes & positions for schedulding info:
4266 if (prog->getTarget()->hasSWSched) {
4267 uint32_t adjPos = func->binPos;
4268 BasicBlock *bb = NULL;
4269 for (int i = 0; i < func->bbCount; ++i) {
4270 bb = func->bbArray[i];
4271 int32_t adjSize = bb->binSize;
4272 if (adjPos % 32) {
4273 adjSize -= 32 - adjPos % 32;
4274 if (adjSize < 0)
4275 adjSize = 0;
4276 }
4277 adjSize = bb->binSize + sizeToBundlesGM107(adjSize) * 8;
4278 bb->binPos = adjPos;
4279 bb->binSize = adjSize;
4280 adjPos += adjSize;
4281 }
4282 if (bb)
4283 func->binSize = adjPos - func->binPos;
4284 }
4285
4286 prog->binSize += func->binSize;
4287 }
4288 }
4289
4290 CodeEmitterGM107::CodeEmitterGM107(const TargetGM107 *target)
4291 : CodeEmitter(target),
4292 targGM107(target),
4293 writeIssueDelays(target->hasSWSched)
4294 {
4295 code = NULL;
4296 codeSize = codeSizeLimit = 0;
4297 relocInfo = NULL;
4298 }
4299
4300 CodeEmitter *
4301 TargetGM107::createCodeEmitterGM107(Program::Type type)
4302 {
4303 CodeEmitterGM107 *emit = new CodeEmitterGM107(this);
4304 emit->setProgramType(type);
4305 return emit;
4306 }
4307
4308 } // namespace nv50_ir