void emitPIXLD(const Instruction *);
+ void emitSHFL(const Instruction *);
+
void emitVOTE(const Instruction *);
inline void defId(const ValueDef&, const int pos);
{
const ImmediateValue *imm = ref.get()->asImm();
- return imm && (imm->reg.data.u32 & ((ty == TYPE_F32) ? 0xfff : 0xfff00000));
+ if (ty == TYPE_F32)
+ return imm && imm->reg.data.u32 & 0xfff;
+ else
+ return imm && (imm->reg.data.s32 > 0x7ffff ||
+ imm->reg.data.s32 < -0x80000);
}
void
} else
if ((code[0] & 0xf) == 0x3 || (code[0] & 0xf) == 4) {
// integer immediate
- assert((u32 & 0xfff00000) == 0 || (u32 & 0xfff00000) == 0xfff00000);
+ assert((u32 & 0xfff80000) == 0 || (u32 & 0xfff80000) == 0xfff80000);
assert(!(code[1] & 0xc000));
u32 &= 0xfffff;
code[0] |= (u32 & 0x3f) << 26;
CodeEmitterNVC0::emitUMUL(const Instruction *i)
{
if (i->encSize == 8) {
- if (i->src(1).getFile() == FILE_IMMEDIATE) {
+ if (isLIMM(i->src(1), TYPE_U32)) {
emitForm_A(i, HEX64(10000000, 00000002));
} else {
emitForm_A(i, HEX64(50000000, 00000003));
CodeEmitterNVC0::emitNOT(Instruction *i)
{
assert(i->encSize == 8);
+ if (i->getPredicate())
+ i->moveSources(1, 1);
i->setSrc(1, i->src(0));
emitForm_A(i, HEX64(68000000, 000001c3));
}
case SV_INVOCATION_ID: return 0x11;
case SV_YDIR: return 0x12;
case SV_THREAD_KILL: return 0x13;
+ case SV_COMBINED_TID: return 0x20;
case SV_TID: return 0x21 + SDATA(ref).sv.index;
case SV_CTAID: return 0x25 + SDATA(ref).sv.index;
case SV_NTID: return 0x29 + SDATA(ref).sv.index;
case SV_NCTAID: return 0x2d + SDATA(ref).sv.index;
case SV_LBASE: return 0x34;
case SV_SBASE: return 0x30;
+ case SV_LANEMASK_EQ: return 0x38;
+ case SV_LANEMASK_LT: return 0x39;
+ case SV_LANEMASK_LE: return 0x3a;
+ case SV_LANEMASK_GT: return 0x3b;
+ case SV_LANEMASK_GE: return 0x3c;
case SV_CLOCK: return 0x50 + SDATA(ref).sv.index;
default:
assert(!"no sreg for system value");
void
CodeEmitterNVC0::emitMOV(const Instruction *i)
{
+ assert(!i->saturate);
if (i->def(0).getFile() == FILE_PREDICATE) {
if (i->src(0).getFile() == FILE_GPR) {
code[0] = 0xfc01c003;
assert(!(imm & 0x000fffff));
code[0] = 0x00000318 | imm;
} else {
- assert(imm < 0x800 || ((int32_t)imm >= -0x800));
+ assert(imm < 0x800 && ((int32_t)imm >= -0x800));
code[0] = 0x00000118 | (imm << 20);
}
} else {
code[1] |= 0x00e00000;
}
+void
+CodeEmitterNVC0::emitSHFL(const Instruction *i)
+{
+ const ImmediateValue *imm;
+
+ assert(targ->getChipset() >= NVISA_GK104_CHIPSET);
+
+ code[0] = 0x00000005;
+ code[1] = 0x88000000 | (i->subOp << 23);
+
+ emitPredicate(i);
+
+ defId(i->def(0), 14);
+ srcId(i->src(0), 20);
+
+ switch (i->src(1).getFile()) {
+ case FILE_GPR:
+ srcId(i->src(1), 26);
+ break;
+ case FILE_IMMEDIATE:
+ imm = i->getSrc(1)->asImm();
+ assert(imm && imm->reg.data.u32 < 0x20);
+ code[0] |= imm->reg.data.u32 << 26;
+ code[0] |= 1 << 5;
+ break;
+ default:
+ assert(!"invalid src1 file");
+ break;
+ }
+
+ switch (i->src(2).getFile()) {
+ case FILE_GPR:
+ srcId(i->src(2), 49);
+ break;
+ case FILE_IMMEDIATE:
+ imm = i->getSrc(2)->asImm();
+ assert(imm && imm->reg.data.u32 < 0x2000);
+ code[1] |= imm->reg.data.u32 << 10;
+ code[0] |= 1 << 6;
+ break;
+ default:
+ assert(!"invalid src2 file");
+ break;
+ }
+
+ setPDSTL(i, i->defExists(1) ? 1 : -1);
+}
+
void
CodeEmitterNVC0::emitVOTE(const Instruction *i)
{
- assert(i->src(0).getFile() == FILE_PREDICATE);
+ const ImmediateValue *imm;
+ uint32_t u32;
code[0] = 0x00000004 | (i->subOp << 5);
code[1] = 0x48000000;
code[0] |= 63 << 14;
if (!(rp & 2))
code[1] |= 7 << 22;
- if (i->src(0).mod == Modifier(NV50_IR_MOD_NOT))
- code[0] |= 1 << 23;
- srcId(i->src(0), 20);
+
+ switch (i->src(0).getFile()) {
+ case FILE_PREDICATE:
+ if (i->src(0).mod == Modifier(NV50_IR_MOD_NOT))
+ code[0] |= 1 << 23;
+ srcId(i->src(0), 20);
+ break;
+ case FILE_IMMEDIATE:
+ imm = i->getSrc(0)->asImm();
+ assert(imm);
+ u32 = imm->reg.data.u32;
+ assert(u32 == 0 || u32 == 1);
+ code[0] |= (u32 == 1 ? 0x7 : 0xf) << 20;
+ break;
+ default:
+ assert(!"Unhandled src");
+ break;
+ }
}
bool
case OP_PIXLD:
emitPIXLD(insn);
break;
+ case OP_SHFL:
+ emitSHFL(insn);
+ break;
case OP_VOTE:
emitVOTE(insn);
break;