[Mesa-dev] [PATCH] nv50/ir: emit VOTE instruction

Ilia Mirkin imirkin at alum.mit.edu
Thu Feb 18 00:29:25 UTC 2016


On Wed, Feb 17, 2016 at 6:16 PM, Samuel Pitoiset
<samuel.pitoiset at gmail.com> wrote:
> Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
> ---
>  src/gallium/drivers/nouveau/codegen/nv50_ir.h      |  4 ++++
>  .../drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp | 24 +++++++++++++++++++++
>  .../drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp | 25 ++++++++++++++++++++++
>  .../drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp  | 23 ++++++++++++++++++++
>  .../drivers/nouveau/codegen/nv50_ir_print.cpp      |  1 +
>  .../drivers/nouveau/codegen/nv50_ir_target.cpp     |  3 +++
>  6 files changed, 80 insertions(+)
>
> diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir.h b/src/gallium/drivers/nouveau/codegen/nv50_ir.h
> index 97ebed4..7b0eb2f 100644
> --- a/src/gallium/drivers/nouveau/codegen/nv50_ir.h
> +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir.h
> @@ -161,6 +161,7 @@ enum operation
>     OP_VSEL,
>     OP_CCTL, // cache control
>     OP_SHFL, // warp shuffle
> +   OP_VOTE,
>     OP_LAST
>  };
>
> @@ -244,6 +245,9 @@ enum operation
>  #define NV50_IR_SUBOP_V2(d,a,b)    (((d) << 10) | ((b) << 5) | (a) | 0x4000)
>  #define NV50_IR_SUBOP_V4(d,a,b)    (((d) << 10) | ((b) << 5) | (a) | 0x8000)
>  #define NV50_IR_SUBOP_Vn(n)        ((n) >> 14)
> +#define NV50_IR_SUBOP_VOTE_ALL 0
> +#define NV50_IR_SUBOP_VOTE_ANY 1
> +#define NV50_IR_SUBOP_VOTE_UNI 2
>
>  enum DataType
>  {
> diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp
> index 8268e08..349c0ee 100644
> --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp
> +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp
> @@ -128,6 +128,8 @@ private:
>
>     void emitFlow(const Instruction *);
>
> +   void emitVOTE(const Instruction *);
> +
>     inline void defId(const ValueDef&, const int pos);
>     inline void srcId(const ValueRef&, const int pos);
>     inline void srcId(const ValueRef *, const int pos);
> @@ -1371,6 +1373,25 @@ CodeEmitterGK110::emitFlow(const Instruction *i)
>  }
>
>  void
> +CodeEmitterGK110::emitVOTE(const Instruction *i)
> +{
> +   code[0] = 0x00000002;
> +   code[1] = 0x86c00000;
> +
> +   switch (i->subOp) {
> +   case NV50_IR_SUBOP_VOTE_ANY: code[1] |= (1 << 19); break;
> +   case NV50_IR_SUBOP_VOTE_UNI: code[1] |= (1 << 20); break;
> +   default:
> +      assert(i->subOp == NV50_IR_SUBOP_VOTE_ALL);
> +      break;
> +   }

aka code[1] |= i->subOp << 19 ?

> +
> +   defId(i->def(0), 2);
> +   srcId(i->src(0), 48);
> +   srcId(i->src(1), 42);

I was expecting to see a def(1) both here and GM107... and only one source.

> +}
> +
> +void
>  CodeEmitterGK110::emitAFETCH(const Instruction *i)
>  {
>     uint32_t offset = i->src(0).get()->reg.data.offset & 0x7ff;
> @@ -2054,6 +2075,9 @@ CodeEmitterGK110::emitInstruction(Instruction *insn)
>     case OP_CCTL:
>        emitCCTL(insn);
>        break;
> +   case OP_VOTE:
> +      emitVOTE(insn);
> +      break;
>     case OP_PHI:
>     case OP_UNION:
>     case OP_CONSTRAINT:
> 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 93c40d1..3113973 100644
> --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp
> +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp
> @@ -195,6 +195,8 @@ private:
>     void emitOUT();
>
>     void emitMEMBAR();
> +
> +   void emitVOTE();
>  };
>
>  /*******************************************************************************
> @@ -2653,6 +2655,26 @@ CodeEmitterGM107::emitMEMBAR()
>     emitField(0x08, 2, insn->subOp >> 2);
>  }
>
> +void
> +CodeEmitterGM107::emitVOTE()
> +{
> +   int subOp;
> +
> +   switch (insn->subOp) {
> +   case NV50_IR_SUBOP_VOTE_ANY: subOp = 1; break;
> +   default:
> +      assert(insn->subOp == NV50_IR_SUBOP_VOTE_ALL);
> +      subOp = 0;
> +      break;
> +   }
> +
> +   emitInsn (0x50d80000);
> +   emitField(0x30, 2, subOp);
> +   emitPRED (0x2d);
> +   emitGPR  (0x00, insn->def(0));
> +   emitPRED (0x27);

no sources?

> +}
> +
>  /*******************************************************************************
>   * assembler front-end
>   ******************************************************************************/
> @@ -2955,6 +2977,9 @@ CodeEmitterGM107::emitInstruction(Instruction *i)
>     case OP_MEMBAR:
>        emitMEMBAR();
>        break;
> +   case OP_VOTE:
> +      emitVOTE();
> +      break;
>     default:
>        assert(!"invalid opcode");
>        emitNOP();
> diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp
> index 8e9d9bc..4d99878 100644
> --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp
> +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp
> @@ -142,6 +142,8 @@ private:
>
>     void emitPIXLD(const Instruction *);
>
> +   void emitVOTE(const Instruction *);
> +
>     inline void defId(const ValueDef&, const int pos);
>     inline void defId(const Instruction *, int d, const int pos);
>     inline void srcId(const ValueRef&, const int pos);
> @@ -2332,6 +2334,24 @@ CodeEmitterNVC0::emitPIXLD(const Instruction *i)
>     code[1] |= 0x00e00000;
>  }
>
> +void
> +CodeEmitterNVC0::emitVOTE(const Instruction *i)
> +{
> +   assert(i->src(0).getFile() == FILE_PREDICATE &&
> +          i->def(1).getFile() == FILE_PREDICATE);
> +
> +   code[0] = 0x00000004 | (i->subOp << 5);
> +   code[1] = 0x48000000;
> +
> +   emitPredicate(i);
> +
> +   defId(i->def(0), 14);
> +   defId(i->def(1), 32 + 22);
> +   if (i->src(0).mod == Modifier(NV50_IR_MOD_NOT))
> +         code[0] |= 1 << 23;
> +   srcId(i->src(0), 20);
> +}
> +
>  bool
>  CodeEmitterNVC0::emitInstruction(Instruction *insn)
>  {
> @@ -2602,6 +2622,9 @@ CodeEmitterNVC0::emitInstruction(Instruction *insn)
>     case OP_PIXLD:
>        emitPIXLD(insn);
>        break;
> +   case OP_VOTE:
> +      emitVOTE(insn);
> +      break;
>     case OP_PHI:
>     case OP_UNION:
>     case OP_CONSTRAINT:
> diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_print.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_print.cpp
> index 85f7704..cfa85ec 100644
> --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_print.cpp
> +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_print.cpp
> @@ -190,6 +190,7 @@ const char *operationStr[OP_LAST + 1] =
>     "vsel",
>     "cctl",
>     "shfl",
> +   "vote",
>     "(invalid)"
>  };
>
> diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_target.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_target.cpp
> index 89d3a08..160e36f 100644
> --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_target.cpp
> +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_target.cpp
> @@ -55,6 +55,7 @@ const uint8_t Target::operationSrcNr[] =
>     2, 2, 2, 2, 3, 2,       // VADD, VAVG, VMIN, VMAX, VSAD, VSET,
>     2, 2, 2, 1,             // VSHR, VSHL, VSEL, CCTL
>     3,                      // SHFL
> +   1,                      // VOTE

since you say this op only has one source...

>     0
>  };
>
> @@ -129,6 +130,8 @@ const OpClass Target::operationClass[] =
>     OPCLASS_VECTOR, OPCLASS_CONTROL,
>     // SHFL
>     OPCLASS_OTHER,
> +   // VOTE
> +   OPCLASS_OTHER,
>     OPCLASS_PSEUDO // LAST
>  };
>
> --
> 2.7.1
>
> _______________________________________________
> 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