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>
This commit is contained in:
Samuel Pitoiset 2016-09-15 00:18:25 +02:00
parent 85132c7453
commit 31545b64b8
3 changed files with 127 additions and 0 deletions

View File

@ -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;

View File

@ -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)) {

View File

@ -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;