nvc0/ir: don't require AND when the high byte is being addressed
authorIlia Mirkin <imirkin@alum.mit.edu>
Wed, 19 Aug 2015 02:53:11 +0000 (22:53 -0400)
committerIlia Mirkin <imirkin@alum.mit.edu>
Thu, 20 Aug 2015 21:58:30 +0000 (17:58 -0400)
unpackUnorm* lowering doesn't AND the high byte/word as it's
unnecessary. Detect that situation as well.

Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp

index ef286c0ab384ff5c8fb23ac9c37c4a8796416f9c..cf83c19056eb3f8f092034452fb1dc9609be0991 100644 (file)
@@ -1532,6 +1532,7 @@ AlgebraicOpt::handleCVT_NEG(Instruction *cvt)
 // CVT(EXTBF(x, byte/word))
 // CVT(AND(bytemask, x))
 // CVT(AND(bytemask, SHR(x, 8/16/24)))
+// CVT(SHR(x, 16/24))
 void
 AlgebraicOpt::handleCVT_EXTBF(Instruction *cvt)
 {
@@ -1578,6 +1579,17 @@ AlgebraicOpt::handleCVT_EXTBF(Instruction *cvt)
          arg = shift->getSrc(0);
          offset = imm1.reg.data.u32;
       }
+   } else if (insn->op == OP_SHR && insn->src(1).getImmediate(imm0)) {
+      arg = insn->getSrc(0);
+      if (imm0.reg.data.u32 == 24) {
+         width = 8;
+         offset = 24;
+      } else if (imm0.reg.data.u32 == 16) {
+         width = 16;
+         offset = 16;
+      } else {
+         return;
+      }
    }
 
    if (!arg)