summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRhys Perry <[email protected]>2018-06-13 16:21:56 +0100
committerRhys Perry <[email protected]>2018-08-27 13:56:41 +0100
commitbcbcdf84485192c0f6b44d94a423d80ba204bb4b (patch)
tree67a7354a0404753da35f91234e033b03ee9c225c
parent5d6952d2dec53c2660a57408395552629c380d35 (diff)
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 <[email protected]> Reviewed-by: Karol Herbst <[email protected]>
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp65
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_target_gm107.cpp6
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_target_nvc0.cpp1
3 files changed, 71 insertions, 1 deletions
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp
index 5e8c22cd54b..b2e22195ec5 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp
@@ -156,6 +156,7 @@ private:
void emitIMUL();
void emitIMAD();
void emitISCADD();
+ void emitXMAD();
void emitIMNMX();
void emitICMP();
void emitISET();
@@ -1894,6 +1895,67 @@ CodeEmitterGM107::emitISCADD()
}
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()) {
@@ -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)) {
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_target_gm107.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_target_gm107.cpp
index 2dd12322a89..de07ad1de89 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_target_gm107.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_target_gm107.cpp
@@ -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;
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nvc0.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nvc0.cpp
index 8e040695363..60134b445db 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nvc0.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nvc0.cpp
@@ -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)