nv50/ir/gk110: fix handling of OP_SUB for floating point ops
authorIlia Mirkin <imirkin@alum.mit.edu>
Fri, 14 Mar 2014 10:11:37 +0000 (06:11 -0400)
committerIlia Mirkin <imirkin@alum.mit.edu>
Tue, 18 Mar 2014 09:56:54 +0000 (05:56 -0400)
Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp

index 92fbf26647ce9144d1a2e79066a0b17f2dd621ea..7c60837eb6835a5d6578817489a185fa5b65cd08 100644 (file)
@@ -534,7 +534,10 @@ CodeEmitterGK110::emitFADD(const Instruction *i)
       assert(i->rnd == ROUND_N);
       assert(!i->saturate);
 
-      emitForm_L(i, 0x400, 0, i->src(1).mod);
+      Modifier mod = i->src(1).mod ^
+         Modifier(i->op == OP_SUB ? NV50_IR_MOD_NEG : 0);
+
+      emitForm_L(i, 0x400, 0, mod);
 
       FTZ_(3a);
       NEG_(3b, 0);
@@ -549,9 +552,11 @@ CodeEmitterGK110::emitFADD(const Instruction *i)
 
       if (code[0] & 0x1) {
          modNegAbsF32_3b(i, 1);
+         if (i->op == OP_SUB) code[1] ^= 1 << 27;
       } else {
          ABS_(34, 1);
          NEG_(30, 1);
+         if (i->op == OP_SUB) code[1] ^= 1 << 16;
       }
    }
 }