diff options
Diffstat (limited to 'src/gallium/drivers/nouveau')
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) |