aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp
diff options
context:
space:
mode:
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.cpp52
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;