nv50/ir: emit VOTE instruction

Changes from v2:
 - add missing NOT modifier for GK110/GM107

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-02-28 20:44:47 +01:00
parent b3efa0a59e
commit 07ed003faf
6 changed files with 83 additions and 0 deletions

View File

@ -161,6 +161,7 @@ enum operation
OP_VSEL,
OP_CCTL, // cache control
OP_SHFL, // warp shuffle
OP_VOTE,
OP_LAST
};
@ -244,6 +245,9 @@ enum operation
#define NV50_IR_SUBOP_V2(d,a,b) (((d) << 10) | ((b) << 5) | (a) | 0x4000)
#define NV50_IR_SUBOP_V4(d,a,b) (((d) << 10) | ((b) << 5) | (a) | 0x8000)
#define NV50_IR_SUBOP_Vn(n) ((n) >> 14)
#define NV50_IR_SUBOP_VOTE_ALL 0
#define NV50_IR_SUBOP_VOTE_ANY 1
#define NV50_IR_SUBOP_VOTE_UNI 2
enum DataType
{

View File

@ -128,6 +128,8 @@ private:
void emitFlow(const Instruction *);
void emitVOTE(const Instruction *);
inline void defId(const ValueDef&, const int pos);
inline void srcId(const ValueRef&, const int pos);
inline void srcId(const ValueRef *, const int pos);
@ -1370,6 +1372,24 @@ CodeEmitterGK110::emitFlow(const Instruction *i)
}
}
void
CodeEmitterGK110::emitVOTE(const Instruction *i)
{
assert(i->src(0).getFile() == FILE_PREDICATE &&
i->def(1).getFile() == FILE_PREDICATE);
code[0] = 0x00000002;
code[1] = 0x86c00000 | (i->subOp << 19);
emitPredicate(i);
defId(i->def(0), 2);
defId(i->def(1), 48);
if (i->src(0).mod == Modifier(NV50_IR_MOD_NOT))
code[0] |= 1 << 45;
srcId(i->src(0), 42);
}
void
CodeEmitterGK110::emitAFETCH(const Instruction *i)
{
@ -2080,6 +2100,9 @@ CodeEmitterGK110::emitInstruction(Instruction *insn)
case OP_CCTL:
emitCCTL(insn);
break;
case OP_VOTE:
emitVOTE(insn);
break;
case OP_PHI:
case OP_UNION:
case OP_CONSTRAINT:

View File

@ -195,6 +195,8 @@ private:
void emitOUT();
void emitMEMBAR();
void emitVOTE();
};
/*******************************************************************************
@ -2653,6 +2655,30 @@ CodeEmitterGM107::emitMEMBAR()
emitField(0x08, 2, insn->subOp >> 2);
}
void
CodeEmitterGM107::emitVOTE()
{
int subOp;
assert(insn->src(0).getFile() == FILE_PREDICATE &&
insn->def(1).getFile() == FILE_PREDICATE);
switch (insn->subOp) {
case NV50_IR_SUBOP_VOTE_ANY: subOp = 1; break;
default:
assert(insn->subOp == NV50_IR_SUBOP_VOTE_ALL);
subOp = 0;
break;
}
emitInsn (0x50d80000);
emitField(0x30, 2, subOp);
emitGPR (0x00, insn->def(0));
emitPRED (0x2d, insn->def(1));
emitField(0x2a, 1, insn->src(0).mod == Modifier(NV50_IR_MOD_NOT));
emitPRED (0x27, insn->src(0));
}
/*******************************************************************************
* assembler front-end
******************************************************************************/
@ -2955,6 +2981,9 @@ CodeEmitterGM107::emitInstruction(Instruction *i)
case OP_MEMBAR:
emitMEMBAR();
break;
case OP_VOTE:
emitVOTE();
break;
default:
assert(!"invalid opcode");
emitNOP();

View File

@ -142,6 +142,8 @@ private:
void emitPIXLD(const Instruction *);
void emitVOTE(const Instruction *);
inline void defId(const ValueDef&, const int pos);
inline void defId(const Instruction *, int d, const int pos);
inline void srcId(const ValueRef&, const int pos);
@ -2334,6 +2336,24 @@ CodeEmitterNVC0::emitPIXLD(const Instruction *i)
code[1] |= 0x00e00000;
}
void
CodeEmitterNVC0::emitVOTE(const Instruction *i)
{
assert(i->src(0).getFile() == FILE_PREDICATE &&
i->def(1).getFile() == FILE_PREDICATE);
code[0] = 0x00000004 | (i->subOp << 5);
code[1] = 0x48000000;
emitPredicate(i);
defId(i->def(0), 14);
defId(i->def(1), 32 + 22);
if (i->src(0).mod == Modifier(NV50_IR_MOD_NOT))
code[0] |= 1 << 23;
srcId(i->src(0), 20);
}
bool
CodeEmitterNVC0::emitInstruction(Instruction *insn)
{
@ -2604,6 +2624,9 @@ CodeEmitterNVC0::emitInstruction(Instruction *insn)
case OP_PIXLD:
emitPIXLD(insn);
break;
case OP_VOTE:
emitVOTE(insn);
break;
case OP_PHI:
case OP_UNION:
case OP_CONSTRAINT:

View File

@ -190,6 +190,7 @@ const char *operationStr[OP_LAST + 1] =
"vsel",
"cctl",
"shfl",
"vote",
"(invalid)"
};

View File

@ -55,6 +55,7 @@ const uint8_t Target::operationSrcNr[] =
2, 2, 2, 2, 3, 2, // VADD, VAVG, VMIN, VMAX, VSAD, VSET,
2, 2, 2, 1, // VSHR, VSHL, VSEL, CCTL
3, // SHFL
1, // VOTE
0
};
@ -129,6 +130,8 @@ const OpClass Target::operationClass[] =
OPCLASS_VECTOR, OPCLASS_CONTROL,
// SHFL
OPCLASS_OTHER,
// VOTE
OPCLASS_OTHER,
OPCLASS_PSEUDO // LAST
};