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); @@ -756,6 +757,54 @@ CodeEmitterGK110::emitISAD(const Instruction *i) code[1] |= 1 << 19; } +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) { @@ -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; diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp index cfde66cd4ed..3fedafdae3a 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp @@ -152,6 +152,7 @@ private: void emitIADD(); void emitIMUL(); void emitIMAD(); + void emitISCADD(); void emitIMNMX(); void emitICMP(); void emitISET(); @@ -1812,6 +1813,34 @@ CodeEmitterGM107::emitIMAD() emitGPR (0x00, insn->def(0)); } +void +CodeEmitterGM107::emitISCADD() +{ + switch (insn->src(2).getFile()) { + case FILE_GPR: + emitInsn(0x5c180000); + emitGPR (0x14, insn->src(2)); + break; + case FILE_MEMORY_CONST: + emitInsn(0x4c180000); + emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(2)); + break; + case FILE_IMMEDIATE: + emitInsn(0x38180000); + emitIMMD(0x14, 19, insn->src(2)); + break; + default: + assert(!"bad src1 file"); + break; + } + emitNEG (0x31, insn->src(0)); + emitNEG (0x30, insn->src(2)); + emitCC (0x2f); + emitIMMD(0x27, 5, insn->src(1)); + emitGPR (0x08, insn->src(0)); + emitGPR (0x00, insn->def(0)); +} + void CodeEmitterGM107::emitIMNMX() { @@ -3098,6 +3127,9 @@ CodeEmitterGM107::emitInstruction(Instruction *i) emitIMAD(); } break; + case OP_SHLADD: + emitISCADD(); + break; case OP_MIN: case OP_MAX: if (isFloatType(insn->dType)) { 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 d8ca6ab07ad..0be9f7af171 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp @@ -101,6 +101,7 @@ private: void emitDMUL(const Instruction *); void emitIMAD(const Instruction *); void emitISAD(const Instruction *); + void emitSHLADD(const Instruction *a); void emitFMAD(const Instruction *); void emitDMAD(const Instruction *); void emitMADSP(const Instruction *); @@ -758,6 +759,45 @@ CodeEmitterNVC0::emitIMAD(const Instruction *i) code[0] |= 1 << 6; } +void +CodeEmitterNVC0::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); + + code[0] = 0x00000003; + code[1] = 0x40000000 | addOp << 23; + + emitPredicate(i); + + defId(i->def(0), 14); + srcId(i->src(0), 20); + + if (i->flagsDef >= 0) + code[1] |= 1 << 16; + + assert(!(imm->reg.data.u32 & 0xffffffe0)); + code[0] |= imm->reg.data.u32 << 5; + + switch (i->src(2).getFile()) { + case FILE_GPR: + srcId(i->src(2), 26); + break; + case FILE_MEMORY_CONST: + code[1] |= 0x4000; + code[1] |= i->getSrc(2)->reg.fileIndex << 10; + setAddress16(i->src(2)); + break; + case FILE_IMMEDIATE: + setImmediate(i, 2); + break; + default: + assert(!"bad src2 file"); + break; + } +} + void CodeEmitterNVC0::emitMADSP(const Instruction *i) { @@ -2603,6 +2643,9 @@ CodeEmitterNVC0::emitInstruction(Instruction *insn) case OP_SAD: emitISAD(insn); break; + case OP_SHLADD: + emitSHLADD(insn); + break; case OP_NOT: emitNOT(insn); break;