panfrost: Use nir_gather_info information about discards
[mesa.git] / src / gallium / drivers / nouveau / codegen / nv50_ir_emit_gk110.cpp
index 1121ae0912343fcf979109b7a4b9c8eda89cf32e..2118c3153f7f0ceffbf3ab7ab59ec76ee27b27d5 100644 (file)
@@ -135,6 +135,8 @@ private:
 
    void emitFlow(const Instruction *);
 
+   void emitSHFL(const Instruction *);
+
    void emitVOTE(const Instruction *);
 
    void emitSULDGB(const TexInstruction *);
@@ -205,7 +207,11 @@ bool CodeEmitterGK110::isLIMM(const ValueRef& ref, DataType ty, bool mod)
 {
    const ImmediateValue *imm = ref.get()->asImm();
 
-   return imm && (imm->reg.data.u32 & ((ty == TYPE_F32) ? 0xfff : 0xfff00000));
+   if (ty == TYPE_F32)
+      return imm && imm->reg.data.u32 & 0xfff;
+   else
+      return imm && (imm->reg.data.s32 > 0x7ffff ||
+                     imm->reg.data.s32 < -0x80000);
 }
 
 void
@@ -340,7 +346,7 @@ CodeEmitterGK110::setShortImmediate(const Instruction *i, const int s)
       code[1] |= ((u64 & 0x7fe0000000000000ULL) >> 53);
       code[1] |= ((u64 & 0x8000000000000000ULL) >> 36);
    } else {
-      assert((u32 & 0xfff00000) == 0 || (u32 & 0xfff00000) == 0xfff00000);
+      assert((u32 & 0xfff80000) == 0 || (u32 & 0xfff80000) == 0xfff80000);
       code[0] |= (u32 & 0x001ff) << 23;
       code[1] |= (u32 & 0x7fe00) >> 9;
       code[1] |= (u32 & 0x80000) << 8;
@@ -631,7 +637,7 @@ CodeEmitterGK110::emitIMUL(const Instruction *i)
    assert(!i->src(0).mod.neg() && !i->src(1).mod.neg());
    assert(!i->src(0).mod.abs() && !i->src(1).mod.abs());
 
-   if (i->src(1).getFile() == FILE_IMMEDIATE) {
+   if (isLIMM(i->src(1), TYPE_S32)) {
       emitForm_L(i, 0x280, 2, Modifier(0));
 
       if (i->subOp == NV50_IR_SUBOP_MUL_HIGH)
@@ -1565,10 +1571,62 @@ CodeEmitterGK110::emitFlow(const Instruction *i)
    }
 }
 
+void
+CodeEmitterGK110::emitSHFL(const Instruction *i)
+{
+   const ImmediateValue *imm;
+
+   code[0] = 0x00000002;
+   code[1] = 0x78800000 | (i->subOp << 1);
+
+   emitPredicate(i);
+
+   defId(i->def(0), 2);
+   srcId(i->src(0), 10);
+
+   switch (i->src(1).getFile()) {
+   case FILE_GPR:
+      srcId(i->src(1), 23);
+      break;
+   case FILE_IMMEDIATE:
+      imm = i->getSrc(1)->asImm();
+      assert(imm && imm->reg.data.u32 < 0x20);
+      code[0] |= imm->reg.data.u32 << 23;
+      code[0] |= 1 << 31;
+      break;
+   default:
+      assert(!"invalid src1 file");
+      break;
+   }
+
+   switch (i->src(2).getFile()) {
+   case FILE_GPR:
+      srcId(i->src(2), 42);
+      break;
+   case FILE_IMMEDIATE:
+      imm = i->getSrc(2)->asImm();
+      assert(imm && imm->reg.data.u32 < 0x2000);
+      code[1] |= imm->reg.data.u32 << 5;
+      code[1] |= 1;
+      break;
+   default:
+      assert(!"invalid src2 file");
+      break;
+   }
+
+   if (!i->defExists(1))
+      code[1] |= 7 << 19;
+   else {
+      assert(i->def(1).getFile() == FILE_PREDICATE);
+      defId(i->def(1), 51);
+   }
+}
+
 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);
@@ -1593,9 +1651,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
@@ -2224,6 +2297,7 @@ CodeEmitterGK110::getSRegEncoding(const ValueRef& ref)
    case SV_INVOCATION_ID: return 0x11;
    case SV_YDIR:          return 0x12;
    case SV_THREAD_KILL:   return 0x13;
+   case SV_COMBINED_TID:  return 0x20;
    case SV_TID:           return 0x21 + SDATA(ref).sv.index;
    case SV_CTAID:         return 0x25 + SDATA(ref).sv.index;
    case SV_NTID:          return 0x29 + SDATA(ref).sv.index;
@@ -2231,6 +2305,11 @@ CodeEmitterGK110::getSRegEncoding(const ValueRef& ref)
    case SV_NCTAID:        return 0x2d + SDATA(ref).sv.index;
    case SV_LBASE:         return 0x34;
    case SV_SBASE:         return 0x30;
+   case SV_LANEMASK_EQ:   return 0x38;
+   case SV_LANEMASK_LT:   return 0x39;
+   case SV_LANEMASK_LE:   return 0x3a;
+   case SV_LANEMASK_GT:   return 0x3b;
+   case SV_LANEMASK_GE:   return 0x3c;
    case SV_CLOCK:         return 0x50 + SDATA(ref).sv.index;
    default:
       assert(!"no sreg for system value");
@@ -2642,6 +2721,9 @@ CodeEmitterGK110::emitInstruction(Instruction *insn)
    case OP_CCTL:
       emitCCTL(insn);
       break;
+   case OP_SHFL:
+      emitSHFL(insn);
+      break;
    case OP_VOTE:
       emitVOTE(insn);
       break;