nvc0/ir: add a "high" subop for shifts, emit shf.l/shf.r for 64-bit
Note that this is not available for SM20/SM30. Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
This commit is contained in:
@@ -175,6 +175,7 @@ enum operation
|
||||
#define NV50_IR_SUBOP_LDC_IS 2
|
||||
#define NV50_IR_SUBOP_LDC_ISL 3
|
||||
#define NV50_IR_SUBOP_SHIFT_WRAP 1
|
||||
#define NV50_IR_SUBOP_SHIFT_HIGH 2
|
||||
#define NV50_IR_SUBOP_EMU_PRERET 1
|
||||
#define NV50_IR_SUBOP_TEXBAR(n) n
|
||||
#define NV50_IR_SUBOP_MOV_FINAL 1
|
||||
|
||||
@@ -109,6 +109,7 @@ private:
|
||||
void emitBFIND(const Instruction *);
|
||||
void emitPERMT(const Instruction *);
|
||||
void emitShift(const Instruction *);
|
||||
void emitShift64(const Instruction *);
|
||||
|
||||
void emitSFnOp(const Instruction *, uint8_t subOp);
|
||||
|
||||
@@ -935,6 +936,24 @@ CodeEmitterGK110::emitShift(const Instruction *i)
|
||||
code[1] |= 1 << 10;
|
||||
}
|
||||
|
||||
void
|
||||
CodeEmitterGK110::emitShift64(const Instruction *i)
|
||||
{
|
||||
if (i->op == OP_SHR) {
|
||||
emitForm_21(i, 0x27c, 0xc7c);
|
||||
if (isSignedType(i->sType))
|
||||
code[1] |= 0x100;
|
||||
if (i->subOp & NV50_IR_SUBOP_SHIFT_HIGH)
|
||||
code[1] |= 1 << 19;
|
||||
} else {
|
||||
emitForm_21(i, 0xdfc, 0xf7c);
|
||||
}
|
||||
code[1] |= 0x200;
|
||||
|
||||
if (i->subOp & NV50_IR_SUBOP_SHIFT_WRAP)
|
||||
code[1] |= 1 << 21;
|
||||
}
|
||||
|
||||
void
|
||||
CodeEmitterGK110::emitPreOp(const Instruction *i)
|
||||
{
|
||||
@@ -2475,7 +2494,10 @@ CodeEmitterGK110::emitInstruction(Instruction *insn)
|
||||
break;
|
||||
case OP_SHL:
|
||||
case OP_SHR:
|
||||
emitShift(insn);
|
||||
if (typeSizeof(insn->sType) == 8)
|
||||
emitShift64(insn);
|
||||
else
|
||||
emitShift(insn);
|
||||
break;
|
||||
case OP_SET:
|
||||
case OP_SET_AND:
|
||||
|
||||
@@ -161,6 +161,7 @@ private:
|
||||
void emitISETP();
|
||||
void emitSHL();
|
||||
void emitSHR();
|
||||
void emitSHF();
|
||||
void emitPOPC();
|
||||
void emitBFI();
|
||||
void emitBFE();
|
||||
@@ -2071,6 +2072,47 @@ CodeEmitterGM107::emitSHR()
|
||||
emitGPR (0x00, insn->def(0));
|
||||
}
|
||||
|
||||
void
|
||||
CodeEmitterGM107::emitSHF()
|
||||
{
|
||||
unsigned type;
|
||||
|
||||
switch (insn->src(1).getFile()) {
|
||||
case FILE_GPR:
|
||||
emitInsn(insn->op == OP_SHL ? 0x5bf80000 : 0x5cf80000);
|
||||
emitGPR(0x14, insn->src(1));
|
||||
break;
|
||||
case FILE_IMMEDIATE:
|
||||
emitInsn(insn->op == OP_SHL ? 0x36f80000 : 0x38f80000);
|
||||
emitIMMD(0x14, 19, insn->src(1));
|
||||
break;
|
||||
default:
|
||||
assert(!"bad src1 file");
|
||||
break;
|
||||
}
|
||||
|
||||
switch (insn->sType) {
|
||||
case TYPE_U64:
|
||||
type = 2;
|
||||
break;
|
||||
case TYPE_S64:
|
||||
type = 3;
|
||||
break;
|
||||
default:
|
||||
type = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
emitField(0x32, 1, !!(insn->subOp & NV50_IR_SUBOP_SHIFT_WRAP));
|
||||
emitX (0x31);
|
||||
emitField(0x30, 1, !!(insn->subOp & NV50_IR_SUBOP_SHIFT_HIGH));
|
||||
emitCC (0x2f);
|
||||
emitGPR (0x27, insn->src(2));
|
||||
emitField(0x25, 2, type);
|
||||
emitGPR (0x08, insn->src(0));
|
||||
emitGPR (0x00, insn->def(0));
|
||||
}
|
||||
|
||||
void
|
||||
CodeEmitterGM107::emitPOPC()
|
||||
{
|
||||
@@ -3169,10 +3211,16 @@ CodeEmitterGM107::emitInstruction(Instruction *i)
|
||||
}
|
||||
break;
|
||||
case OP_SHL:
|
||||
emitSHL();
|
||||
if (typeSizeof(insn->sType) == 8)
|
||||
emitSHF();
|
||||
else
|
||||
emitSHL();
|
||||
break;
|
||||
case OP_SHR:
|
||||
emitSHR();
|
||||
if (typeSizeof(insn->sType) == 8)
|
||||
emitSHF();
|
||||
else
|
||||
emitSHR();
|
||||
break;
|
||||
case OP_POPCNT:
|
||||
emitPOPC();
|
||||
|
||||
Reference in New Issue
Block a user