diff options
Diffstat (limited to 'src/gallium/drivers/nouveau/codegen')
3 files changed, 27 insertions, 7 deletions
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp index ac59187130c..fe428cacee4 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp @@ -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; diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp index 3eca27d0bbc..3eabfa6ae8f 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp @@ -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; diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp index 90c409d35e6..96a4af4262e 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp @@ -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 |