nouveau/codegen: set dType to S32 for OP_NEG U32
authorIlia Mirkin <imirkin@alum.mit.edu>
Fri, 10 Jan 2014 22:58:37 +0000 (17:58 -0500)
committerMaarten Lankhorst <maarten.lankhorst@canonical.com>
Mon, 27 Jan 2014 15:40:42 +0000 (16:40 +0100)
It doesn't make sense to do an OP_NEG from U32 to U32. This was
manifested on nv50 in glsl-fs-atan-3 which was generating a

UMAD TEMP[0].x, TEMP[0].xxxx, -TEMP[5].xxxx, TEMP[0].xxxx

instruction. (For some reason, nvc0 causes a different shader to be
generated.) This led to a

cvt neg u32 $r1 u32 $r1

Which did not yield the desired result. This changes the final output to

cvt neg s32 $r1 u32 $r1

which produces the desired output and the piglit tests passes. My
assumption is that this is also what we want on nvc0, but could not test
as there was no suitable shader that generated the problem instruction.

Signed-off-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_nv50.cpp
src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp

index ac59187130c050178bab6076bcc6299b5a7bed05..fe428cacee44a2367017f205cf3a64bd8d9f27de 100644 (file)
@@ -808,6 +808,14 @@ CodeEmitterGK110::emitCVT(const Instruction *i)
       break;
    }
 
+   DataType dType;
+
+   if (i->op == OP_NEG && i->dType == TYPE_U32)
+      dType = TYPE_S32;
+   else
+      dType = i->dType;
+
+
    uint32_t op;
 
    if      (f2f) op = 0x254;
@@ -824,10 +832,10 @@ CodeEmitterGK110::emitCVT(const Instruction *i)
 
    emitRoundMode(rnd, 32 + 10, f2f ? (32 + 13) : -1);
 
-   code[0] |= typeSizeofLog2(i->dType) << 10;
+   code[0] |= typeSizeofLog2(dType) << 10;
    code[0] |= typeSizeofLog2(i->sType) << 12;
 
-   if (isSignedIntType(i->dType))
+   if (isSignedIntType(dType))
       code[0] |= 0x4000;
    if (isSignedIntType(i->sType))
       code[0] |= 0x8000;
index 3eca27d0bbc52140ce56c377e917e1a844316d2f..3eabfa6ae8f05e5b36a8390c19cab0f36aa0150e 100644 (file)
@@ -1106,6 +1106,7 @@ CodeEmitterNV50::emitCVT(const Instruction *i)
 {
    const bool f2f = isFloatType(i->dType) && isFloatType(i->sType);
    RoundMode rnd;
+   DataType dType;
 
    switch (i->op) {
    case OP_CEIL:  rnd = f2f ? ROUND_PI : ROUND_P; break;
@@ -1116,9 +1117,14 @@ CodeEmitterNV50::emitCVT(const Instruction *i)
       break;
    }
 
+   if (i->op == OP_NEG && i->dType == TYPE_U32)
+      dType = TYPE_S32;
+   else
+      dType = i->dType;
+
    code[0] = 0xa0000000;
 
-   switch (i->dType) {
+   switch (dType) {
    case TYPE_F64:
       switch (i->sType) {
       case TYPE_F64: code[1] = 0xc4404000; break;
index 90c409d35e6f86e3add34c6235fc2fec6782cff4..96a4af4262ebc9df772ac9b423979bc606674e1d 100644 (file)
@@ -921,6 +921,7 @@ void
 CodeEmitterNVC0::emitCVT(Instruction *i)
 {
    const bool f2f = isFloatType(i->dType) && isFloatType(i->sType);
+   DataType dType;
 
    switch (i->op) {
    case OP_CEIL:  i->rnd = f2f ? ROUND_PI : ROUND_P; break;
@@ -934,13 +935,18 @@ CodeEmitterNVC0::emitCVT(Instruction *i)
    const bool abs = (i->op == OP_ABS) || i->src(0).mod.abs();
    const bool neg = (i->op == OP_NEG) || i->src(0).mod.neg();
 
+   if (i->op == OP_NEG && i->dType == TYPE_U32)
+      dType = TYPE_S32;
+   else
+      dType = i->dType;
+
    if (i->encSize == 8) {
       emitForm_B(i, HEX64(10000000, 00000004));
 
       roundMode_C(i);
 
       // cvt u16 f32 sets high bits to 0, so we don't have to use Value::Size()
-      code[0] |= util_logbase2(typeSizeof(i->dType)) << 20;
+      code[0] |= util_logbase2(typeSizeof(dType)) << 20;
       code[0] |= util_logbase2(typeSizeof(i->sType)) << 23;
 
       if (sat)
@@ -953,12 +959,12 @@ CodeEmitterNVC0::emitCVT(Instruction *i)
       if (i->ftz)
          code[1] |= 1 << 23;
 
-      if (isSignedIntType(i->dType))
+      if (isSignedIntType(dType))
          code[0] |= 0x080;
       if (isSignedIntType(i->sType))
          code[0] |= 0x200;
 
-      if (isFloatType(i->dType)) {
+      if (isFloatType(dType)) {
          if (!isFloatType(i->sType))
             code[1] |= 0x08000000;
       } else {
@@ -971,7 +977,7 @@ CodeEmitterNVC0::emitCVT(Instruction *i)
       if (i->op == OP_CEIL || i->op == OP_FLOOR || i->op == OP_TRUNC) {
          code[0] = 0x298;
       } else
-      if (isFloatType(i->dType)) {
+      if (isFloatType(dType)) {
          if (isFloatType(i->sType))
             code[0] = 0x098;
          else