[Mesa-dev] [PATCH v2 2/6] nvc0/ir: add emission for SHLADD
Samuel Pitoiset
samuel.pitoiset at gmail.com
Mon Sep 26 21:02:10 UTC 2016
Unfortunately, we can't use the emit helpers for GF100/GK110
because src1 and src2 are swapped.
v2: - s/emitSHLADD/emitISCADD for GM107 emitter
Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
---
.../drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp | 53 ++++++++++++++++++++++
.../drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp | 32 +++++++++++++
.../drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp | 44 ++++++++++++++++++
3 files changed, 129 insertions(+)
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 61c450b..2c4e3a7 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,55 @@ 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() ^ i->src(1).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 +2453,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 cfde66c..3fedafd 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 d8ca6ab..c874b86 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,46 @@ 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() ^ i->src(1).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 +2644,9 @@ CodeEmitterNVC0::emitInstruction(Instruction *insn)
case OP_SAD:
emitISAD(insn);
break;
+ case OP_SHLADD:
+ emitSHLADD(insn);
+ break;
case OP_NOT:
emitNOT(insn);
break;
--
2.10.0
More information about the mesa-dev
mailing list