From 493ad88e1b6598e3827546854b0c8336b42b36a2 Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Fri, 18 Jul 2014 22:20:42 -0400 Subject: [PATCH] gk110/ir: add emission of dadd/dmul/dmad opcodes Signed-off-by: Ilia Mirkin --- .../nouveau/codegen/nv50_ir_emit_gk110.cpp | 80 ++++++++++++++++++- 1 file changed, 77 insertions(+), 3 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 d8adc93eb5c..204d911ae17 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp @@ -84,11 +84,14 @@ private: void emitUADD(const Instruction *); void emitFADD(const Instruction *); + void emitDADD(const Instruction *); void emitIMUL(const Instruction *); void emitFMUL(const Instruction *); + void emitDMUL(const Instruction *); void emitIMAD(const Instruction *); void emitISAD(const Instruction *); void emitFMAD(const Instruction *); + void emitDMAD(const Instruction *); void emitNOT(const Instruction *); void emitLogicOp(const Instruction *, uint8_t subOp); @@ -478,6 +481,28 @@ CodeEmitterGK110::emitFMAD(const Instruction *i) } } +void +CodeEmitterGK110::emitDMAD(const Instruction *i) +{ + assert(!i->saturate); + assert(!i->ftz); + + emitForm_21(i, 0x1b8, 0xb38); + + NEG_(34, 2); + RND_(36, F); + + bool neg1 = (i->src(0).mod ^ i->src(1).mod).neg(); + + if (code[0] & 0x1) { + if (neg1) + code[1] ^= 1 << 27; + } else + if (neg1) { + code[1] |= 1 << 19; + } +} + void CodeEmitterGK110::emitFMUL(const Instruction *i) { @@ -515,6 +540,29 @@ CodeEmitterGK110::emitFMUL(const Instruction *i) } } +void +CodeEmitterGK110::emitDMUL(const Instruction *i) +{ + bool neg = (i->src(0).mod ^ i->src(1).mod).neg(); + + assert(!i->postFactor); + assert(!i->saturate); + assert(!i->ftz); + assert(!i->dnz); + + emitForm_21(i, 0x240, 0xc40); + + RND_(2a, F); + + if (code[0] & 0x1) { + if (neg) + code[1] ^= 1 << 27; + } else + if (neg) { + code[1] |= 1 << 19; + } +} + void CodeEmitterGK110::emitIMUL(const Instruction *i) { @@ -573,6 +621,26 @@ CodeEmitterGK110::emitFADD(const Instruction *i) } } +void +CodeEmitterGK110::emitDADD(const Instruction *i) +{ + assert(!i->saturate); + assert(!i->ftz); + + emitForm_21(i, 0x238, 0xc38); + RND_(2a, F); + ABS_(31, 0); + NEG_(33, 0); + if (code[0] & 0x1) { + modNegAbsF32_3b(i, 1); + if (i->op == OP_SUB) code[1] ^= 1 << 27; + } else { + NEG_(30, 1); + ABS_(34, 1); + if (i->op == OP_SUB) code[1] ^= 1 << 16; + } +} + void CodeEmitterGK110::emitUADD(const Instruction *i) { @@ -1634,20 +1702,26 @@ CodeEmitterGK110::emitInstruction(Instruction *insn) break; case OP_ADD: case OP_SUB: - if (isFloatType(insn->dType)) + if (insn->dType == TYPE_F64) + emitDADD(insn); + else if (isFloatType(insn->dType)) emitFADD(insn); else emitUADD(insn); break; case OP_MUL: - if (isFloatType(insn->dType)) + if (insn->dType == TYPE_F64) + emitDMUL(insn); + else if (isFloatType(insn->dType)) emitFMUL(insn); else emitIMUL(insn); break; case OP_MAD: case OP_FMA: - if (isFloatType(insn->dType)) + if (insn->dType == TYPE_F64) + emitDMAD(insn); + else if (isFloatType(insn->dType)) emitFMAD(insn); else emitIMAD(insn); -- 2.30.2