nvc0/ir: Allow 0/1 immediate value as source of OP_VOTE
authorBoyan Ding <boyan.j.ding@gmail.com>
Mon, 10 Apr 2017 14:56:01 +0000 (22:56 +0800)
committerIlia Mirkin <imirkin@alum.mit.edu>
Thu, 13 Apr 2017 06:24:59 +0000 (02:24 -0400)
Implementation of readFirstInvocationARB() on nvidia hardware needs a
ballotARB(true) used to decide the first active thread. This expressed
in gm107 asm as (supposing output is $r0):
vote any $r0 0x1 0x1

To model the always true input, which corresponds to the second 0x1
above, we make OP_VOTE accept immediate value 0/1 and emit "0x1" and
"not 0x1" in the src field respectively.

v2: Make sure that asImm() is not NULL (Samuel Pitoiset)

v3: (Ilia Mirkin)
Make the handling more symmetric with predicate version in gm107
Use i->getSrc(s)

Signed-off-by: Boyan Ding <boyan.j.ding@gmail.com>
Reviewed-by: Ilia Mirkin <imirkin@alum.mit.edu>
src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp
src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp
src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp

index 2a6c773ba25b2788b8f6df5dc0249f49da6a3f9e..f2efb0c60bb23e2a8114e077426b3cd99970ca2d 100644 (file)
@@ -1621,7 +1621,8 @@ CodeEmitterGK110::emitSHFL(const Instruction *i)
 void
 CodeEmitterGK110::emitVOTE(const Instruction *i)
 {
-   assert(i->src(0).getFile() == FILE_PREDICATE);
+   const ImmediateValue *imm;
+   uint32_t u32;
 
    code[0] = 0x00000002;
    code[1] = 0x86c00000 | (i->subOp << 19);
@@ -1646,9 +1647,24 @@ CodeEmitterGK110::emitVOTE(const Instruction *i)
       code[0] |= 255 << 2;
    if (!(rp & 2))
       code[1] |= 7 << 16;
-   if (i->src(0).mod == Modifier(NV50_IR_MOD_NOT))
-      code[1] |= 1 << 13;
-   srcId(i->src(0), 42);
+
+   switch (i->src(0).getFile()) {
+   case FILE_PREDICATE:
+      if (i->src(0).mod == Modifier(NV50_IR_MOD_NOT))
+         code[0] |= 1 << 13;
+      srcId(i->src(0), 42);
+      break;
+   case FILE_IMMEDIATE:
+      imm = i->getSrc(0)->asImm();
+      assert(imm);
+      u32 = imm->reg.data.u32;
+      assert(u32 == 0 || u32 == 1);
+      code[1] |= (u32 == 1 ? 0x7 : 0xf) << 10;
+      break;
+   default:
+      assert(!"Unhandled src");
+      break;
+   }
 }
 
 void
index 944563c93cf0fbaefddff77a82e4367ad40a2883..b1645265565174d59e2148c88e9b5766fcd6d555 100644 (file)
@@ -2931,7 +2931,8 @@ CodeEmitterGM107::emitMEMBAR()
 void
 CodeEmitterGM107::emitVOTE()
 {
-   assert(insn->src(0).getFile() == FILE_PREDICATE);
+   const ImmediateValue *imm;
+   uint32_t u32;
 
    int r = -1, p = -1;
    for (int i = 0; insn->defExists(i); i++) {
@@ -2951,8 +2952,24 @@ CodeEmitterGM107::emitVOTE()
       emitPRED (0x2d, insn->def(p));
    else
       emitPRED (0x2d);
-   emitField(0x2a, 1, insn->src(0).mod == Modifier(NV50_IR_MOD_NOT));
-   emitPRED (0x27, insn->src(0));
+
+   switch (insn->src(0).getFile()) {
+   case FILE_PREDICATE:
+      emitField(0x2a, 1, insn->src(0).mod == Modifier(NV50_IR_MOD_NOT));
+      emitPRED (0x27, insn->src(0));
+      break;
+   case FILE_IMMEDIATE:
+      imm = insn->getSrc(0)->asImm();
+      assert(imm);
+      u32 = imm->reg.data.u32;
+      assert(u32 == 0 || u32 == 1);
+      emitPRED(0x27);
+      emitField(0x2a, 1, u32 == 0);
+      break;
+   default:
+      assert(!"Unhandled src");
+      break;
+   }
 }
 
 void
index f4c39a168bed810c3617194fb5500b31a0386597..5ca8672054472b8a6eb6f7458918837aaa614c4e 100644 (file)
@@ -2583,7 +2583,8 @@ CodeEmitterNVC0::emitSHFL(const Instruction *i)
 void
 CodeEmitterNVC0::emitVOTE(const Instruction *i)
 {
-   assert(i->src(0).getFile() == FILE_PREDICATE);
+   const ImmediateValue *imm;
+   uint32_t u32;
 
    code[0] = 0x00000004 | (i->subOp << 5);
    code[1] = 0x48000000;
@@ -2608,9 +2609,24 @@ CodeEmitterNVC0::emitVOTE(const Instruction *i)
       code[0] |= 63 << 14;
    if (!(rp & 2))
       code[1] |= 7 << 22;
-   if (i->src(0).mod == Modifier(NV50_IR_MOD_NOT))
-      code[0] |= 1 << 23;
-   srcId(i->src(0), 20);
+
+   switch (i->src(0).getFile()) {
+   case FILE_PREDICATE:
+      if (i->src(0).mod == Modifier(NV50_IR_MOD_NOT))
+         code[0] |= 1 << 23;
+      srcId(i->src(0), 20);
+      break;
+   case FILE_IMMEDIATE:
+      imm = i->getSrc(0)->asImm();
+      assert(imm);
+      u32 = imm->reg.data.u32;
+      assert(u32 == 0 || u32 == 1);
+      code[0] |= (u32 == 1 ? 0x7 : 0xf) << 20;
+      break;
+   default:
+      assert(!"Unhandled src");
+      break;
+   }
 }
 
 bool