summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Pitoiset <samuel.pitoiset@gmail.com>2016-09-15 00:18:25 +0200
committerSamuel Pitoiset <samuel.pitoiset@gmail.com>2016-09-29 21:20:36 +0200
commit31545b64b80aa939a693723e07f06fe45160ae62 (patch)
treeb847eeea44e83568c72a6f057dbe1b11a5e344b4
parent85132c7453230960f34cfe7b7b7fcaaab158d79f (diff)
nvc0/ir: add emission for SHLADD
Unfortunately, we can't use the emit helpers for GF100/GK110 because src1 and src2 are swapped. Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Reviewed-by: Ilia Mirkin <imirkin@alum.mit.edu>
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp52
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp32
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp43
3 files changed, 127 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;
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();
@@ -1813,6 +1814,34 @@ CodeEmitterGM107::emitIMAD()
}
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()
{
switch (insn->src(1).getFile()) {
@@ -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 *);
@@ -759,6 +760,45 @@ CodeEmitterNVC0::emitIMAD(const Instruction *i)
}
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)
{
assert(targ->getChipset() >= NVISA_GK104_CHIPSET);
@@ -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;