void emitIMUL();
void emitIMAD();
void emitISCADD();
+ void emitXMAD();
void emitIMNMX();
void emitICMP();
void emitISET();
}
void
+CodeEmitterGM107::emitXMAD()
+{
+ assert(insn->src(0).getFile() == FILE_GPR);
+
+ bool constbuf = false;
+ bool psl_mrg = true;
+ bool immediate = false;
+ if (insn->src(2).getFile() == FILE_MEMORY_CONST) {
+ assert(insn->src(1).getFile() == FILE_GPR);
+ constbuf = true;
+ psl_mrg = false;
+ emitInsn(0x51000000);
+ emitGPR(0x27, insn->src(1));
+ emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(2));
+ } else if (insn->src(1).getFile() == FILE_MEMORY_CONST) {
+ assert(insn->src(2).getFile() == FILE_GPR);
+ constbuf = true;
+ emitInsn(0x4e000000);
+ emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1));
+ emitGPR(0x27, insn->src(2));
+ } else if (insn->src(1).getFile() == FILE_IMMEDIATE) {
+ assert(insn->src(2).getFile() == FILE_GPR);
+ assert(!(insn->subOp & NV50_IR_SUBOP_XMAD_H1(1)));
+ immediate = true;
+ emitInsn(0x36000000);
+ emitIMMD(0x14, 16, insn->src(1));
+ emitGPR(0x27, insn->src(2));
+ } else {
+ assert(insn->src(1).getFile() == FILE_GPR);
+ assert(insn->src(2).getFile() == FILE_GPR);
+ emitInsn(0x5b000000);
+ emitGPR(0x14, insn->src(1));
+ emitGPR(0x27, insn->src(2));
+ }
+
+ if (psl_mrg)
+ emitField(constbuf ? 0x37 : 0x24, 2, insn->subOp & 0x3);
+
+ unsigned cmode = (insn->subOp & NV50_IR_SUBOP_XMAD_CMODE_MASK);
+ cmode >>= NV50_IR_SUBOP_XMAD_CMODE_SHIFT;
+ emitField(0x32, constbuf ? 2 : 3, cmode);
+
+ emitX(constbuf ? 0x36 : 0x26);
+ emitCC(0x2f);
+
+ emitGPR(0x0, insn->def(0));
+ emitGPR(0x8, insn->src(0));
+
+ // source flags
+ if (isSignedType(insn->sType)) {
+ uint16_t h1s = insn->subOp & NV50_IR_SUBOP_XMAD_H1_MASK;
+ emitField(0x30, 2, h1s >> NV50_IR_SUBOP_XMAD_H1_SHIFT);
+ }
+ emitField(0x35, 1, insn->subOp & NV50_IR_SUBOP_XMAD_H1(0) ? 1 : 0);
+ if (!immediate) {
+ bool h1 = insn->subOp & NV50_IR_SUBOP_XMAD_H1(1);
+ emitField(constbuf ? 0x34 : 0x23, 1, h1);
+ }
+}
+
+void
CodeEmitterGM107::emitIMNMX()
{
switch (insn->src(1).getFile()) {
case OP_SHLADD:
emitISCADD();
break;
+ case OP_XMAD:
+ emitXMAD();
+ break;
case OP_MIN:
case OP_MAX:
if (isFloatType(insn->dType)) {
{ OP_SUSTP, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4 },
{ OP_SUREDB, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4 },
{ OP_SUREDP, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4 },
+ { OP_XMAD, 0x0, 0x0, 0x0, 0x0, 0x6, 0x2 },
};
void TargetNVC0::initProps(const struct opProperties *props, int size)