diff options
Diffstat (limited to 'src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp')
-rw-r--r-- | src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp | 52 |
1 files changed, 52 insertions, 0 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 61c450bc696..ce20ed33275 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp @@ -96,6 +96,7 @@ private: void emitDMUL(const Instruction *); void emitIMAD(const Instruction *); void emitISAD(const Instruction *); + void emitSHLADD(const Instruction *); void emitFMAD(const Instruction *); void emitDMAD(const Instruction *); void emitMADSP(const Instruction *i); @@ -757,6 +758,54 @@ CodeEmitterGK110::emitISAD(const Instruction *i) } void +CodeEmitterGK110::emitSHLADD(const Instruction *i) +{ + uint8_t addOp = (i->src(2).mod.neg() << 1) | i->src(0).mod.neg(); + const ImmediateValue *imm = i->src(1).get()->asImm(); + assert(imm); + + if (i->src(2).getFile() == FILE_IMMEDIATE) { + code[0] = 0x1; + code[1] = 0xc0c << 20; + } else { + code[0] = 0x2; + code[1] = 0x20c << 20; + } + code[1] |= addOp << 19; + + emitPredicate(i); + + defId(i->def(0), 2); + srcId(i->src(0), 10); + + if (i->flagsDef >= 0) + code[1] |= 1 << 18; + + assert(!(imm->reg.data.u32 & 0xffffffe0)); + code[1] |= imm->reg.data.u32 << 10; + + switch (i->src(2).getFile()) { + case FILE_GPR: + assert(code[0] & 0x2); + code[1] |= 0xc << 28; + srcId(i->src(2), 23); + break; + case FILE_MEMORY_CONST: + assert(code[0] & 0x2); + code[1] |= 0x4 << 28; + setCAddress14(i->src(2)); + break; + case FILE_IMMEDIATE: + assert(code[0] & 0x1); + setShortImmediate(i, 2); + break; + default: + assert(!"bad src2 file"); + break; + } +} + +void CodeEmitterGK110::emitNOT(const Instruction *i) { code[0] = 0x0003fc02; // logop(mov2) dst, 0, not src @@ -2403,6 +2452,9 @@ CodeEmitterGK110::emitInstruction(Instruction *insn) case OP_SAD: emitISAD(insn); break; + case OP_SHLADD: + emitSHLADD(insn); + break; case OP_NOT: emitNOT(insn); break; |