[Mesa-dev] [PATCH v2 2/5] gm107/ir: add support for OP_XMAD on GM107+

Karol Herbst kherbst at redhat.com
Wed Jul 18 18:12:49 UTC 2018


On Wed, Jul 18, 2018 at 7:05 PM, Rhys Perry <pendingchaos02 at gmail.com> wrote:
> Signed-off-by: Rhys Perry <pendingchaos02 at gmail.com>
> ---
>  .../drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp | 63 ++++++++++++++++++++++
>  .../nouveau/codegen/nv50_ir_target_gm107.cpp       |  6 ++-
>  .../nouveau/codegen/nv50_ir_target_nvc0.cpp        |  1 +
>  3 files changed, 69 insertions(+), 1 deletion(-)
>
> 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 694d1b10a3..caf853d58b 100644
> --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp
> +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp
> @@ -155,6 +155,7 @@ private:
>     void emitIMUL();
>     void emitIMAD();
>     void emitISCADD();
> +   void emitXMAD();
>     void emitIMNMX();
>     void emitICMP();
>     void emitISET();
> @@ -1882,6 +1883,65 @@ CodeEmitterGM107::emitISCADD()
>     emitGPR (0x08, insn->src(0));
>     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 = false;
> +      emitInsn(0x36000000);
> +      emitIMMD(0x14, 19, 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);
> +   emitField(0x32, constbuf ? 2 : 3, (insn->subOp >> 2) & 0x7);
> +
> +   emitX(constbuf ? 0x36 : 0x26);
> +   emitCC(0x2f);
> +
> +   emitGPR(0x0, insn->def(0));
> +   emitGPR(0x8, insn->src(0));
> +
> +   // source flags
> +   bool h1[2];
> +   h1[0] = insn->subOp & NV50_IR_SUBOP_XMAD_H1(0);
> +   h1[1] = insn->subOp & NV50_IR_SUBOP_XMAD_H1(1);
> +   bool isSigned = isSignedType(insn->sType);
> +   bool sext[2] = {h1[0] && isSigned, h1[1] && isSigned};
> +
> +   emitField(0x30, 2, sext[0] | (sext[1] << 1));

maybe better do this instead?:
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, h1[0]);
> +   if (!immediate)
> +      emitField(constbuf ? 0x34 : 0x23, 1, h1[1]);
> +}
>
>  void
>  CodeEmitterGM107::emitIMNMX()
> @@ -3254,6 +3314,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 24a1cbb8da..f918fbfdd3 100644
> --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_target_gm107.cpp
> +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_target_gm107.cpp
> @@ -60,8 +60,11 @@ TargetGM107::isOpSupported(operation op, DataType ty) const
>     case OP_SQRT:
>     case OP_DIV:
>     case OP_MOD:
> -   case OP_XMAD:
>        return false;
> +   case OP_XMAD:
> +      if (isFloatType(ty))
> +         return false;
> +      break;
>     default:
>        break;
>     }
> @@ -230,6 +233,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 94e98ada5e..39869e3145 100644
> --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nvc0.cpp
> +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nvc0.cpp
> @@ -161,6 +161,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)
> --
> 2.14.4
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list