gm107/ir: add support for OP_XMAD on GM107+

v4: make the immediate field 16 bits
v5: don't ever emit h1 flags for immediates

Signed-off-by: Rhys Perry <pendingchaos02@gmail.com>
Reviewed-by: Karol Herbst <kherbst@redhat.com>
This commit is contained in:
Rhys Perry
2018-06-13 16:21:56 +01:00
parent 5d6952d2de
commit bcbcdf8448
3 changed files with 71 additions and 1 deletions
@@ -156,6 +156,7 @@ private:
void emitIMUL();
void emitIMAD();
void emitISCADD();
void emitXMAD();
void emitIMNMX();
void emitICMP();
void emitISET();
@@ -1893,6 +1894,67 @@ CodeEmitterGM107::emitISCADD()
emitGPR (0x00, insn->def(0));
}
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()
{
@@ -3267,6 +3329,9 @@ CodeEmitterGM107::emitInstruction(Instruction *i)
case OP_SHLADD:
emitISCADD();
break;
case OP_XMAD:
emitXMAD();
break;
case OP_MIN:
case OP_MAX:
if (isFloatType(insn->dType)) {
@@ -59,12 +59,15 @@ TargetGM107::isOpSupported(operation op, DataType ty) const
case OP_POW:
case OP_DIV:
case OP_MOD:
case OP_XMAD:
return false;
case OP_SQRT:
if (ty == TYPE_F64)
return false;
return chipset >= NVISA_GM200_CHIPSET;
case OP_XMAD:
if (isFloatType(ty))
return false;
break;
default:
break;
}
@@ -235,6 +238,7 @@ TargetGM107::getLatency(const Instruction *insn) const
case OP_SUB:
case OP_VOTE:
case OP_XOR:
case OP_XMAD:
if (insn->dType != TYPE_F64)
return 6;
break;
@@ -162,6 +162,7 @@ static const struct opProperties _initPropsGM107[] = {
{ 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)