mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-26 05:00:13 +01:00
IR: Remove 8/16bit ROR
Opcode Dispatcher will now explictly emualte them
This commit is contained in:
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
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user