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:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user