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

Samuel Pitoiset samuel.pitoiset at gmail.com
Wed Feb 17 23:16:55 UTC 2016


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;
+   }
+
+   defId(i->def(0), 2);
+   srcId(i->src(0), 48);
+   srcId(i->src(1), 42);
+}
+
+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);
+}
+
 /*******************************************************************************
  * 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
    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



More information about the mesa-dev mailing list