2 * Copyright 2014 Red Hat Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
22 * Authors: Ben Skeggs <bskeggs@redhat.com>
25 #include "codegen/nv50_ir_target_gm107.h"
29 class CodeEmitterGM107 : public CodeEmitter
32 CodeEmitterGM107(const TargetGM107 *);
34 virtual bool emitInstruction(Instruction *);
35 virtual uint32_t getMinEncodingSize(const Instruction *) const;
37 virtual void prepareEmission(Program *);
38 virtual void prepareEmission(Function *);
40 inline void setProgramType(Program::Type pType) { progType = pType; }
43 const TargetGM107 *targGM107;
45 Program::Type progType;
47 const Instruction *insn;
48 const bool writeIssueDelays;
52 inline void emitField(uint32_t *, int, int, uint32_t);
53 inline void emitField(int b, int s, uint32_t v) { emitField(code, b, s, v); }
55 inline void emitInsn(uint32_t, bool);
56 inline void emitInsn(uint32_t o) { emitInsn(o, true); }
57 inline void emitPred();
58 inline void emitGPR(int, const Value *);
59 inline void emitGPR(int pos) {
60 emitGPR(pos, (const Value *)NULL);
62 inline void emitGPR(int pos, const ValueRef &ref) {
63 emitGPR(pos, ref.get() ? ref.rep() : (const Value *)NULL);
65 inline void emitGPR(int pos, const ValueRef *ref) {
66 emitGPR(pos, ref ? ref->rep() : (const Value *)NULL);
68 inline void emitGPR(int pos, const ValueDef &def) {
69 emitGPR(pos, def.get() ? def.rep() : (const Value *)NULL);
71 inline void emitSYS(int, const Value *);
72 inline void emitSYS(int pos, const ValueRef &ref) {
73 emitSYS(pos, ref.get() ? ref.rep() : (const Value *)NULL);
75 inline void emitPRED(int, const Value *);
76 inline void emitPRED(int pos) {
77 emitPRED(pos, (const Value *)NULL);
79 inline void emitPRED(int pos, const ValueRef &ref) {
80 emitPRED(pos, ref.get() ? ref.rep() : (const Value *)NULL);
82 inline void emitPRED(int pos, const ValueDef &def) {
83 emitPRED(pos, def.get() ? def.rep() : (const Value *)NULL);
85 inline void emitADDR(int, int, int, int, const ValueRef &);
86 inline void emitCBUF(int, int, int, int, int, const ValueRef &);
87 inline bool longIMMD(const ValueRef &);
88 inline void emitIMMD(int, int, const ValueRef &);
90 void emitCond3(int, CondCode);
91 void emitCond4(int, CondCode);
92 void emitCond5(int pos, CondCode cc) { emitCond4(pos, cc); }
93 inline void emitO(int);
94 inline void emitP(int);
95 inline void emitSAT(int);
96 inline void emitCC(int);
97 inline void emitX(int);
98 inline void emitABS(int, const ValueRef &);
99 inline void emitNEG(int, const ValueRef &);
100 inline void emitNEG2(int, const ValueRef &, const ValueRef &);
101 inline void emitFMZ(int, int);
102 inline void emitRND(int, RoundMode, int);
103 inline void emitRND(int pos) {
104 emitRND(pos, insn->rnd, -1);
106 inline void emitPDIV(int);
107 inline void emitINV(int, const ValueRef &);
166 void emitLDSTs(int, DataType);
205 /*******************************************************************************
206 * general instruction layout/fields
207 ******************************************************************************/
210 CodeEmitterGM107::emitField(uint32_t *data, int b, int s, uint32_t v)
213 uint32_t m = ((1ULL << s) - 1);
214 uint64_t d = (uint64_t)(v & m) << b;
215 assert(!(v & ~m) || (v & ~m) == ~m);
222 CodeEmitterGM107::emitPred()
224 if (insn->predSrc >= 0) {
225 emitField(16, 3, insn->getSrc(insn->predSrc)->rep()->reg.data.id);
226 emitField(19, 1, insn->cc == CC_NOT_P);
233 CodeEmitterGM107::emitInsn(uint32_t hi, bool pred)
235 code[0] = 0x00000000;
242 CodeEmitterGM107::emitGPR(int pos, const Value *val)
244 emitField(pos, 8, val ? val->reg.data.id : 255);
248 CodeEmitterGM107::emitSYS(int pos, const Value *val)
250 int id = val ? val->reg.data.id : -1;
253 case SV_LANEID : id = 0x00; break;
254 case SV_VERTEX_COUNT : id = 0x10; break;
255 case SV_INVOCATION_ID : id = 0x11; break;
256 case SV_THREAD_KILL : id = 0x13; break;
257 case SV_INVOCATION_INFO: id = 0x1d; break;
258 case SV_TID : id = 0x21 + val->reg.data.sv.index; break;
259 case SV_CTAID : id = 0x25 + val->reg.data.sv.index; break;
261 assert(!"invalid system value");
266 emitField(pos, 8, id);
270 CodeEmitterGM107::emitPRED(int pos, const Value *val)
272 emitField(pos, 3, val ? val->reg.data.id : 7);
276 CodeEmitterGM107::emitADDR(int gpr, int off, int len, int shr,
279 const Value *v = ref.get();
280 assert(!(v->reg.data.offset & ((1 << shr) - 1)));
282 emitGPR(gpr, ref.getIndirect(0));
283 emitField(off, len, v->reg.data.offset >> shr);
287 CodeEmitterGM107::emitCBUF(int buf, int gpr, int off, int len, int shr,
290 const Value *v = ref.get();
291 const Symbol *s = v->asSym();
293 assert(!(s->reg.data.offset & ((1 << shr) - 1)));
295 emitField(buf, 5, v->reg.fileIndex);
297 emitGPR(gpr, ref.getIndirect(0));
298 emitField(off, 16, s->reg.data.offset >> shr);
302 CodeEmitterGM107::longIMMD(const ValueRef &ref)
304 if (ref.getFile() == FILE_IMMEDIATE) {
305 const ImmediateValue *imm = ref.get()->asImm();
306 if (isFloatType(insn->sType)) {
307 if ((imm->reg.data.u32 & 0x00000fff) != 0x00000000)
310 if ((imm->reg.data.u32 & 0xfff00000) != 0x00000000 &&
311 (imm->reg.data.u32 & 0xfff00000) != 0xfff00000)
319 CodeEmitterGM107::emitIMMD(int pos, int len, const ValueRef &ref)
321 const ImmediateValue *imm = ref.get()->asImm();
322 uint32_t val = imm->reg.data.u32;
325 if (insn->sType == TYPE_F32 || insn->sType == TYPE_F16) {
326 assert(!(val & 0x00000fff));
328 } else if (insn->sType == TYPE_F64) {
329 assert(!(imm->reg.data.u64 & 0x00000fffffffffffULL));
330 val = imm->reg.data.u64 >> 44;
332 assert(!(val & 0xfff00000) || (val & 0xfff00000) == 0xfff00000);
333 emitField( 56, 1, (val & 0x80000) >> 19);
334 emitField(pos, len, (val & 0x7ffff));
336 emitField(pos, len, val);
340 /*******************************************************************************
342 ******************************************************************************/
345 CodeEmitterGM107::emitCond3(int pos, CondCode code)
350 case CC_FL : data = 0x00; break;
352 case CC_LT : data = 0x01; break;
354 case CC_EQ : data = 0x02; break;
356 case CC_LE : data = 0x03; break;
358 case CC_GT : data = 0x04; break;
360 case CC_NE : data = 0x05; break;
362 case CC_GE : data = 0x06; break;
363 case CC_TR : data = 0x07; break;
365 assert(!"invalid cond3");
369 emitField(pos, 3, data);
373 CodeEmitterGM107::emitCond4(int pos, CondCode code)
378 case CC_FL: data = 0x00; break;
379 case CC_LT: data = 0x01; break;
380 case CC_EQ: data = 0x02; break;
381 case CC_LE: data = 0x03; break;
382 case CC_GT: data = 0x04; break;
383 case CC_NE: data = 0x05; break;
384 case CC_GE: data = 0x06; break;
385 // case CC_NUM: data = 0x07; break;
386 // case CC_NAN: data = 0x08; break;
387 case CC_LTU: data = 0x09; break;
388 case CC_EQU: data = 0x0a; break;
389 case CC_LEU: data = 0x0b; break;
390 case CC_GTU: data = 0x0c; break;
391 case CC_NEU: data = 0x0d; break;
392 case CC_GEU: data = 0x0e; break;
393 case CC_TR: data = 0x0f; break;
395 assert(!"invalid cond4");
399 emitField(pos, 4, data);
403 CodeEmitterGM107::emitO(int pos)
405 emitField(pos, 1, insn->getSrc(0)->reg.file == FILE_SHADER_OUTPUT);
409 CodeEmitterGM107::emitP(int pos)
411 emitField(pos, 1, insn->perPatch);
415 CodeEmitterGM107::emitSAT(int pos)
417 emitField(pos, 1, insn->saturate);
421 CodeEmitterGM107::emitCC(int pos)
423 emitField(pos, 1, insn->flagsDef >= 0);
427 CodeEmitterGM107::emitX(int pos)
429 emitField(pos, 1, insn->flagsSrc >= 0);
433 CodeEmitterGM107::emitABS(int pos, const ValueRef &ref)
435 emitField(pos, 1, ref.mod.abs());
439 CodeEmitterGM107::emitNEG(int pos, const ValueRef &ref)
441 emitField(pos, 1, ref.mod.neg());
445 CodeEmitterGM107::emitNEG2(int pos, const ValueRef &a, const ValueRef &b)
447 emitField(pos, 1, a.mod.neg() ^ b.mod.neg());
451 CodeEmitterGM107::emitFMZ(int pos, int len)
453 emitField(pos, len, insn->dnz << 1 | insn->ftz);
457 CodeEmitterGM107::emitRND(int rmp, RoundMode rnd, int rip)
461 case ROUND_NI: ri = 1;
462 case ROUND_N : rm = 0; break;
463 case ROUND_MI: ri = 1;
464 case ROUND_M : rm = 1; break;
465 case ROUND_PI: ri = 1;
466 case ROUND_P : rm = 2; break;
467 case ROUND_ZI: ri = 1;
468 case ROUND_Z : rm = 3; break;
470 assert(!"invalid round mode");
473 emitField(rip, 1, ri);
474 emitField(rmp, 2, rm);
478 CodeEmitterGM107::emitPDIV(int pos)
480 assert(insn->postFactor >= -3 && insn->postFactor <= 3);
481 if (insn->postFactor > 0)
482 emitField(pos, 3, 7 - insn->postFactor);
484 emitField(pos, 3, 0 - insn->postFactor);
488 CodeEmitterGM107::emitINV(int pos, const ValueRef &ref)
490 emitField(pos, 1, !!(ref.mod & Modifier(NV50_IR_MOD_NOT)));
493 /*******************************************************************************
495 ******************************************************************************/
498 CodeEmitterGM107::emitEXIT()
500 emitInsn (0xe3000000);
501 emitCond5(0x00, CC_TR);
505 CodeEmitterGM107::emitBRA()
507 const FlowInstruction *insn = this->insn->asFlow();
510 if (insn->indirect) {
512 emitInsn(0xe2000000); // JMX
514 emitInsn(0xe2500000); // BRX
518 emitInsn(0xe2100000); // JMP
520 emitInsn(0xe2400000); // BRA
521 emitField(0x07, 1, insn->allWarp);
524 emitField(0x06, 1, insn->limit);
525 emitCond5(0x00, CC_TR);
527 if (!insn->srcExists(0) || insn->src(0).getFile() != FILE_MEMORY_CONST) {
528 int32_t pos = insn->target.bb->binPos;
529 if (writeIssueDelays && !(pos & 0x1f))
532 emitField(0x14, 24, pos - (codeSize + 8));
534 emitField(0x14, 32, pos);
536 emitCBUF (0x24, gpr, 20, 16, 0, insn->src(0));
537 emitField(0x05, 1, 1);
542 CodeEmitterGM107::emitCAL()
544 const FlowInstruction *insn = this->insn->asFlow();
546 if (insn->absolute) {
547 emitInsn(0xe2200000, 0); // JCAL
549 emitInsn(0xe2600000, 0); // CAL
552 if (!insn->srcExists(0) || insn->src(0).getFile() != FILE_MEMORY_CONST) {
554 emitField(0x14, 24, insn->target.bb->binPos - (codeSize + 8));
557 int pcAbs = targGM107->getBuiltinOffset(insn->target.builtin);
558 addReloc(RelocEntry::TYPE_BUILTIN, 0, pcAbs, 0xfff00000, 20);
559 addReloc(RelocEntry::TYPE_BUILTIN, 1, pcAbs, 0x000fffff, -12);
561 emitField(0x14, 32, insn->target.bb->binPos);
565 emitCBUF (0x24, -1, 20, 16, 0, insn->src(0));
566 emitField(0x05, 1, 1);
571 CodeEmitterGM107::emitPCNT()
573 const FlowInstruction *insn = this->insn->asFlow();
575 emitInsn(0xe2b00000, 0);
577 if (!insn->srcExists(0) || insn->src(0).getFile() != FILE_MEMORY_CONST) {
578 emitField(0x14, 24, insn->target.bb->binPos - (codeSize + 8));
580 emitCBUF (0x24, -1, 20, 16, 0, insn->src(0));
581 emitField(0x05, 1, 1);
586 CodeEmitterGM107::emitCONT()
588 emitInsn (0xe3500000);
589 emitCond5(0x00, CC_TR);
593 CodeEmitterGM107::emitPBK()
595 const FlowInstruction *insn = this->insn->asFlow();
597 emitInsn(0xe2a00000, 0);
599 if (!insn->srcExists(0) || insn->src(0).getFile() != FILE_MEMORY_CONST) {
600 emitField(0x14, 24, insn->target.bb->binPos - (codeSize + 8));
602 emitCBUF (0x24, -1, 20, 16, 0, insn->src(0));
603 emitField(0x05, 1, 1);
608 CodeEmitterGM107::emitBRK()
610 emitInsn (0xe3400000);
611 emitCond5(0x00, CC_TR);
615 CodeEmitterGM107::emitPRET()
617 const FlowInstruction *insn = this->insn->asFlow();
619 emitInsn(0xe2700000, 0);
621 if (!insn->srcExists(0) || insn->src(0).getFile() != FILE_MEMORY_CONST) {
622 emitField(0x14, 24, insn->target.bb->binPos - (codeSize + 8));
624 emitCBUF (0x24, -1, 20, 16, 0, insn->src(0));
625 emitField(0x05, 1, 1);
630 CodeEmitterGM107::emitRET()
632 emitInsn (0xe3200000);
633 emitCond5(0x00, CC_TR);
637 CodeEmitterGM107::emitSSY()
639 const FlowInstruction *insn = this->insn->asFlow();
641 emitInsn(0xe2900000, 0);
643 if (!insn->srcExists(0) || insn->src(0).getFile() != FILE_MEMORY_CONST) {
644 emitField(0x14, 24, insn->target.bb->binPos - (codeSize + 8));
646 emitCBUF (0x24, -1, 20, 16, 0, insn->src(0));
647 emitField(0x05, 1, 1);
652 CodeEmitterGM107::emitSYNC()
654 emitInsn (0xf0f80000);
655 emitCond5(0x00, CC_TR);
659 CodeEmitterGM107::emitSAM()
661 emitInsn(0xe3700000, 0);
665 CodeEmitterGM107::emitRAM()
667 emitInsn(0xe3800000, 0);
670 /*******************************************************************************
672 ******************************************************************************/
674 /*******************************************************************************
675 * movement / conversion
676 ******************************************************************************/
679 CodeEmitterGM107::emitMOV()
681 if (insn->src(0).getFile() != FILE_IMMEDIATE) {
682 switch (insn->src(0).getFile()) {
684 if (insn->def(0).getFile() == FILE_PREDICATE) {
685 emitInsn(0x5b6a0000);
688 emitInsn(0x5c980000);
690 emitGPR (0x14, insn->src(0));
692 case FILE_MEMORY_CONST:
693 emitInsn(0x4c980000);
694 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
697 emitInsn(0x38980000);
698 emitIMMD(0x14, 19, insn->src(0));
701 emitInsn(0x50880000);
702 emitPRED(0x0c, insn->src(0));
707 assert(!"bad src file");
710 if (insn->def(0).getFile() != FILE_PREDICATE &&
711 insn->src(0).getFile() != FILE_PREDICATE)
712 emitField(0x27, 4, insn->lanes);
714 emitInsn (0x01000000);
715 emitIMMD (0x14, 32, insn->src(0));
716 emitField(0x0c, 4, insn->lanes);
719 if (insn->def(0).getFile() == FILE_PREDICATE) {
721 emitPRED(0x03, insn->def(0));
724 emitGPR(0x00, insn->def(0));
729 CodeEmitterGM107::emitS2R()
731 emitInsn(0xf0c80000);
732 emitSYS (0x14, insn->src(0));
733 emitGPR (0x00, insn->def(0));
737 CodeEmitterGM107::emitF2F()
739 RoundMode rnd = insn->rnd;
742 case OP_FLOOR: rnd = ROUND_MI; break;
743 case OP_CEIL : rnd = ROUND_PI; break;
744 case OP_TRUNC: rnd = ROUND_ZI; break;
749 switch (insn->src(0).getFile()) {
751 emitInsn(0x5ca80000);
752 emitGPR (0x14, insn->src(0));
754 case FILE_MEMORY_CONST:
755 emitInsn(0x4ca80000);
756 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
759 emitInsn(0x38a80000);
760 emitIMMD(0x14, 19, insn->src(0));
763 assert(!"bad src0 file");
767 emitField(0x32, 1, (insn->op == OP_SAT) || insn->saturate);
768 emitField(0x31, 1, (insn->op == OP_ABS) || insn->src(0).mod.abs());
770 emitField(0x2d, 1, (insn->op == OP_NEG) || insn->src(0).mod.neg());
772 emitField(0x29, 1, insn->subOp);
773 emitRND (0x27, rnd, 0x2a);
774 emitField(0x0a, 2, util_logbase2(typeSizeof(insn->sType)));
775 emitField(0x08, 2, util_logbase2(typeSizeof(insn->dType)));
776 emitGPR (0x00, insn->def(0));
780 CodeEmitterGM107::emitF2I()
782 RoundMode rnd = insn->rnd;
785 case OP_FLOOR: rnd = ROUND_M; break;
786 case OP_CEIL : rnd = ROUND_P; break;
787 case OP_TRUNC: rnd = ROUND_Z; break;
792 switch (insn->src(0).getFile()) {
794 emitInsn(0x5cb00000);
795 emitGPR (0x14, insn->src(0));
797 case FILE_MEMORY_CONST:
798 emitInsn(0x4cb00000);
799 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
802 emitInsn(0x38b00000);
803 emitIMMD(0x14, 19, insn->src(0));
806 assert(!"bad src0 file");
810 emitField(0x31, 1, (insn->op == OP_ABS) || insn->src(0).mod.abs());
812 emitField(0x2d, 1, (insn->op == OP_NEG) || insn->src(0).mod.neg());
814 emitRND (0x27, rnd, 0x2a);
815 emitField(0x0c, 1, isSignedType(insn->dType));
816 emitField(0x0a, 2, util_logbase2(typeSizeof(insn->sType)));
817 emitField(0x08, 2, util_logbase2(typeSizeof(insn->dType)));
818 emitGPR (0x00, insn->def(0));
822 CodeEmitterGM107::emitI2F()
824 RoundMode rnd = insn->rnd;
827 case OP_FLOOR: rnd = ROUND_M; break;
828 case OP_CEIL : rnd = ROUND_P; break;
829 case OP_TRUNC: rnd = ROUND_Z; break;
834 switch (insn->src(0).getFile()) {
836 emitInsn(0x5cb80000);
837 emitGPR (0x14, insn->src(0));
839 case FILE_MEMORY_CONST:
840 emitInsn(0x4cb80000);
841 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
844 emitInsn(0x38b80000);
845 emitIMMD(0x14, 19, insn->src(0));
848 assert(!"bad src0 file");
852 emitField(0x31, 1, (insn->op == OP_ABS) || insn->src(0).mod.abs());
854 emitField(0x2d, 1, (insn->op == OP_NEG) || insn->src(0).mod.neg());
855 emitField(0x29, 2, insn->subOp);
856 emitRND (0x27, rnd, -1);
857 emitField(0x0d, 1, isSignedType(insn->sType));
858 emitField(0x0a, 2, util_logbase2(typeSizeof(insn->sType)));
859 emitField(0x08, 2, util_logbase2(typeSizeof(insn->dType)));
860 emitGPR (0x00, insn->def(0));
864 CodeEmitterGM107::emitI2I()
866 switch (insn->src(0).getFile()) {
868 emitInsn(0x5ce00000);
869 emitGPR (0x14, insn->src(0));
871 case FILE_MEMORY_CONST:
872 emitInsn(0x4ce00000);
873 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
876 emitInsn(0x38e00000);
877 emitIMMD(0x14, 19, insn->src(0));
880 assert(!"bad src0 file");
885 emitField(0x31, 1, (insn->op == OP_ABS) || insn->src(0).mod.abs());
887 emitField(0x2d, 1, (insn->op == OP_NEG) || insn->src(0).mod.neg());
888 emitField(0x29, 2, insn->subOp);
889 emitField(0x0d, 1, isSignedType(insn->sType));
890 emitField(0x0c, 1, isSignedType(insn->dType));
891 emitField(0x0a, 2, util_logbase2(typeSizeof(insn->sType)));
892 emitField(0x08, 2, util_logbase2(typeSizeof(insn->dType)));
893 emitGPR (0x00, insn->def(0));
897 selpFlip(const FixupEntry *entry, uint32_t *code, const FixupData& data)
899 int loc = entry->loc;
900 if (data.force_persample_interp)
901 code[loc + 1] |= 1 << 10;
903 code[loc + 1] &= ~(1 << 10);
907 CodeEmitterGM107::emitSEL()
909 switch (insn->src(1).getFile()) {
911 emitInsn(0x5ca00000);
912 emitGPR (0x14, insn->src(1));
914 case FILE_MEMORY_CONST:
915 emitInsn(0x4ca00000);
916 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
919 emitInsn(0x38a00000);
920 emitIMMD(0x14, 19, insn->src(1));
923 assert(!"bad src1 file");
927 emitINV (0x2a, insn->src(2));
928 emitPRED(0x27, insn->src(2));
929 emitGPR (0x08, insn->src(0));
930 emitGPR (0x00, insn->def(0));
932 if (insn->subOp == 1) {
933 addInterp(0, 0, selpFlip);
938 CodeEmitterGM107::emitSHFL()
942 emitInsn (0xef100000);
944 switch (insn->src(1).getFile()) {
946 emitGPR(0x14, insn->src(1));
949 emitIMMD(0x14, 5, insn->src(1));
953 assert(!"invalid src1 file");
957 /*XXX: what is this arg? hardcode immediate for now */
958 emitField(0x22, 13, 0x1c03);
962 emitField(0x1e, 2, insn->subOp);
963 emitField(0x1c, 2, type);
964 emitGPR (0x08, insn->src(0));
965 emitGPR (0x00, insn->def(0));
968 /*******************************************************************************
970 ******************************************************************************/
973 CodeEmitterGM107::emitDADD()
975 switch (insn->src(1).getFile()) {
977 emitInsn(0x5c700000);
978 emitGPR (0x14, insn->src(1));
980 case FILE_MEMORY_CONST:
981 emitInsn(0x4c700000);
982 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
985 emitInsn(0x38700000);
986 emitIMMD(0x14, 19, insn->src(1));
989 assert(!"bad src1 file");
992 emitABS(0x31, insn->src(1));
993 emitNEG(0x30, insn->src(0));
995 emitABS(0x2e, insn->src(0));
996 emitNEG(0x2d, insn->src(1));
998 if (insn->op == OP_SUB)
999 code[1] ^= 0x00002000;
1001 emitGPR(0x08, insn->src(0));
1002 emitGPR(0x00, insn->def(0));
1006 CodeEmitterGM107::emitDMUL()
1008 switch (insn->src(1).getFile()) {
1010 emitInsn(0x5c800000);
1011 emitGPR (0x14, insn->src(1));
1013 case FILE_MEMORY_CONST:
1014 emitInsn(0x4c800000);
1015 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1017 case FILE_IMMEDIATE:
1018 emitInsn(0x38800000);
1019 emitIMMD(0x14, 19, insn->src(1));
1022 assert(!"bad src1 file");
1026 emitNEG2(0x30, insn->src(0), insn->src(1));
1029 emitGPR (0x08, insn->src(0));
1030 emitGPR (0x00, insn->def(0));
1034 CodeEmitterGM107::emitDFMA()
1036 switch(insn->src(2).getFile()) {
1038 switch (insn->src(1).getFile()) {
1040 emitInsn(0x5b700000);
1041 emitGPR (0x14, insn->src(1));
1043 case FILE_MEMORY_CONST:
1044 emitInsn(0x4b700000);
1045 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1047 case FILE_IMMEDIATE:
1048 emitInsn(0x36700000);
1049 emitIMMD(0x14, 19, insn->src(1));
1052 assert(!"bad src1 file");
1055 emitGPR (0x27, insn->src(2));
1057 case FILE_MEMORY_CONST:
1058 emitInsn(0x53700000);
1059 emitGPR (0x27, insn->src(1));
1060 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(2));
1063 assert(!"bad src2 file");
1068 emitNEG (0x31, insn->src(2));
1069 emitNEG2(0x30, insn->src(0), insn->src(1));
1071 emitGPR (0x08, insn->src(0));
1072 emitGPR (0x00, insn->def(0));
1076 CodeEmitterGM107::emitDMNMX()
1078 switch (insn->src(1).getFile()) {
1080 emitInsn(0x5c500000);
1081 emitGPR (0x14, insn->src(1));
1083 case FILE_MEMORY_CONST:
1084 emitInsn(0x4c500000);
1085 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1087 case FILE_IMMEDIATE:
1088 emitInsn(0x38500000);
1089 emitIMMD(0x14, 19, insn->src(1));
1092 assert(!"bad src1 file");
1096 emitABS (0x31, insn->src(1));
1097 emitNEG (0x30, insn->src(0));
1099 emitABS (0x2e, insn->src(0));
1100 emitNEG (0x2d, insn->src(1));
1101 emitField(0x2a, 1, insn->op == OP_MAX);
1103 emitGPR (0x08, insn->src(0));
1104 emitGPR (0x00, insn->def(0));
1108 CodeEmitterGM107::emitDSET()
1110 const CmpInstruction *insn = this->insn->asCmp();
1112 switch (insn->src(1).getFile()) {
1114 emitInsn(0x59000000);
1115 emitGPR (0x14, insn->src(1));
1117 case FILE_MEMORY_CONST:
1118 emitInsn(0x49000000);
1119 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1121 case FILE_IMMEDIATE:
1122 emitInsn(0x32000000);
1123 emitIMMD(0x14, 19, insn->src(1));
1126 assert(!"bad src1 file");
1130 if (insn->op != OP_SET) {
1132 case OP_SET_AND: emitField(0x2d, 2, 0); break;
1133 case OP_SET_OR : emitField(0x2d, 2, 1); break;
1134 case OP_SET_XOR: emitField(0x2d, 2, 2); break;
1136 assert(!"invalid set op");
1139 emitPRED(0x27, insn->src(2));
1144 emitABS (0x36, insn->src(0));
1145 emitNEG (0x35, insn->src(1));
1146 emitField(0x34, 1, insn->dType == TYPE_F32);
1147 emitCond4(0x30, insn->setCond);
1149 emitABS (0x2c, insn->src(1));
1150 emitNEG (0x2b, insn->src(0));
1151 emitGPR (0x08, insn->src(0));
1152 emitGPR (0x00, insn->def(0));
1156 CodeEmitterGM107::emitDSETP()
1158 const CmpInstruction *insn = this->insn->asCmp();
1160 switch (insn->src(1).getFile()) {
1162 emitInsn(0x5b800000);
1163 emitGPR (0x14, insn->src(1));
1165 case FILE_MEMORY_CONST:
1166 emitInsn(0x4b800000);
1167 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1169 case FILE_IMMEDIATE:
1170 emitInsn(0x36800000);
1171 emitIMMD(0x14, 19, insn->src(1));
1174 assert(!"bad src1 file");
1178 if (insn->op != OP_SET) {
1180 case OP_SET_AND: emitField(0x2d, 2, 0); break;
1181 case OP_SET_OR : emitField(0x2d, 2, 1); break;
1182 case OP_SET_XOR: emitField(0x2d, 2, 2); break;
1184 assert(!"invalid set op");
1187 emitPRED(0x27, insn->src(2));
1192 emitCond4(0x30, insn->setCond);
1193 emitABS (0x2c, insn->src(1));
1194 emitNEG (0x2b, insn->src(0));
1195 emitGPR (0x08, insn->src(0));
1196 emitABS (0x07, insn->src(0));
1197 emitNEG (0x06, insn->src(1));
1198 emitPRED (0x03, insn->def(0));
1199 if (insn->defExists(1))
1200 emitPRED(0x00, insn->def(1));
1205 /*******************************************************************************
1207 ******************************************************************************/
1210 CodeEmitterGM107::emitFADD()
1212 if (!longIMMD(insn->src(1))) {
1213 switch (insn->src(1).getFile()) {
1215 emitInsn(0x5c580000);
1216 emitGPR (0x14, insn->src(1));
1218 case FILE_MEMORY_CONST:
1219 emitInsn(0x4c580000);
1220 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1222 case FILE_IMMEDIATE:
1223 emitInsn(0x38580000);
1224 emitIMMD(0x14, 19, insn->src(1));
1227 assert(!"bad src1 file");
1231 emitABS(0x31, insn->src(1));
1232 emitNEG(0x30, insn->src(0));
1234 emitABS(0x2e, insn->src(0));
1235 emitNEG(0x2d, insn->src(1));
1238 if (insn->op == OP_SUB)
1239 code[1] ^= 0x00002000;
1241 emitInsn(0x08000000);
1242 emitABS(0x39, insn->src(1));
1243 emitNEG(0x38, insn->src(0));
1245 emitABS(0x36, insn->src(0));
1246 emitNEG(0x35, insn->src(1));
1248 emitIMMD(0x14, 32, insn->src(1));
1250 if (insn->op == OP_SUB)
1251 code[1] ^= 0x00080000;
1254 emitGPR(0x08, insn->src(0));
1255 emitGPR(0x00, insn->def(0));
1259 CodeEmitterGM107::emitFMUL()
1261 if (!longIMMD(insn->src(1))) {
1262 switch (insn->src(1).getFile()) {
1264 emitInsn(0x5c680000);
1265 emitGPR (0x14, insn->src(1));
1267 case FILE_MEMORY_CONST:
1268 emitInsn(0x4c680000);
1269 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1271 case FILE_IMMEDIATE:
1272 emitInsn(0x38680000);
1273 emitIMMD(0x14, 19, insn->src(1));
1276 assert(!"bad src1 file");
1280 emitNEG2(0x30, insn->src(0), insn->src(1));
1286 emitInsn(0x1e000000);
1290 emitIMMD(0x14, 32, insn->src(1));
1291 if (insn->src(0).mod.neg() ^ insn->src(1).mod.neg())
1292 code[1] ^= 0x00080000; /* flip immd sign bit */
1295 emitGPR(0x08, insn->src(0));
1296 emitGPR(0x00, insn->def(0));
1300 CodeEmitterGM107::emitFFMA()
1302 /*XXX: ffma32i exists, but not using it as third src overlaps dst */
1303 switch(insn->src(2).getFile()) {
1305 switch (insn->src(1).getFile()) {
1307 emitInsn(0x59800000);
1308 emitGPR (0x14, insn->src(1));
1310 case FILE_MEMORY_CONST:
1311 emitInsn(0x49800000);
1312 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1314 case FILE_IMMEDIATE:
1315 emitInsn(0x32800000);
1316 emitIMMD(0x14, 19, insn->src(1));
1319 assert(!"bad src1 file");
1322 emitGPR (0x27, insn->src(2));
1324 case FILE_MEMORY_CONST:
1325 emitInsn(0x51800000);
1326 emitGPR (0x27, insn->src(1));
1327 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(2));
1330 assert(!"bad src2 file");
1335 emitNEG (0x31, insn->src(2));
1336 emitNEG2(0x30, insn->src(0), insn->src(1));
1340 emitGPR(0x08, insn->src(0));
1341 emitGPR(0x00, insn->def(0));
1345 CodeEmitterGM107::emitMUFU()
1350 case OP_COS: mufu = 0; break;
1351 case OP_SIN: mufu = 1; break;
1352 case OP_EX2: mufu = 2; break;
1353 case OP_LG2: mufu = 3; break;
1354 case OP_RCP: mufu = 4 + 2 * insn->subOp; break;
1355 case OP_RSQ: mufu = 5 + 2 * insn->subOp; break;
1357 assert(!"invalid mufu");
1361 emitInsn (0x50800000);
1363 emitNEG (0x30, insn->src(0));
1364 emitABS (0x2e, insn->src(0));
1365 emitField(0x14, 3, mufu);
1366 emitGPR (0x08, insn->src(0));
1367 emitGPR (0x00, insn->def(0));
1371 CodeEmitterGM107::emitFMNMX()
1373 switch (insn->src(1).getFile()) {
1375 emitInsn(0x5c600000);
1376 emitGPR (0x14, insn->src(1));
1378 case FILE_MEMORY_CONST:
1379 emitInsn(0x4c600000);
1380 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1382 case FILE_IMMEDIATE:
1383 emitInsn(0x38600000);
1384 emitIMMD(0x14, 19, insn->src(1));
1387 assert(!"bad src1 file");
1391 emitField(0x2a, 1, insn->op == OP_MAX);
1394 emitABS(0x31, insn->src(1));
1395 emitNEG(0x30, insn->src(0));
1397 emitABS(0x2e, insn->src(0));
1398 emitNEG(0x2d, insn->src(1));
1400 emitGPR(0x08, insn->src(0));
1401 emitGPR(0x00, insn->def(0));
1405 CodeEmitterGM107::emitRRO()
1407 switch (insn->src(0).getFile()) {
1409 emitInsn(0x5c900000);
1410 emitGPR (0x14, insn->src(0));
1412 case FILE_MEMORY_CONST:
1413 emitInsn(0x4c900000);
1414 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
1416 case FILE_IMMEDIATE:
1417 emitInsn(0x38900000);
1418 emitIMMD(0x14, 19, insn->src(0));
1421 assert(!"bad src file");
1425 emitABS (0x31, insn->src(0));
1426 emitNEG (0x2d, insn->src(0));
1427 emitField(0x27, 1, insn->op == OP_PREEX2);
1428 emitGPR (0x00, insn->def(0));
1432 CodeEmitterGM107::emitFCMP()
1434 const CmpInstruction *insn = this->insn->asCmp();
1435 CondCode cc = insn->setCond;
1437 if (insn->src(2).mod.neg())
1438 cc = reverseCondCode(cc);
1440 switch(insn->src(2).getFile()) {
1442 switch (insn->src(1).getFile()) {
1444 emitInsn(0x5ba00000);
1445 emitGPR (0x14, insn->src(1));
1447 case FILE_MEMORY_CONST:
1448 emitInsn(0x4ba00000);
1449 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1451 case FILE_IMMEDIATE:
1452 emitInsn(0x36a00000);
1453 emitIMMD(0x14, 19, insn->src(1));
1456 assert(!"bad src1 file");
1459 emitGPR (0x27, insn->src(2));
1461 case FILE_MEMORY_CONST:
1462 emitInsn(0x53a00000);
1463 emitGPR (0x27, insn->src(1));
1464 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(2));
1467 assert(!"bad src2 file");
1471 emitCond4(0x30, cc);
1473 emitGPR (0x08, insn->src(0));
1474 emitGPR (0x00, insn->def(0));
1478 CodeEmitterGM107::emitFSET()
1480 const CmpInstruction *insn = this->insn->asCmp();
1482 switch (insn->src(1).getFile()) {
1484 emitInsn(0x58000000);
1485 emitGPR (0x14, insn->src(1));
1487 case FILE_MEMORY_CONST:
1488 emitInsn(0x48000000);
1489 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1491 case FILE_IMMEDIATE:
1492 emitInsn(0x30000000);
1493 emitIMMD(0x14, 19, insn->src(1));
1496 assert(!"bad src1 file");
1500 if (insn->op != OP_SET) {
1502 case OP_SET_AND: emitField(0x2d, 2, 0); break;
1503 case OP_SET_OR : emitField(0x2d, 2, 1); break;
1504 case OP_SET_XOR: emitField(0x2d, 2, 2); break;
1506 assert(!"invalid set op");
1509 emitPRED(0x27, insn->src(2));
1515 emitABS (0x36, insn->src(0));
1516 emitNEG (0x35, insn->src(1));
1517 emitField(0x34, 1, insn->dType == TYPE_F32);
1518 emitCond4(0x30, insn->setCond);
1520 emitABS (0x2c, insn->src(1));
1521 emitNEG (0x2b, insn->src(0));
1522 emitGPR (0x08, insn->src(0));
1523 emitGPR (0x00, insn->def(0));
1527 CodeEmitterGM107::emitFSETP()
1529 const CmpInstruction *insn = this->insn->asCmp();
1531 switch (insn->src(1).getFile()) {
1533 emitInsn(0x5bb00000);
1534 emitGPR (0x14, insn->src(1));
1536 case FILE_MEMORY_CONST:
1537 emitInsn(0x4bb00000);
1538 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1540 case FILE_IMMEDIATE:
1541 emitInsn(0x36b00000);
1542 emitIMMD(0x14, 19, insn->src(1));
1545 assert(!"bad src1 file");
1549 if (insn->op != OP_SET) {
1551 case OP_SET_AND: emitField(0x2d, 2, 0); break;
1552 case OP_SET_OR : emitField(0x2d, 2, 1); break;
1553 case OP_SET_XOR: emitField(0x2d, 2, 2); break;
1555 assert(!"invalid set op");
1558 emitPRED(0x27, insn->src(2));
1563 emitCond4(0x30, insn->setCond);
1565 emitABS (0x2c, insn->src(1));
1566 emitNEG (0x2b, insn->src(0));
1567 emitGPR (0x08, insn->src(0));
1568 emitABS (0x07, insn->src(0));
1569 emitNEG (0x06, insn->src(1));
1570 emitPRED (0x03, insn->def(0));
1571 if (insn->defExists(1))
1572 emitPRED(0x00, insn->def(1));
1578 CodeEmitterGM107::emitFSWZADD()
1580 emitInsn (0x50f80000);
1584 emitField(0x26, 1, insn->lanes); /* abused for .ndv */
1585 emitField(0x1c, 8, insn->subOp);
1586 if (insn->predSrc != 1)
1587 emitGPR (0x14, insn->src(1));
1590 emitGPR (0x08, insn->src(0));
1591 emitGPR (0x00, insn->def(0));
1594 /*******************************************************************************
1596 ******************************************************************************/
1599 CodeEmitterGM107::emitLOP()
1604 case OP_AND: lop = 0; break;
1605 case OP_OR : lop = 1; break;
1606 case OP_XOR: lop = 2; break;
1608 assert(!"invalid lop");
1612 if (insn->src(1).getFile() != FILE_IMMEDIATE) {
1613 switch (insn->src(1).getFile()) {
1615 emitInsn(0x5c400000);
1616 emitGPR (0x14, insn->src(1));
1618 case FILE_MEMORY_CONST:
1619 emitInsn(0x4c400000);
1620 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1622 case FILE_IMMEDIATE:
1623 emitInsn(0x38400000);
1624 emitIMMD(0x14, 19, insn->src(1));
1627 assert(!"bad src1 file");
1633 emitField(0x29, 2, lop);
1634 emitINV (0x28, insn->src(1));
1635 emitINV (0x27, insn->src(0));
1637 emitInsn (0x04000000);
1639 emitINV (0x38, insn->src(1));
1640 emitINV (0x37, insn->src(0));
1641 emitField(0x35, 2, lop);
1643 emitIMMD (0x14, 32, insn->src(1));
1646 emitGPR (0x08, insn->src(0));
1647 emitGPR (0x00, insn->def(0));
1650 /* special-case of emitLOP(): lop pass_b dst 0 ~src */
1652 CodeEmitterGM107::emitNOT()
1654 if (!longIMMD(insn->src(0))) {
1655 switch (insn->src(0).getFile()) {
1657 emitInsn(0x5c400700);
1658 emitGPR (0x14, insn->src(0));
1660 case FILE_MEMORY_CONST:
1661 emitInsn(0x4c400700);
1662 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
1664 case FILE_IMMEDIATE:
1665 emitInsn(0x38400700);
1666 emitIMMD(0x14, 19, insn->src(0));
1669 assert(!"bad src1 file");
1674 emitInsn (0x05600000);
1675 emitIMMD (0x14, 32, insn->src(1));
1679 emitGPR(0x00, insn->def(0));
1683 CodeEmitterGM107::emitIADD()
1685 if (!longIMMD(insn->src(1))) {
1686 switch (insn->src(1).getFile()) {
1688 emitInsn(0x5c100000);
1689 emitGPR (0x14, insn->src(1));
1691 case FILE_MEMORY_CONST:
1692 emitInsn(0x4c100000);
1693 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1695 case FILE_IMMEDIATE:
1696 emitInsn(0x38100000);
1697 emitIMMD(0x14, 19, insn->src(1));
1700 assert(!"bad src1 file");
1704 emitNEG(0x31, insn->src(0));
1705 emitNEG(0x30, insn->src(1));
1709 emitInsn(0x1c000000);
1713 emitIMMD(0x14, 32, insn->src(1));
1716 if (insn->op == OP_SUB)
1717 code[1] ^= 0x00010000;
1719 emitGPR(0x08, insn->src(0));
1720 emitGPR(0x00, insn->def(0));
1724 CodeEmitterGM107::emitIMUL()
1726 if (insn->src(1).getFile() != FILE_IMMEDIATE) {
1727 switch (insn->src(1).getFile()) {
1729 emitInsn(0x5c380000);
1730 emitGPR (0x14, insn->src(1));
1732 case FILE_MEMORY_CONST:
1733 emitInsn(0x4c380000);
1734 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1736 case FILE_IMMEDIATE:
1737 emitInsn(0x38380000);
1738 emitIMMD(0x14, 19, insn->src(1));
1741 assert(!"bad src1 file");
1745 emitField(0x29, 1, isSignedType(insn->sType));
1746 emitField(0x28, 1, isSignedType(insn->dType));
1747 emitField(0x27, 1, insn->subOp == NV50_IR_SUBOP_MUL_HIGH);
1749 emitInsn (0x1f000000);
1750 emitField(0x37, 1, isSignedType(insn->sType));
1751 emitField(0x36, 1, isSignedType(insn->dType));
1752 emitField(0x35, 1, insn->subOp == NV50_IR_SUBOP_MUL_HIGH);
1754 emitIMMD (0x14, 32, insn->src(1));
1757 emitGPR(0x08, insn->src(0));
1758 emitGPR(0x00, insn->def(0));
1762 CodeEmitterGM107::emitIMAD()
1764 /*XXX: imad32i exists, but not using it as third src overlaps dst */
1765 switch(insn->src(2).getFile()) {
1767 switch (insn->src(1).getFile()) {
1769 emitInsn(0x5a000000);
1770 emitGPR (0x14, insn->src(1));
1772 case FILE_MEMORY_CONST:
1773 emitInsn(0x4a000000);
1774 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1776 case FILE_IMMEDIATE:
1777 emitInsn(0x34000000);
1778 emitIMMD(0x14, 19, insn->src(1));
1781 assert(!"bad src1 file");
1784 emitGPR (0x27, insn->src(2));
1786 case FILE_MEMORY_CONST:
1787 emitInsn(0x52000000);
1788 emitGPR (0x27, insn->src(1));
1789 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(2));
1792 assert(!"bad src2 file");
1796 emitField(0x36, 1, insn->subOp == NV50_IR_SUBOP_MUL_HIGH);
1797 emitField(0x35, 1, isSignedType(insn->sType));
1798 emitNEG (0x34, insn->src(2));
1799 emitNEG2 (0x33, insn->src(0), insn->src(1));
1802 emitField(0x30, 1, isSignedType(insn->dType));
1804 emitGPR (0x08, insn->src(0));
1805 emitGPR (0x00, insn->def(0));
1809 CodeEmitterGM107::emitIMNMX()
1811 switch (insn->src(1).getFile()) {
1813 emitInsn(0x5c200000);
1814 emitGPR (0x14, insn->src(1));
1816 case FILE_MEMORY_CONST:
1817 emitInsn(0x4c200000);
1818 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1820 case FILE_IMMEDIATE:
1821 emitInsn(0x38200000);
1822 emitIMMD(0x14, 19, insn->src(1));
1825 assert(!"bad src1 file");
1829 emitField(0x30, 1, isSignedType(insn->dType));
1831 emitField(0x2a, 1, insn->op == OP_MAX);
1833 emitGPR (0x08, insn->src(0));
1834 emitGPR (0x00, insn->def(0));
1838 CodeEmitterGM107::emitICMP()
1840 const CmpInstruction *insn = this->insn->asCmp();
1841 CondCode cc = insn->setCond;
1843 if (insn->src(2).mod.neg())
1844 cc = reverseCondCode(cc);
1846 switch(insn->src(2).getFile()) {
1848 switch (insn->src(1).getFile()) {
1850 emitInsn(0x5b400000);
1851 emitGPR (0x14, insn->src(1));
1853 case FILE_MEMORY_CONST:
1854 emitInsn(0x4b400000);
1855 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1857 case FILE_IMMEDIATE:
1858 emitInsn(0x36400000);
1859 emitIMMD(0x14, 19, insn->src(1));
1862 assert(!"bad src1 file");
1865 emitGPR (0x27, insn->src(2));
1867 case FILE_MEMORY_CONST:
1868 emitInsn(0x53400000);
1869 emitGPR (0x27, insn->src(1));
1870 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(2));
1873 assert(!"bad src2 file");
1877 emitCond3(0x31, cc);
1878 emitField(0x30, 1, isSignedType(insn->sType));
1879 emitGPR (0x08, insn->src(0));
1880 emitGPR (0x00, insn->def(0));
1884 CodeEmitterGM107::emitISET()
1886 const CmpInstruction *insn = this->insn->asCmp();
1888 switch (insn->src(1).getFile()) {
1890 emitInsn(0x5b500000);
1891 emitGPR (0x14, insn->src(1));
1893 case FILE_MEMORY_CONST:
1894 emitInsn(0x4b500000);
1895 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1897 case FILE_IMMEDIATE:
1898 emitInsn(0x36500000);
1899 emitIMMD(0x14, 19, insn->src(1));
1902 assert(!"bad src1 file");
1906 if (insn->op != OP_SET) {
1908 case OP_SET_AND: emitField(0x2d, 2, 0); break;
1909 case OP_SET_OR : emitField(0x2d, 2, 1); break;
1910 case OP_SET_XOR: emitField(0x2d, 2, 2); break;
1912 assert(!"invalid set op");
1915 emitPRED(0x27, insn->src(2));
1920 emitCond3(0x31, insn->setCond);
1921 emitField(0x30, 1, isSignedType(insn->sType));
1923 emitField(0x2c, 1, insn->dType == TYPE_F32);
1925 emitGPR (0x08, insn->src(0));
1926 emitGPR (0x00, insn->def(0));
1930 CodeEmitterGM107::emitISETP()
1932 const CmpInstruction *insn = this->insn->asCmp();
1934 switch (insn->src(1).getFile()) {
1936 emitInsn(0x5b600000);
1937 emitGPR (0x14, insn->src(1));
1939 case FILE_MEMORY_CONST:
1940 emitInsn(0x4b600000);
1941 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1943 case FILE_IMMEDIATE:
1944 emitInsn(0x36600000);
1945 emitIMMD(0x14, 19, insn->src(1));
1948 assert(!"bad src1 file");
1952 if (insn->op != OP_SET) {
1954 case OP_SET_AND: emitField(0x2d, 2, 0); break;
1955 case OP_SET_OR : emitField(0x2d, 2, 1); break;
1956 case OP_SET_XOR: emitField(0x2d, 2, 2); break;
1958 assert(!"invalid set op");
1961 emitPRED(0x27, insn->src(2));
1966 emitCond3(0x31, insn->setCond);
1967 emitField(0x30, 1, isSignedType(insn->sType));
1969 emitGPR (0x08, insn->src(0));
1970 emitPRED (0x03, insn->def(0));
1971 if (insn->defExists(1))
1972 emitPRED(0x00, insn->def(1));
1978 CodeEmitterGM107::emitSHL()
1980 switch (insn->src(1).getFile()) {
1982 emitInsn(0x5c480000);
1983 emitGPR (0x14, insn->src(1));
1985 case FILE_MEMORY_CONST:
1986 emitInsn(0x4c480000);
1987 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
1989 case FILE_IMMEDIATE:
1990 emitInsn(0x38480000);
1991 emitIMMD(0x14, 19, insn->src(1));
1994 assert(!"bad src1 file");
2000 emitField(0x27, 1, insn->subOp == NV50_IR_SUBOP_SHIFT_WRAP);
2001 emitGPR (0x08, insn->src(0));
2002 emitGPR (0x00, insn->def(0));
2006 CodeEmitterGM107::emitSHR()
2008 switch (insn->src(1).getFile()) {
2010 emitInsn(0x5c280000);
2011 emitGPR (0x14, insn->src(1));
2013 case FILE_MEMORY_CONST:
2014 emitInsn(0x4c280000);
2015 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
2017 case FILE_IMMEDIATE:
2018 emitInsn(0x38280000);
2019 emitIMMD(0x14, 19, insn->src(1));
2022 assert(!"bad src1 file");
2026 emitField(0x30, 1, isSignedType(insn->dType));
2029 emitField(0x27, 1, insn->subOp == NV50_IR_SUBOP_SHIFT_WRAP);
2030 emitGPR (0x08, insn->src(0));
2031 emitGPR (0x00, insn->def(0));
2035 CodeEmitterGM107::emitPOPC()
2037 switch (insn->src(0).getFile()) {
2039 emitInsn(0x5c080000);
2040 emitGPR (0x14, insn->src(0));
2042 case FILE_MEMORY_CONST:
2043 emitInsn(0x4c080000);
2044 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
2046 case FILE_IMMEDIATE:
2047 emitInsn(0x38080000);
2048 emitIMMD(0x14, 19, insn->src(0));
2051 assert(!"bad src1 file");
2055 emitINV(0x28, insn->src(0));
2056 emitGPR(0x00, insn->def(0));
2060 CodeEmitterGM107::emitBFI()
2062 switch(insn->src(2).getFile()) {
2064 switch (insn->src(1).getFile()) {
2066 emitInsn(0x5bf00000);
2067 emitGPR (0x14, insn->src(1));
2069 case FILE_MEMORY_CONST:
2070 emitInsn(0x4bf00000);
2071 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
2073 case FILE_IMMEDIATE:
2074 emitInsn(0x36f00000);
2075 emitIMMD(0x14, 19, insn->src(1));
2078 assert(!"bad src1 file");
2081 emitGPR (0x27, insn->src(2));
2083 case FILE_MEMORY_CONST:
2084 emitInsn(0x53f00000);
2085 emitGPR (0x27, insn->src(1));
2086 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(2));
2089 assert(!"bad src2 file");
2094 emitGPR (0x08, insn->src(0));
2095 emitGPR (0x00, insn->def(0));
2099 CodeEmitterGM107::emitBFE()
2101 switch (insn->src(1).getFile()) {
2103 emitInsn(0x5c000000);
2104 emitGPR (0x14, insn->src(1));
2106 case FILE_MEMORY_CONST:
2107 emitInsn(0x4c000000);
2108 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
2110 case FILE_IMMEDIATE:
2111 emitInsn(0x38000000);
2112 emitIMMD(0x14, 19, insn->src(1));
2115 assert(!"bad src1 file");
2119 emitField(0x30, 1, isSignedType(insn->dType));
2121 emitField(0x28, 1, insn->subOp == NV50_IR_SUBOP_EXTBF_REV);
2122 emitGPR (0x08, insn->src(0));
2123 emitGPR (0x00, insn->def(0));
2127 CodeEmitterGM107::emitFLO()
2129 switch (insn->src(0).getFile()) {
2131 emitInsn(0x5c300000);
2132 emitGPR (0x14, insn->src(0));
2134 case FILE_MEMORY_CONST:
2135 emitInsn(0x4c300000);
2136 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(0));
2138 case FILE_IMMEDIATE:
2139 emitInsn(0x38300000);
2140 emitIMMD(0x14, 19, insn->src(0));
2143 assert(!"bad src1 file");
2147 emitField(0x30, 1, isSignedType(insn->dType));
2149 emitField(0x29, 1, insn->subOp == NV50_IR_SUBOP_BFIND_SAMT);
2150 emitINV (0x28, insn->src(0));
2151 emitGPR (0x00, insn->def(0));
2154 /*******************************************************************************
2156 ******************************************************************************/
2159 CodeEmitterGM107::emitLDSTs(int pos, DataType type)
2163 switch (typeSizeof(type)) {
2164 case 1: data = isSignedType(type) ? 1 : 0; break;
2165 case 2: data = isSignedType(type) ? 3 : 2; break;
2166 case 4: data = 4; break;
2167 case 8: data = 5; break;
2168 case 16: data = 6; break;
2170 assert(!"bad type");
2174 emitField(pos, 3, data);
2178 CodeEmitterGM107::emitLDSTc(int pos)
2182 switch (insn->cache) {
2183 case CACHE_CA: mode = 0; break;
2184 case CACHE_CG: mode = 1; break;
2185 case CACHE_CS: mode = 2; break;
2186 case CACHE_CV: mode = 3; break;
2188 assert(!"invalid caching mode");
2192 emitField(pos, 2, mode);
2196 CodeEmitterGM107::emitLDC()
2198 emitInsn (0xef900000);
2199 emitLDSTs(0x30, insn->dType);
2200 emitField(0x2c, 2, insn->subOp);
2201 emitCBUF (0x24, 0x08, 0x14, 16, 0, insn->src(0));
2202 emitGPR (0x00, insn->def(0));
2206 CodeEmitterGM107::emitLDL()
2208 emitInsn (0xef400000);
2209 emitLDSTs(0x30, insn->dType);
2211 emitADDR (0x08, 0x14, 24, 0, insn->src(0));
2212 emitGPR (0x00, insn->def(0));
2216 CodeEmitterGM107::emitLDS()
2218 emitInsn (0xef480000);
2219 emitLDSTs(0x30, insn->dType);
2220 emitADDR (0x08, 0x14, 24, 0, insn->src(0));
2221 emitGPR (0x00, insn->def(0));
2225 CodeEmitterGM107::emitLD()
2227 emitInsn (0x80000000);
2230 emitLDSTs(0x35, insn->dType);
2231 emitField(0x34, 1, insn->src(0).getIndirect(0)->getSize() == 8);
2232 emitADDR (0x08, 0x14, 32, 0, insn->src(0));
2233 emitGPR (0x00, insn->def(0));
2237 CodeEmitterGM107::emitSTL()
2239 emitInsn (0xef500000);
2240 emitLDSTs(0x30, insn->dType);
2242 emitADDR (0x08, 0x14, 24, 0, insn->src(0));
2243 emitGPR (0x00, insn->src(1));
2247 CodeEmitterGM107::emitSTS()
2249 emitInsn (0xef580000);
2250 emitLDSTs(0x30, insn->dType);
2251 emitADDR (0x08, 0x14, 24, 0, insn->src(0));
2252 emitGPR (0x00, insn->src(1));
2256 CodeEmitterGM107::emitST()
2258 emitInsn (0xa0000000);
2261 emitLDSTs(0x35, insn->dType);
2262 emitField(0x34, 1, insn->src(0).getIndirect(0)->getSize() == 8);
2263 emitADDR (0x08, 0x14, 32, 0, insn->src(0));
2264 emitGPR (0x00, insn->src(1));
2268 CodeEmitterGM107::emitALD()
2270 emitInsn (0xefd80000);
2271 emitField(0x2f, 2, (insn->getDef(0)->reg.size / 4) - 1);
2272 emitGPR (0x27, insn->src(0).getIndirect(1));
2275 emitADDR (0x08, 20, 10, 0, insn->src(0));
2276 emitGPR (0x00, insn->def(0));
2280 CodeEmitterGM107::emitAST()
2282 emitInsn (0xeff00000);
2283 emitField(0x2f, 2, (typeSizeof(insn->dType) / 4) - 1);
2284 emitGPR (0x27, insn->src(0).getIndirect(1));
2286 emitADDR (0x08, 20, 10, 0, insn->src(0));
2287 emitGPR (0x00, insn->src(1));
2291 CodeEmitterGM107::emitISBERD()
2293 emitInsn(0xefd00000);
2294 emitGPR (0x08, insn->src(0));
2295 emitGPR (0x00, insn->def(0));
2299 CodeEmitterGM107::emitAL2P()
2301 emitInsn (0xefa00000);
2302 emitField(0x2f, 2, (insn->getDef(0)->reg.size / 4) - 1);
2304 emitField(0x14, 11, insn->src(0).get()->reg.data.offset);
2305 emitGPR (0x08, insn->src(0).getIndirect(0));
2306 emitGPR (0x00, insn->def(0));
2310 interpApply(const FixupEntry *entry, uint32_t *code, const FixupData& data)
2312 int ipa = entry->ipa;
2313 int reg = entry->reg;
2314 int loc = entry->loc;
2316 if (data.flatshade &&
2317 (ipa & NV50_IR_INTERP_MODE_MASK) == NV50_IR_INTERP_SC) {
2318 ipa = NV50_IR_INTERP_FLAT;
2320 } else if (data.force_persample_interp &&
2321 (ipa & NV50_IR_INTERP_SAMPLE_MASK) == NV50_IR_INTERP_DEFAULT &&
2322 (ipa & NV50_IR_INTERP_MODE_MASK) != NV50_IR_INTERP_FLAT) {
2323 ipa |= NV50_IR_INTERP_CENTROID;
2325 code[loc + 1] &= ~(0xf << 0x14);
2326 code[loc + 1] |= (ipa & 0x3) << 0x16;
2327 code[loc + 1] |= (ipa & 0xc) << (0x14 - 2);
2328 code[loc + 0] &= ~(0xff << 0x14);
2329 code[loc + 0] |= reg << 0x14;
2333 CodeEmitterGM107::emitIPA()
2335 int ipam = 0, ipas = 0;
2337 switch (insn->getInterpMode()) {
2338 case NV50_IR_INTERP_LINEAR : ipam = 0; break;
2339 case NV50_IR_INTERP_PERSPECTIVE: ipam = 1; break;
2340 case NV50_IR_INTERP_FLAT : ipam = 2; break;
2341 case NV50_IR_INTERP_SC : ipam = 3; break;
2343 assert(!"invalid ipa mode");
2347 switch (insn->getSampleMode()) {
2348 case NV50_IR_INTERP_DEFAULT : ipas = 0; break;
2349 case NV50_IR_INTERP_CENTROID: ipas = 1; break;
2350 case NV50_IR_INTERP_OFFSET : ipas = 2; break;
2352 assert(!"invalid ipa sample mode");
2356 emitInsn (0xe0000000);
2357 emitField(0x36, 2, ipam);
2358 emitField(0x34, 2, ipas);
2360 emitField(0x2f, 3, 7);
2361 emitADDR (0x08, 0x1c, 10, 0, insn->src(0));
2362 if ((code[0] & 0x0000ff00) != 0x0000ff00)
2363 code[1] |= 0x00000040; /* .idx */
2364 emitGPR(0x00, insn->def(0));
2366 if (insn->op == OP_PINTERP) {
2367 emitGPR(0x14, insn->src(1));
2368 if (insn->getSampleMode() == NV50_IR_INTERP_OFFSET)
2369 emitGPR(0x27, insn->src(2));
2370 addInterp(insn->ipa, insn->getSrc(1)->reg.data.id, interpApply);
2372 if (insn->getSampleMode() == NV50_IR_INTERP_OFFSET)
2373 emitGPR(0x27, insn->src(1));
2375 addInterp(insn->ipa, 0xff, interpApply);
2378 if (insn->getSampleMode() != NV50_IR_INTERP_OFFSET)
2383 CodeEmitterGM107::emitATOM()
2385 unsigned dType, subOp;
2387 if (insn->subOp == NV50_IR_SUBOP_ATOM_CAS) {
2388 switch (insn->dType) {
2389 case TYPE_U32: dType = 0; break;
2390 case TYPE_U64: dType = 1; break;
2391 default: assert(!"unexpected dType"); dType = 0; break;
2395 emitInsn (0xee000000);
2397 switch (insn->dType) {
2398 case TYPE_U32: dType = 0; break;
2399 case TYPE_S32: dType = 1; break;
2400 case TYPE_U64: dType = 2; break;
2401 case TYPE_F32: dType = 3; break;
2402 case TYPE_B128: dType = 4; break;
2403 case TYPE_S64: dType = 5; break;
2404 default: assert(!"unexpected dType"); dType = 0; break;
2406 if (insn->subOp == NV50_IR_SUBOP_ATOM_EXCH)
2409 subOp = insn->subOp;
2411 emitInsn (0xed000000);
2414 emitField(0x34, 4, subOp);
2415 emitField(0x31, 3, dType);
2416 emitField(0x30, 1, insn->src(0).getIndirect(0)->getSize() == 8);
2417 emitGPR (0x14, insn->src(1));
2418 emitADDR (0x08, 0x1c, 20, 0, insn->src(0));
2419 emitGPR (0x00, insn->def(0));
2423 CodeEmitterGM107::emitATOMS()
2425 unsigned dType, subOp;
2427 if (insn->subOp == NV50_IR_SUBOP_ATOM_CAS) {
2428 switch (insn->dType) {
2429 case TYPE_U32: dType = 0; break;
2430 case TYPE_U64: dType = 1; break;
2431 default: assert(!"unexpected dType"); dType = 0; break;
2435 emitInsn (0xee000000);
2436 emitField(0x34, 1, dType);
2438 switch (insn->dType) {
2439 case TYPE_U32: dType = 0; break;
2440 case TYPE_S32: dType = 1; break;
2441 case TYPE_U64: dType = 2; break;
2442 case TYPE_S64: dType = 3; break;
2443 default: assert(!"unexpected dType"); dType = 0; break;
2446 if (insn->subOp == NV50_IR_SUBOP_ATOM_EXCH)
2449 subOp = insn->subOp;
2451 emitInsn (0xec000000);
2452 emitField(0x1c, 3, dType);
2455 emitField(0x34, 4, subOp);
2456 emitGPR (0x14, insn->src(1));
2457 emitADDR (0x08, 0x12, 22, 0, insn->src(0));
2458 emitGPR (0x00, insn->def(0));
2462 CodeEmitterGM107::emitCCTL()
2465 if (insn->src(0).getFile() == FILE_MEMORY_GLOBAL) {
2466 emitInsn(0xef600000);
2469 emitInsn(0xef800000);
2472 emitField(0x34, 1, insn->src(0).getIndirect(0)->getSize() == 8);
2473 emitADDR (0x08, 0x16, width, 2, insn->src(0));
2474 emitField(0x00, 4, insn->subOp);
2477 /*******************************************************************************
2479 ******************************************************************************/
2482 CodeEmitterGM107::emitPIXLD()
2484 emitInsn (0xefe80000);
2486 emitField(0x1f, 3, insn->subOp);
2487 emitGPR (0x08, insn->src(0));
2488 emitGPR (0x00, insn->def(0));
2491 /*******************************************************************************
2493 ******************************************************************************/
2496 CodeEmitterGM107::emitTEXs(int pos)
2498 int src1 = insn->predSrc == 1 ? 2 : 1;
2499 if (insn->srcExists(src1))
2500 emitGPR(pos, insn->src(src1));
2506 CodeEmitterGM107::emitTEX()
2508 const TexInstruction *insn = this->insn->asTex();
2511 if (!insn->tex.levelZero) {
2513 case OP_TEX: lodm = 0; break;
2514 case OP_TXB: lodm = 2; break;
2515 case OP_TXL: lodm = 3; break;
2517 assert(!"invalid tex op");
2524 if (insn->tex.rIndirectSrc >= 0) {
2525 emitInsn (0xdeb80000);
2526 emitField(0x35, 2, lodm);
2527 emitField(0x24, 1, insn->tex.useOffsets == 1);
2529 emitInsn (0xc0380000);
2530 emitField(0x37, 2, lodm);
2531 emitField(0x36, 1, insn->tex.useOffsets == 1);
2532 emitField(0x24, 13, insn->tex.r);
2535 emitField(0x32, 1, insn->tex.target.isShadow());
2536 emitField(0x31, 1, insn->tex.liveOnly);
2537 emitField(0x23, 1, insn->tex.derivAll);
2538 emitField(0x1f, 4, insn->tex.mask);
2539 emitField(0x1d, 2, insn->tex.target.isCube() ? 3 :
2540 insn->tex.target.getDim() - 1);
2541 emitField(0x1c, 1, insn->tex.target.isArray());
2543 emitGPR (0x08, insn->src(0));
2544 emitGPR (0x00, insn->def(0));
2548 CodeEmitterGM107::emitTLD()
2550 const TexInstruction *insn = this->insn->asTex();
2552 if (insn->tex.rIndirectSrc >= 0) {
2553 emitInsn (0xdd380000);
2555 emitInsn (0xdc380000);
2556 emitField(0x24, 13, insn->tex.r);
2559 emitField(0x37, 1, insn->tex.levelZero == 0);
2560 emitField(0x32, 1, insn->tex.target.isMS());
2561 emitField(0x31, 1, insn->tex.liveOnly);
2562 emitField(0x23, 1, insn->tex.useOffsets == 1);
2563 emitField(0x1f, 4, insn->tex.mask);
2564 emitField(0x1d, 2, insn->tex.target.isCube() ? 3 :
2565 insn->tex.target.getDim() - 1);
2566 emitField(0x1c, 1, insn->tex.target.isArray());
2568 emitGPR (0x08, insn->src(0));
2569 emitGPR (0x00, insn->def(0));
2573 CodeEmitterGM107::emitTLD4()
2575 const TexInstruction *insn = this->insn->asTex();
2577 if (insn->tex.rIndirectSrc >= 0) {
2578 emitInsn (0xdef80000);
2579 emitField(0x26, 2, insn->tex.gatherComp);
2580 emitField(0x25, 2, insn->tex.useOffsets == 4);
2581 emitField(0x24, 2, insn->tex.useOffsets == 1);
2583 emitInsn (0xc8380000);
2584 emitField(0x38, 2, insn->tex.gatherComp);
2585 emitField(0x37, 2, insn->tex.useOffsets == 4);
2586 emitField(0x36, 2, insn->tex.useOffsets == 1);
2587 emitField(0x24, 13, insn->tex.r);
2590 emitField(0x32, 1, insn->tex.target.isShadow());
2591 emitField(0x31, 1, insn->tex.liveOnly);
2592 emitField(0x23, 1, insn->tex.derivAll);
2593 emitField(0x1f, 4, insn->tex.mask);
2594 emitField(0x1d, 2, insn->tex.target.isCube() ? 3 :
2595 insn->tex.target.getDim() - 1);
2596 emitField(0x1c, 1, insn->tex.target.isArray());
2598 emitGPR (0x08, insn->src(0));
2599 emitGPR (0x00, insn->def(0));
2603 CodeEmitterGM107::emitTXD()
2605 const TexInstruction *insn = this->insn->asTex();
2607 if (insn->tex.rIndirectSrc >= 0) {
2608 emitInsn (0xde780000);
2610 emitInsn (0xde380000);
2611 emitField(0x24, 13, insn->tex.r);
2614 emitField(0x31, 1, insn->tex.liveOnly);
2615 emitField(0x23, 1, insn->tex.useOffsets == 1);
2616 emitField(0x1f, 4, insn->tex.mask);
2617 emitField(0x1d, 2, insn->tex.target.isCube() ? 3 :
2618 insn->tex.target.getDim() - 1);
2619 emitField(0x1c, 1, insn->tex.target.isArray());
2621 emitGPR (0x08, insn->src(0));
2622 emitGPR (0x00, insn->def(0));
2626 CodeEmitterGM107::emitTMML()
2628 const TexInstruction *insn = this->insn->asTex();
2630 if (insn->tex.rIndirectSrc >= 0) {
2631 emitInsn (0xdf600000);
2633 emitInsn (0xdf580000);
2634 emitField(0x24, 13, insn->tex.r);
2637 emitField(0x31, 1, insn->tex.liveOnly);
2638 emitField(0x23, 1, insn->tex.derivAll);
2639 emitField(0x1f, 4, insn->tex.mask);
2640 emitField(0x1d, 2, insn->tex.target.isCube() ? 3 :
2641 insn->tex.target.getDim() - 1);
2642 emitField(0x1c, 1, insn->tex.target.isArray());
2644 emitGPR (0x08, insn->src(0));
2645 emitGPR (0x00, insn->def(0));
2649 CodeEmitterGM107::emitTXQ()
2651 const TexInstruction *insn = this->insn->asTex();
2654 switch (insn->tex.query) {
2655 case TXQ_DIMS : type = 0x01; break;
2656 case TXQ_TYPE : type = 0x02; break;
2657 case TXQ_SAMPLE_POSITION: type = 0x05; break;
2658 case TXQ_FILTER : type = 0x10; break;
2659 case TXQ_LOD : type = 0x12; break;
2660 case TXQ_WRAP : type = 0x14; break;
2661 case TXQ_BORDER_COLOUR : type = 0x16; break;
2663 assert(!"invalid txq query");
2667 if (insn->tex.rIndirectSrc >= 0) {
2668 emitInsn (0xdf500000);
2670 emitInsn (0xdf480000);
2671 emitField(0x24, 13, insn->tex.r);
2674 emitField(0x31, 1, insn->tex.liveOnly);
2675 emitField(0x1f, 4, insn->tex.mask);
2676 emitField(0x16, 6, type);
2677 emitGPR (0x08, insn->src(0));
2678 emitGPR (0x00, insn->def(0));
2682 CodeEmitterGM107::emitDEPBAR()
2684 emitInsn (0xf0f00000);
2685 emitField(0x1d, 1, 1); /* le */
2686 emitField(0x1a, 3, 5);
2687 emitField(0x14, 6, insn->subOp);
2688 emitField(0x00, 6, insn->subOp);
2691 /*******************************************************************************
2693 ******************************************************************************/
2696 CodeEmitterGM107::emitNOP()
2698 emitInsn(0x50b00000);
2702 CodeEmitterGM107::emitKIL()
2704 emitInsn (0xe3300000);
2705 emitCond5(0x00, CC_TR);
2709 CodeEmitterGM107::emitOUT()
2711 const int cut = insn->op == OP_RESTART || insn->subOp;
2712 const int emit = insn->op == OP_EMIT;
2714 switch (insn->src(1).getFile()) {
2716 emitInsn(0xfbe00000);
2717 emitGPR (0x14, insn->src(1));
2719 case FILE_IMMEDIATE:
2720 emitInsn(0xf6e00000);
2721 emitIMMD(0x14, 19, insn->src(1));
2723 case FILE_MEMORY_CONST:
2724 emitInsn(0xebe00000);
2725 emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
2728 assert(!"bad src1 file");
2732 emitField(0x27, 2, (cut << 1) | emit);
2733 emitGPR (0x08, insn->src(0));
2734 emitGPR (0x00, insn->def(0));
2738 CodeEmitterGM107::emitBAR()
2742 emitInsn (0xf0a80000);
2744 switch (insn->subOp) {
2745 case NV50_IR_SUBOP_BAR_RED_POPC: subop = 0x02; break;
2746 case NV50_IR_SUBOP_BAR_RED_AND: subop = 0x0a; break;
2747 case NV50_IR_SUBOP_BAR_RED_OR: subop = 0x12; break;
2748 case NV50_IR_SUBOP_BAR_ARRIVE: subop = 0x81; break;
2751 assert(insn->subOp == NV50_IR_SUBOP_BAR_SYNC);
2755 emitField(0x20, 8, subop);
2758 if (insn->src(0).getFile() == FILE_GPR) {
2759 emitGPR(0x08, insn->src(0));
2761 ImmediateValue *imm = insn->getSrc(0)->asImm();
2763 emitField(0x08, 8, imm->reg.data.u32);
2764 emitField(0x2b, 1, 1);
2768 if (insn->src(1).getFile() == FILE_GPR) {
2769 emitGPR(0x14, insn->src(1));
2771 ImmediateValue *imm = insn->getSrc(0)->asImm();
2773 emitField(0x14, 12, imm->reg.data.u32);
2774 emitField(0x2c, 1, 1);
2777 if (insn->srcExists(2) && (insn->predSrc != 2)) {
2778 emitPRED (0x27, insn->src(2));
2779 emitField(0x2a, 1, insn->src(2).mod == Modifier(NV50_IR_MOD_NOT));
2781 emitField(0x27, 3, 7);
2786 CodeEmitterGM107::emitMEMBAR()
2788 emitInsn (0xef980000);
2789 emitField(0x08, 2, insn->subOp >> 2);
2793 CodeEmitterGM107::emitVOTE()
2797 assert(insn->src(0).getFile() == FILE_PREDICATE &&
2798 insn->def(1).getFile() == FILE_PREDICATE);
2800 switch (insn->subOp) {
2801 case NV50_IR_SUBOP_VOTE_ANY: subOp = 1; break;
2803 assert(insn->subOp == NV50_IR_SUBOP_VOTE_ALL);
2808 emitInsn (0x50d80000);
2809 emitField(0x30, 2, subOp);
2810 emitGPR (0x00, insn->def(0));
2811 emitPRED (0x2d, insn->def(1));
2812 emitField(0x2a, 1, insn->src(0).mod == Modifier(NV50_IR_MOD_NOT));
2813 emitPRED (0x27, insn->src(0));
2816 /*******************************************************************************
2817 * assembler front-end
2818 ******************************************************************************/
2821 CodeEmitterGM107::emitInstruction(Instruction *i)
2823 const unsigned int size = (writeIssueDelays && !(codeSize & 0x1f)) ? 16 : 8;
2828 if (insn->encSize != 8) {
2829 ERROR("skipping undecodable instruction: "); insn->print();
2832 if (codeSize + size > codeSizeLimit) {
2833 ERROR("code emitter output buffer too small\n");
2837 if (writeIssueDelays) {
2838 int n = ((codeSize & 0x1f) / 8) - 1;
2841 data[0] = 0x00000000;
2842 data[1] = 0x00000000;
2848 emitField(data, n * 21, 21, insn->sched);
2904 if (insn->op == OP_CVT && (insn->def(0).getFile() == FILE_PREDICATE ||
2905 insn->src(0).getFile() == FILE_PREDICATE)) {
2907 } else if (isFloatType(insn->dType)) {
2908 if (isFloatType(insn->sType))
2913 if (isFloatType(insn->sType))
2924 if (isFloatType(insn->dType)) {
2925 if (insn->dType == TYPE_F64)
2934 if (isFloatType(insn->dType)) {
2935 if (insn->dType == TYPE_F64)
2945 if (isFloatType(insn->dType)) {
2946 if (insn->dType == TYPE_F64)
2956 if (isFloatType(insn->dType)) {
2957 if (insn->dType == TYPE_F64)
2984 if (isFloatType(insn->dType))
2993 if (insn->def(0).getFile() != FILE_PREDICATE) {
2994 if (isFloatType(insn->sType))
2995 if (insn->sType == TYPE_F64)
3002 if (isFloatType(insn->sType))
3003 if (insn->sType == TYPE_F64)
3035 switch (insn->src(0).getFile()) {
3036 case FILE_MEMORY_CONST : emitLDC(); break;
3037 case FILE_MEMORY_LOCAL : emitLDL(); break;
3038 case FILE_MEMORY_SHARED: emitLDS(); break;
3039 case FILE_MEMORY_GLOBAL: emitLD(); break;
3041 assert(!"invalid load");
3047 switch (insn->src(0).getFile()) {
3048 case FILE_MEMORY_LOCAL : emitSTL(); break;
3049 case FILE_MEMORY_SHARED: emitSTS(); break;
3050 case FILE_MEMORY_GLOBAL: emitST(); break;
3052 assert(!"invalid store");
3058 if (insn->src(0).getFile() == FILE_MEMORY_SHARED)
3131 assert(!"invalid opcode");
3147 CodeEmitterGM107::getMinEncodingSize(const Instruction *i) const
3152 /*******************************************************************************
3153 * sched data calculator
3154 ******************************************************************************/
3156 class SchedDataCalculatorGM107 : public Pass
3159 SchedDataCalculatorGM107(const Target *targ) : targ(targ) {}
3162 bool visit(BasicBlock *bb);
3166 SchedDataCalculatorGM107::visit(BasicBlock *bb)
3168 for (Instruction *insn = bb->getEntry(); insn; insn = insn->next) {
3170 insn->sched = 0x7e0;
3176 /*******************************************************************************
3178 ******************************************************************************/
3181 CodeEmitterGM107::prepareEmission(Function *func)
3183 SchedDataCalculatorGM107 sched(targ);
3184 CodeEmitter::prepareEmission(func);
3185 sched.run(func, true, true);
3188 static inline uint32_t sizeToBundlesGM107(uint32_t size)
3190 return (size + 23) / 24;
3194 CodeEmitterGM107::prepareEmission(Program *prog)
3196 for (ArrayList::Iterator fi = prog->allFuncs.iterator();
3197 !fi.end(); fi.next()) {
3198 Function *func = reinterpret_cast<Function *>(fi.get());
3199 func->binPos = prog->binSize;
3200 prepareEmission(func);
3202 // adjust sizes & positions for schedulding info:
3203 if (prog->getTarget()->hasSWSched) {
3204 uint32_t adjPos = func->binPos;
3205 BasicBlock *bb = NULL;
3206 for (int i = 0; i < func->bbCount; ++i) {
3207 bb = func->bbArray[i];
3208 int32_t adjSize = bb->binSize;
3210 adjSize -= 32 - adjPos % 32;
3214 adjSize = bb->binSize + sizeToBundlesGM107(adjSize) * 8;
3215 bb->binPos = adjPos;
3216 bb->binSize = adjSize;
3220 func->binSize = adjPos - func->binPos;
3223 prog->binSize += func->binSize;
3227 CodeEmitterGM107::CodeEmitterGM107(const TargetGM107 *target)
3228 : CodeEmitter(target),
3230 writeIssueDelays(target->hasSWSched)
3233 codeSize = codeSizeLimit = 0;
3238 TargetGM107::createCodeEmitterGM107(Program::Type type)
3240 CodeEmitterGM107 *emit = new CodeEmitterGM107(this);
3241 emit->setProgramType(type);
3245 } // namespace nv50_ir