IR: Remove 8/16bit ROR

Opcode Dispatcher will now explictly emualte them
This commit is contained in:
Scott Mansell committed 2020-11-26 14:00:24 +13:00
1 parent 5b1d4eadd4
commit 0ec6e40a67
4 files changed
+43 -73

No files matched your search

@@ -1170,12 +1170,6 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
};
switch (OpSize) {
case 1:
GD = Ror(static_cast<uint8_t>(Src1), static_cast<uint8_t>(Src2));
break;
case 2:
GD = Ror(static_cast<uint16_t>(Src1), static_cast<uint16_t>(Src2));
break;
case 4:
GD = Ror(static_cast<uint32_t>(Src1), static_cast<uint32_t>(Src2));
break;
@@ -1642,7 +1636,7 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
}
case IR::OP_SELECT: {
auto Op = IROp->C<IR::IROp_Select>();
uint64_t Src1 = *GetSrc<uint64_t*>(SSAData, Op->Header.Args[0]);
uint64_t Src2 = *GetSrc<uint64_t*>(SSAData, Op->Header.Args[1]);
@@ -1656,7 +1650,7 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
ArgTrue = *GetSrc<uint64_t*>(SSAData, Op->Header.Args[2]);
ArgFalse = *GetSrc<uint64_t*>(SSAData, Op->Header.Args[3]);
}
bool CompResult;
if (Op->CompareSize == 4)
+1 -29
View File
@@ -561,20 +561,6 @@ DEF_OP(Ror) {
uint64_t Const;
if (IsInlineConstant(Op->Header.Args[1], &Const)) {
switch (OpSize) {
case 1: {
mov(TMP1.W(), GetReg<RA_32>(Op->Header.Args[0].ID()));
bfi(TMP1.W(), GetReg<RA_32>(Op->Header.Args[0].ID()), 8, 8);
bfi(TMP1.W(), GetReg<RA_32>(Op->Header.Args[0].ID()), 16, 8);
bfi(TMP1.W(), GetReg<RA_32>(Op->Header.Args[0].ID()), 24, 8);
ror(GetReg<RA_32>(Node), TMP1.W(), (unsigned int)Const);
break;
}
case 2: {
mov(TMP1.W(), GetReg<RA_32>(Op->Header.Args[0].ID()));
bfi(TMP1.W(), GetReg<RA_32>(Op->Header.Args[0].ID()), 16, 16);
ror(GetReg<RA_32>(Node), TMP1.W(), (unsigned int)Const);
break;
}
case 4: {
ror(GetReg<RA_32>(Node), GetReg<RA_32>(Op->Header.Args[0].ID()), (unsigned int)Const);
break;
@@ -588,20 +574,6 @@ DEF_OP(Ror) {
}
} else {
switch (OpSize) {
case 1: {
mov(TMP1.W(), GetReg<RA_32>(Op->Header.Args[0].ID()));
bfi(TMP1.W(), GetReg<RA_32>(Op->Header.Args[0].ID()), 8, 8);
bfi(TMP1.W(), GetReg<RA_32>(Op->Header.Args[0].ID()), 16, 8);
bfi(TMP1.W(), GetReg<RA_32>(Op->Header.Args[0].ID()), 24, 8);
rorv(GetReg<RA_32>(Node), TMP1.W(), GetReg<RA_32>(Op->Header.Args[1].ID()));
break;
}
case 2: {
mov(TMP1.W(), GetReg<RA_32>(Op->Header.Args[0].ID()));
bfi(TMP1.W(), GetReg<RA_32>(Op->Header.Args[0].ID()), 16, 16);
rorv(GetReg<RA_32>(Node), TMP1.W(), GetReg<RA_32>(Op->Header.Args[1].ID()));
break;
}
case 4: {
rorv(GetReg<RA_32>(Node), GetReg<RA_32>(Op->Header.Args[0].ID()), GetReg<RA_32>(Op->Header.Args[1].ID()));
break;
@@ -1127,7 +1099,7 @@ DEF_OP(Select) {
uint64_t const_true, const_false;
bool is_const_true = IsInlineConstant(Op->Header.Args[2], &const_true);
bool is_const_false = IsInlineConstant(Op->Header.Args[3], &const_false);
if (is_const_true || is_const_false) {
if (is_const_false != true || is_const_true != true || const_true != 1 || const_false != 0) {
LogMan::Msg::A("Select: Unsupported compare inline parameters");
@@ -683,16 +683,6 @@ DEF_OP(Ror) {
if (IsInlineConstant(Op->Header.Args[1], &Const)) {
Const &= Mask;
switch (OpSize) {
case 1: {
movzx(rax, GetSrc<RA_8>(Op->Header.Args[0].ID()));
ror(al, Const);
break;
}
case 2: {
movzx(rax, GetSrc<RA_16>(Op->Header.Args[0].ID()));
ror(ax, Const);
break;
}
case 4: {
mov(eax, GetSrc<RA_32>(Op->Header.Args[0].ID()));
ror(eax, Const);
@@ -703,21 +693,12 @@ DEF_OP(Ror) {
ror(rax, Const);
break;
}
default: LogMan::Msg::A("Unknown ROR Size: %d\n", OpSize); break;
}
} else {
mov (rcx, GetSrc<RA_64>(Op->Header.Args[1].ID()));
and(rcx, Mask);
switch (OpSize) {
case 1: {
movzx(rax, GetSrc<RA_8>(Op->Header.Args[0].ID()));
ror(al, cl);
break;
}
case 2: {
movzx(rax, GetSrc<RA_16>(Op->Header.Args[0].ID()));
ror(ax, cl);
break;
}
case 4: {
mov(eax, GetSrc<RA_32>(Op->Header.Args[0].ID()));
ror(eax, cl);
@@ -728,6 +709,7 @@ DEF_OP(Ror) {
ror(rax, cl);
break;
}
default: LogMan::Msg::A("Unknown ROR Size: %d\n", OpSize); break;
}
}
mov(GetDst<RA_64>(Node), rax);
@@ -1193,11 +1175,11 @@ DEF_OP(Select) {
} else {
cmp(GRCMP(Op->Cmp1.ID()), GRCMP(Op->Cmp2.ID()));
}
uint64_t const_true, const_false;
bool is_const_true = IsInlineConstant(Op->TrueVal, &const_true);
bool is_const_false = IsInlineConstant(Op->FalseVal, &const_false);
if (is_const_true || is_const_false) {
if (is_const_false != true || is_const_true != true || const_true != 1 || const_false != 0) {
LogMan::Msg::A("Select: Unsupported compare inline parameters");
@@ -1214,7 +1196,7 @@ DEF_OP(Select) {
case FEXCore::IR::COND_ULT: setb(al); break;
case FEXCore::IR::COND_UGT: seta(al); break;
case FEXCore::IR::COND_ULE: setna(al); break;
case FEXCore::IR::COND_MI:
case FEXCore::IR::COND_PL:
case FEXCore::IR::COND_VS:
@@ -1237,7 +1219,7 @@ DEF_OP(Select) {
case FEXCore::IR::COND_ULT: cmovb(rax, GetSrc<RA_64>(Op->TrueVal.ID())); break;
case FEXCore::IR::COND_UGT: cmova(rax, GetSrc<RA_64>(Op->TrueVal.ID())); break;
case FEXCore::IR::COND_ULE: cmovna(rax, GetSrc<RA_64>(Op->TrueVal.ID())); break;
case FEXCore::IR::COND_MI:
case FEXCore::IR::COND_PL:
case FEXCore::IR::COND_VS:
+34 -12
View File
@@ -148,7 +148,7 @@ void OpDispatchBuilder::RETOp(OpcodeArgs) {
if (CTX->Config.ABILocalFlags) {
_InvalidateFlags();
}
auto Constant = _Constant(GPRSize);
auto OldSP = _LoadContext(GPRSize, offsetof(FEXCore::Core::CPUState, gregs[FEXCore::X86State::REG_RSP]), GPRClass);
@@ -183,9 +183,9 @@ SS
*/
void OpDispatchBuilder::IRETOp(OpcodeArgs) {
LogMan::Throw::A(CTX->Config.Is64BitMode == true, "IRET only implemented for x64");
uint8_t GPRSize = CTX->Config.Is64BitMode ? 8 : 4;
auto Constant = _Constant(GPRSize);
OrderedNode* SP = _LoadContext(GPRSize, offsetof(FEXCore::Core::CPUState, gregs[FEXCore::X86State::REG_RSP]), GPRClass);
@@ -206,7 +206,7 @@ void OpDispatchBuilder::IRETOp(OpcodeArgs) {
//ss
_StoreContext(GPRClass, 2, offsetof(FEXCore::Core::CPUState, ss), _LoadMem(GPRClass, GPRSize, SP, GPRSize));
SP = _Add(SP, Constant);
_ExitFunction();
BlockSetRIP = true;
}
@@ -681,7 +681,7 @@ void OpDispatchBuilder::CALLAbsoluteOp(OpcodeArgs) {
OrderedNode *OpDispatchBuilder::SelectCC(uint8_t OP, OrderedNode *TrueValue, OrderedNode *FalseValue) {
OrderedNode *SrcCond = nullptr;
auto ZeroConst = _Constant(0);
auto OneConst = _Constant(1);
@@ -822,12 +822,12 @@ OrderedNode *OpDispatchBuilder::SelectCC(uint8_t OP, OrderedNode *TrueValue, Ord
case 0xD: SrcCond = _Select(FEXCore::IR::COND_SGE, flagsOpDestSigned, flagsOpSrcSigned, TrueValue, FalseValue, flagsOpSize); break;
// SL
case 0xC: SrcCond = _Select(FEXCore::IR::COND_SLT, flagsOpDestSigned, flagsOpSrcSigned, TrueValue, FalseValue, flagsOpSize); break;
// not sign
//case 0x99: SrcCond = _Select(FEXCore::IR::COND_, flagsOpDestSigned, flagsOpSrcSigned, TrueValue, FalseValue, flagsOpSize); break;
// sign
//case 0x98: SrcCond = _Select(FEXCore::IR::COND_, flagsOpDestSigned, flagsOpSrcSigned, TrueValue, FalseValue, flagsOpSize); break;
// UABove
case 0x7: SrcCond = _Select(FEXCore::IR::COND_UGT, flagsOpDest, flagsOpSrc, TrueValue, FalseValue, flagsOpSize); break;
// UBE
@@ -1139,9 +1139,9 @@ void OpDispatchBuilder::TESTOp(OpcodeArgs) {
auto ALUOp = _And(Dest, Src);
GenerateFlags_Logical(Op, ALUOp, Dest, Src);
auto Size = GetDstSize(Op);
if (Size >=4) {
flagsOp = FLAGS_OP_AND;
flagsOpDest = ALUOp;
@@ -1837,7 +1837,7 @@ void OpDispatchBuilder::ROROp(OpcodeArgs) {
auto Size = GetSrcSize(Op) * 8;
if (Is1Bit) {
Src = _Constant(Size, 1);
Src = _Constant(std::max(32, Size), 1);
}
else {
Src = LoadSource(GPRClass, Op, Op->Src[1], Op->Flags, -1);
@@ -1849,6 +1849,17 @@ void OpDispatchBuilder::ROROp(OpcodeArgs) {
else
Src = _And(Src, _Constant(Size, 0x1F));
if (Size < 32) {
// ARM doesn't support 8/16bit rotates. Emulate with an insert
// StoreResult truncates back to a 8/16 bit value
Dest = _Bfi(4, Size, Size, Dest, Dest);
if (Size == 8 && !Is1Bit) {
// And because the shift size isn't masked to 8 bits, we need to fill the
// the full 32bits to get the correct result.
Dest = _Bfi(4, 16, 16, Dest, Dest);
}
}
auto ALUOp = _Ror(Dest, Src);
StoreResult(GPRClass, Op, ALUOp, -1);
@@ -1875,7 +1886,18 @@ void OpDispatchBuilder::RORImmediateOp(OpcodeArgs) {
else
Shift &= 0x1F;
OrderedNode *Src = _Constant(Size, Shift);
OrderedNode *Src = _Constant(std::max(32, Size), Shift);
if (Size < 32) {
// ARM doesn't support 8/16bit rotates. Emulate with an insert
// StoreResult truncates back to a 8/16 bit value
Dest = _Bfi(4, Size, Size, Dest, Dest);
if (Size == 8 && Shift > 8) {
// And because the shift size isn't masked to 8 bits, we need to fill the
// the full 32bits to get the correct result.
Dest = _Bfi(4, 16, 16, Dest, Dest);
}
}
auto ALUOp = _Ror(Dest, Src);
@@ -5129,7 +5151,7 @@ void OpDispatchBuilder::GenerateFlags_ShiftLeft(FEXCore::X86Tables::DecodedOp Op
// Extract the last bit shifted in to CF
auto Size = _Constant(GetSrcSize(Op) * 8);
auto ShiftAmt = _Sub(Size, Src2);
auto LastBit = _And(_Lshr(Src1, ShiftAmt), _Constant(1));
auto LastBit = _And(_Lshr(Src1, ShiftAmt), _Constant(1));
COND_FLAG_SET(Src2, RFLAG_CF_LOC, LastBit);
}