OP_VSEL,
OP_CCTL, // cache control
OP_SHFL, // warp shuffle
+ OP_VOTE,
OP_LAST
};
#define NV50_IR_SUBOP_V2(d,a,b) (((d) << 10) | ((b) << 5) | (a) | 0x4000)
#define NV50_IR_SUBOP_V4(d,a,b) (((d) << 10) | ((b) << 5) | (a) | 0x8000)
#define NV50_IR_SUBOP_Vn(n) ((n) >> 14)
+#define NV50_IR_SUBOP_VOTE_ALL 0
+#define NV50_IR_SUBOP_VOTE_ANY 1
+#define NV50_IR_SUBOP_VOTE_UNI 2
enum DataType
{
void emitFlow(const Instruction *);
+ void emitVOTE(const Instruction *);
+
inline void defId(const ValueDef&, const int pos);
inline void srcId(const ValueRef&, const int pos);
inline void srcId(const ValueRef *, const int pos);
}
}
+void
+CodeEmitterGK110::emitVOTE(const Instruction *i)
+{
+ assert(i->src(0).getFile() == FILE_PREDICATE &&
+ i->def(1).getFile() == FILE_PREDICATE);
+
+ code[0] = 0x00000002;
+ code[1] = 0x86c00000 | (i->subOp << 19);
+
+ emitPredicate(i);
+
+ defId(i->def(0), 2);
+ defId(i->def(1), 48);
+ if (i->src(0).mod == Modifier(NV50_IR_MOD_NOT))
+ code[0] |= 1 << 45;
+ srcId(i->src(0), 42);
+}
+
void
CodeEmitterGK110::emitAFETCH(const Instruction *i)
{
case OP_CCTL:
emitCCTL(insn);
break;
+ case OP_VOTE:
+ emitVOTE(insn);
+ break;
case OP_PHI:
case OP_UNION:
case OP_CONSTRAINT:
void emitOUT();
void emitMEMBAR();
+
+ void emitVOTE();
};
/*******************************************************************************
emitField(0x08, 2, insn->subOp >> 2);
}
+void
+CodeEmitterGM107::emitVOTE()
+{
+ int subOp;
+
+ assert(insn->src(0).getFile() == FILE_PREDICATE &&
+ insn->def(1).getFile() == FILE_PREDICATE);
+
+ switch (insn->subOp) {
+ case NV50_IR_SUBOP_VOTE_ANY: subOp = 1; break;
+ default:
+ assert(insn->subOp == NV50_IR_SUBOP_VOTE_ALL);
+ subOp = 0;
+ break;
+ }
+
+ emitInsn (0x50d80000);
+ emitField(0x30, 2, subOp);
+ emitGPR (0x00, insn->def(0));
+ emitPRED (0x2d, insn->def(1));
+ emitField(0x2a, 1, insn->src(0).mod == Modifier(NV50_IR_MOD_NOT));
+ emitPRED (0x27, insn->src(0));
+}
+
/*******************************************************************************
* assembler front-end
******************************************************************************/
case OP_MEMBAR:
emitMEMBAR();
break;
+ case OP_VOTE:
+ emitVOTE();
+ break;
default:
assert(!"invalid opcode");
emitNOP();
void emitPIXLD(const Instruction *);
+ void emitVOTE(const Instruction *);
+
inline void defId(const ValueDef&, const int pos);
inline void defId(const Instruction *, int d, const int pos);
inline void srcId(const ValueRef&, const int pos);
code[1] |= 0x00e00000;
}
+void
+CodeEmitterNVC0::emitVOTE(const Instruction *i)
+{
+ assert(i->src(0).getFile() == FILE_PREDICATE &&
+ i->def(1).getFile() == FILE_PREDICATE);
+
+ code[0] = 0x00000004 | (i->subOp << 5);
+ code[1] = 0x48000000;
+
+ emitPredicate(i);
+
+ defId(i->def(0), 14);
+ defId(i->def(1), 32 + 22);
+ if (i->src(0).mod == Modifier(NV50_IR_MOD_NOT))
+ code[0] |= 1 << 23;
+ srcId(i->src(0), 20);
+}
+
bool
CodeEmitterNVC0::emitInstruction(Instruction *insn)
{
case OP_PIXLD:
emitPIXLD(insn);
break;
+ case OP_VOTE:
+ emitVOTE(insn);
+ break;
case OP_PHI:
case OP_UNION:
case OP_CONSTRAINT:
"vsel",
"cctl",
"shfl",
+ "vote",
"(invalid)"
};
2, 2, 2, 2, 3, 2, // VADD, VAVG, VMIN, VMAX, VSAD, VSET,
2, 2, 2, 1, // VSHR, VSHL, VSEL, CCTL
3, // SHFL
+ 1, // VOTE
0
};
OPCLASS_VECTOR, OPCLASS_CONTROL,
// SHFL
OPCLASS_OTHER,
+ // VOTE
+ OPCLASS_OTHER,
OPCLASS_PSEUDO // LAST
};