mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-10 14:00:18 +02:00
Merge pull request #3400 from Sonicadvance1/revert_runtime_longmode_switch
Revert #3303
This commit is contained in:
35 files changed
+2789
-2900
No files matched your search
@@ -108,7 +108,7 @@ void OpDispatchBuilder::SyscallOp(OpcodeArgs) {
|
||||
// Calculate flags early.
|
||||
CalculateDeferredFlags();
|
||||
|
||||
const uint8_t GPRSize = GetGPRSize();
|
||||
const uint8_t GPRSize = CTX->GetGPRSize();
|
||||
auto NewRIP = GetRelocatedPC(Op, -Op->InstSize);
|
||||
_StoreContext(GPRSize, GPRClass, NewRIP, offsetof(FEXCore::Core::CPUState, rip));
|
||||
|
||||
@@ -170,10 +170,10 @@ void OpDispatchBuilder::ThunkOp(OpcodeArgs) {
|
||||
// Calculate flags early.
|
||||
CalculateDeferredFlags();
|
||||
|
||||
const uint8_t GPRSize = GetGPRSize();
|
||||
const uint8_t GPRSize = CTX->GetGPRSize();
|
||||
uint8_t *sha256 = (uint8_t *)(Op->PC + 2);
|
||||
|
||||
if (Is64BitMode) {
|
||||
if (CTX->Config.Is64BitMode) {
|
||||
// x86-64 ABI puts the function argument in RDI
|
||||
_Thunk(
|
||||
LoadGPRRegister(X86State::REG_RDI),
|
||||
@@ -206,14 +206,14 @@ void OpDispatchBuilder::LEAOp(OpcodeArgs) {
|
||||
// LEA specifically ignores segment prefixes
|
||||
const auto SrcSize = GetSrcSize(Op);
|
||||
|
||||
if (Is64BitMode) {
|
||||
if (CTX->Config.Is64BitMode) {
|
||||
const uint32_t DstSize = X86Tables::DecodeFlags::GetOpAddr(Op->Flags, 0) == X86Tables::DecodeFlags::FLAG_OPERAND_SIZE_LAST ? 2 :
|
||||
X86Tables::DecodeFlags::GetOpAddr(Op->Flags, 0) == X86Tables::DecodeFlags::FLAG_WIDENING_SIZE_LAST ? 8 : 4;
|
||||
|
||||
auto Src = LoadSource_WithOpSize(GPRClass, Op, Op->Src[0], SrcSize, Op->Flags, {.LoadData = false});
|
||||
if (DstSize != SrcSize) {
|
||||
// If the SrcSize isn't the DstSize then we need to zero extend.
|
||||
const uint8_t GPRSize = GetGPRSize();
|
||||
const uint8_t GPRSize = CTX->GetGPRSize();
|
||||
Src = _Bfe(IR::SizeToOpSize(GPRSize), SrcSize * 8, 0, Src);
|
||||
}
|
||||
StoreResult_WithOpSize(GPRClass, Op, Op->Dest, Src, DstSize, -1);
|
||||
@@ -230,7 +230,7 @@ void OpDispatchBuilder::NOPOp(OpcodeArgs) {
|
||||
}
|
||||
|
||||
void OpDispatchBuilder::RETOp(OpcodeArgs) {
|
||||
const uint8_t GPRSize = GetGPRSize();
|
||||
const uint8_t GPRSize = CTX->GetGPRSize();
|
||||
|
||||
// ABI Optimization: Flags don't survive calls or rets
|
||||
if (CTX->Config.ABILocalFlags) {
|
||||
@@ -285,7 +285,7 @@ void OpDispatchBuilder::IRETOp(OpcodeArgs) {
|
||||
// Calculate flags early.
|
||||
CalculateDeferredFlags();
|
||||
|
||||
const uint8_t GPRSize = GetGPRSize();
|
||||
const uint8_t GPRSize = CTX->GetGPRSize();
|
||||
|
||||
auto Constant = _Constant(GPRSize);
|
||||
|
||||
@@ -305,7 +305,7 @@ void OpDispatchBuilder::IRETOp(OpcodeArgs) {
|
||||
SetPackedRFLAG(false, eflags);
|
||||
SP = _Add(IR::SizeToOpSize(GPRSize), SP, Constant);
|
||||
|
||||
if (Is64BitMode) {
|
||||
if (CTX->Config.Is64BitMode) {
|
||||
// RSP and SS only happen in 64-bit mode or if this is a CPL mode jump!
|
||||
// FEX doesn't support a CPL mode switch, so don't need to worry about this on 32-bit
|
||||
StoreGPRRegister(X86State::REG_RSP, _LoadMem(GPRClass, GPRSize, SP, GPRSize));
|
||||
@@ -329,7 +329,7 @@ void OpDispatchBuilder::IRETOp(OpcodeArgs) {
|
||||
}
|
||||
|
||||
void OpDispatchBuilder::CallbackReturnOp(OpcodeArgs) {
|
||||
const uint8_t GPRSize = GetGPRSize();
|
||||
const uint8_t GPRSize = CTX->GetGPRSize();
|
||||
// Store the new RIP
|
||||
_CallbackReturn();
|
||||
auto NewRIP = _LoadContext(GPRSize, GPRClass, offsetof(FEXCore::Core::CPUState, rip));
|
||||
@@ -523,7 +523,7 @@ void OpDispatchBuilder::PUSHOp(OpcodeArgs) {
|
||||
|
||||
auto OldSP = LoadGPRRegister(X86State::REG_RSP);
|
||||
|
||||
const uint8_t GPRSize = GetGPRSize();
|
||||
const uint8_t GPRSize = CTX->GetGPRSize();
|
||||
auto NewSP = _Push(GPRSize, Size, Src, OldSP);
|
||||
|
||||
// Store the new stack pointer
|
||||
@@ -537,7 +537,7 @@ void OpDispatchBuilder::PUSHREGOp(OpcodeArgs) {
|
||||
{.AllowUpperGarbage = true});
|
||||
|
||||
auto OldSP = LoadGPRRegister(X86State::REG_RSP);
|
||||
const uint8_t GPRSize = GetGPRSize();
|
||||
const uint8_t GPRSize = CTX->GetGPRSize();
|
||||
auto NewSP = _Push(GPRSize, Size, Src, OldSP);
|
||||
// Store the new stack pointer
|
||||
StoreGPRRegister(X86State::REG_RSP, NewSP);
|
||||
@@ -562,7 +562,7 @@ void OpDispatchBuilder::PUSHAOp(OpcodeArgs) {
|
||||
|
||||
OrderedNode *Src{};
|
||||
OrderedNode *NewSP = OldSP;
|
||||
const uint8_t GPRSize = GetGPRSize();
|
||||
const uint8_t GPRSize = CTX->GetGPRSize();
|
||||
|
||||
Src = LoadGPRRegister(X86State::REG_RAX);
|
||||
NewSP = _Push(GPRSize, Size, Src, NewSP);
|
||||
@@ -600,7 +600,7 @@ void OpDispatchBuilder::PUSHSegmentOp(OpcodeArgs) {
|
||||
auto OldSP = LoadGPRRegister(X86State::REG_RSP);
|
||||
|
||||
OrderedNode *Src{};
|
||||
if (!Is64BitMode) {
|
||||
if (!CTX->Config.Is64BitMode()) {
|
||||
switch (SegmentReg) {
|
||||
case FEXCore::X86Tables::DecodeFlags::FLAG_ES_PREFIX:
|
||||
Src = _LoadContext(SrcSize, GPRClass, offsetof(FEXCore::Core::CPUState, es_idx));
|
||||
@@ -647,7 +647,7 @@ void OpDispatchBuilder::PUSHSegmentOp(OpcodeArgs) {
|
||||
}
|
||||
}
|
||||
|
||||
const uint8_t GPRSize = GetGPRSize();
|
||||
const uint8_t GPRSize = CTX->GetGPRSize();
|
||||
// Store our value to the new stack location
|
||||
// AMD hardware zexts segment selector to 32bit
|
||||
// Intel hardware inserts segment selector
|
||||
@@ -780,7 +780,7 @@ void OpDispatchBuilder::LEAVEOp(OpcodeArgs) {
|
||||
}
|
||||
|
||||
void OpDispatchBuilder::CALLOp(OpcodeArgs) {
|
||||
const uint8_t GPRSize = GetGPRSize();
|
||||
const uint8_t GPRSize = CTX->GetGPRSize();
|
||||
|
||||
BlockSetRIP = true;
|
||||
|
||||
@@ -951,7 +951,7 @@ void OpDispatchBuilder::SETccOp(OpcodeArgs) {
|
||||
}
|
||||
|
||||
void OpDispatchBuilder::CMOVOp(OpcodeArgs) {
|
||||
const uint8_t GPRSize = GetGPRSize();
|
||||
const uint8_t GPRSize = CTX->GetGPRSize();
|
||||
|
||||
// Calculate flags early.
|
||||
CalculateDeferredFlags();
|
||||
@@ -983,7 +983,7 @@ void OpDispatchBuilder::CondJUMPOp(OpcodeArgs) {
|
||||
uint64_t InstRIP = Op->PC + Op->InstSize;
|
||||
uint64_t Target = InstRIP + TargetOffset;
|
||||
|
||||
if (GetGPRSize() == 4) {
|
||||
if (CTX->GetGPRSize() == 4) {
|
||||
// If the GPRSize is 4 then we need to be careful about PC wrapping
|
||||
if (TargetOffset < 0 && -TargetOffset > InstRIP) {
|
||||
// Invert the signed value if we are underflowing
|
||||
@@ -1058,7 +1058,7 @@ void OpDispatchBuilder::CondJUMPRCXOp(OpcodeArgs) {
|
||||
CalculateDeferredFlags();
|
||||
|
||||
BlockSetRIP = true;
|
||||
uint8_t JcxGPRSize = GetGPRSize();
|
||||
uint8_t JcxGPRSize = CTX->GetGPRSize();
|
||||
JcxGPRSize = (Op->Flags & X86Tables::DecodeFlags::FLAG_ADDRESS_SIZE) ? (JcxGPRSize >> 1) : JcxGPRSize;
|
||||
|
||||
IRPair<IROp_Constant> TakeBranch;
|
||||
@@ -1211,7 +1211,7 @@ void OpDispatchBuilder::JUMPOp(OpcodeArgs) {
|
||||
uint64_t InstRIP = Op->PC + Op->InstSize;
|
||||
uint64_t TargetRIP = InstRIP + TargetOffset;
|
||||
|
||||
if (GetGPRSize() == 4) {
|
||||
if (CTX->GetGPRSize() == 4) {
|
||||
// If the GPRSize is 4 then we need to be careful about PC wrapping
|
||||
if (TargetOffset < 0 && -TargetOffset > InstRIP) {
|
||||
// Invert the signed value if we are underflowing
|
||||
@@ -1502,7 +1502,7 @@ void OpDispatchBuilder::MOVSegOp(OpcodeArgs) {
|
||||
break;
|
||||
case FEXCore::X86State::REG_RBP: // GS
|
||||
case FEXCore::X86State::REG_R13: // GS
|
||||
if (!Is64BitMode) {
|
||||
if (!CTX->Config.Is64BitMode) {
|
||||
_StoreContext(2, GPRClass, Src, offsetof(FEXCore::Core::CPUState, gs_idx));
|
||||
UpdatePrefixFromSegment(Src, FEXCore::X86Tables::DecodeFlags::FLAG_GS_PREFIX);
|
||||
} else {
|
||||
@@ -1512,7 +1512,7 @@ void OpDispatchBuilder::MOVSegOp(OpcodeArgs) {
|
||||
break;
|
||||
case FEXCore::X86State::REG_RSP: // FS
|
||||
case FEXCore::X86State::REG_R12: // FS
|
||||
if (!Is64BitMode) {
|
||||
if (!CTX->Config.Is64BitMode) {
|
||||
_StoreContext(2, GPRClass, Src, offsetof(FEXCore::Core::CPUState, fs_idx));
|
||||
UpdatePrefixFromSegment(Src, FEXCore::X86Tables::DecodeFlags::FLAG_FS_PREFIX);
|
||||
} else {
|
||||
@@ -1548,7 +1548,7 @@ void OpDispatchBuilder::MOVSegOp(OpcodeArgs) {
|
||||
break;
|
||||
case FEXCore::X86State::REG_RBP: // GS
|
||||
case FEXCore::X86State::REG_R13: // GS
|
||||
if (Is64BitMode) {
|
||||
if (CTX->Config.Is64BitMode) {
|
||||
Segment = _Constant(0);
|
||||
}
|
||||
else {
|
||||
@@ -1557,7 +1557,7 @@ void OpDispatchBuilder::MOVSegOp(OpcodeArgs) {
|
||||
break;
|
||||
case FEXCore::X86State::REG_RSP: // FS
|
||||
case FEXCore::X86State::REG_R12: // FS
|
||||
if (Is64BitMode) {
|
||||
if (CTX->Config.Is64BitMode) {
|
||||
Segment = _Constant(0);
|
||||
}
|
||||
else {
|
||||
@@ -1604,7 +1604,7 @@ void OpDispatchBuilder::MOVOffsetOp(OpcodeArgs) {
|
||||
}
|
||||
|
||||
void OpDispatchBuilder::CPUIDOp(OpcodeArgs) {
|
||||
const auto GPRSize = GetGPRSize();
|
||||
const auto GPRSize = CTX->GetGPRSize();
|
||||
|
||||
OrderedNode *Src = LoadSource_WithOpSize(GPRClass, Op, Op->Src[0], GPRSize, Op->Flags);
|
||||
OrderedNode *Leaf = LoadGPRRegister(X86State::REG_RCX);
|
||||
@@ -2218,7 +2218,7 @@ void OpDispatchBuilder::BLSRBMIOp(OpcodeArgs) {
|
||||
void OpDispatchBuilder::BMI2Shift(OpcodeArgs) {
|
||||
// In the event the source is a memory operand, use the
|
||||
// exact width instead of the GPR size.
|
||||
const auto GPRSize = GetGPRSize();
|
||||
const auto GPRSize = CTX->GetGPRSize();
|
||||
const auto Size = GetSrcSize(Op);
|
||||
const auto SrcSize = Op->Src[0].IsGPR() ? GPRSize : Size;
|
||||
|
||||
@@ -2280,7 +2280,7 @@ void OpDispatchBuilder::RORX(OpcodeArgs) {
|
||||
const auto Amount = Op->Src[1].Data.Literal.Value;
|
||||
const auto SrcSize = GetSrcSize(Op);
|
||||
const auto SrcSizeBits = SrcSize * 8;
|
||||
const auto GPRSize = GetGPRSize();
|
||||
const auto GPRSize = CTX->GetGPRSize();
|
||||
|
||||
const auto DoRotation = Amount != 0 && Amount < SrcSizeBits;
|
||||
const auto IsSameGPR = Op->Src[0].IsGPR() && Op->Dest.IsGPR() &&
|
||||
@@ -2313,7 +2313,7 @@ void OpDispatchBuilder::MULX(OpcodeArgs) {
|
||||
|
||||
// Src1 can be a memory operand, so ensure we constrain to the
|
||||
// absolute width of the access in that scenario.
|
||||
const auto GPRSize = GetGPRSize();
|
||||
const auto GPRSize = CTX->GetGPRSize();
|
||||
const auto Src1Size = Op->Src[1].IsGPR() ? GPRSize : OperandSize;
|
||||
|
||||
OrderedNode* Src1 = LoadSource_WithOpSize(GPRClass, Op, Op->Src[1], Src1Size, Op->Flags);
|
||||
@@ -2809,7 +2809,7 @@ void OpDispatchBuilder::BTOp(OpcodeArgs) {
|
||||
if (Op->Dest.IsGPR()) {
|
||||
// When the destination is a GPR, we don't care about garbage in the upper bits.
|
||||
// Load the full register.
|
||||
auto Dest = LoadSource_WithOpSize(GPRClass, Op, Op->Dest, GetGPRSize(), Op->Flags);
|
||||
auto Dest = LoadSource_WithOpSize(GPRClass, Op, Op->Dest, CTX->GetGPRSize(), Op->Flags);
|
||||
Value = Dest;
|
||||
|
||||
// Get the bit selection from the src. We need to mask for 8/16-bit, but
|
||||
@@ -3045,7 +3045,7 @@ void OpDispatchBuilder::IMULOp(OpcodeArgs) {
|
||||
StoreGPRRegister(X86State::REG_RDX, LocalResultHigh);
|
||||
}
|
||||
else if (Size == 8) {
|
||||
if (!Is64BitMode) {
|
||||
if (!CTX->Config.Is64BitMode) {
|
||||
LogMan::Msg::EFmt("Doesn't exist in 32bit mode");
|
||||
DecodeFailure = true;
|
||||
return;
|
||||
@@ -3095,7 +3095,7 @@ void OpDispatchBuilder::MULOp(OpcodeArgs) {
|
||||
StoreGPRRegister(X86State::REG_RDX, ResultHigh);
|
||||
}
|
||||
else if (Size == 8) {
|
||||
if (!Is64BitMode) {
|
||||
if (!CTX->Config.Is64BitMode) {
|
||||
LogMan::Msg::EFmt("Doesn't exist in 32bit mode");
|
||||
DecodeFailure = true;
|
||||
return;
|
||||
@@ -3142,7 +3142,7 @@ void OpDispatchBuilder::NOTOp(OpcodeArgs) {
|
||||
|
||||
// Always load full size, we explicitly want the upper bits to get the
|
||||
// insert behaviour for free/implicitly.
|
||||
const uint8_t GPRSize = GetGPRSize();
|
||||
const uint8_t GPRSize = CTX->GetGPRSize();
|
||||
OrderedNode *Src = LoadSource_WithOpSize(GPRClass, Op, Dest, GPRSize, Op->Flags);
|
||||
|
||||
// For 8/16-bit, use 64-bit invert so we invert in place, while getting
|
||||
@@ -3506,7 +3506,7 @@ void OpDispatchBuilder::WriteSegmentReg(OpcodeArgs) {
|
||||
}
|
||||
|
||||
void OpDispatchBuilder::EnterOp(OpcodeArgs) {
|
||||
const uint8_t GPRSize = GetGPRSize();
|
||||
const uint8_t GPRSize = CTX->GetGPRSize();
|
||||
|
||||
LOGMAN_THROW_A_FMT(Op->Src[0].IsLiteral(), "Src1 needs to be literal here");
|
||||
const uint64_t Value = Op->Src[0].Data.Literal.Value;
|
||||
@@ -3515,7 +3515,7 @@ void OpDispatchBuilder::EnterOp(OpcodeArgs) {
|
||||
const uint8_t Level = (Value >> 16) & 0x1F;
|
||||
|
||||
const auto PushValue = [&](uint8_t Size, OrderedNode *Src) -> OrderedNode* {
|
||||
const uint8_t GPRSize = GetGPRSize();
|
||||
const uint8_t GPRSize = CTX->GetGPRSize();
|
||||
|
||||
auto OldSP = LoadGPRRegister(X86State::REG_RSP);
|
||||
auto NewSP = _Push(GPRSize, Size, Src, OldSP);
|
||||
@@ -3556,7 +3556,7 @@ void OpDispatchBuilder::SGDTOp(OpcodeArgs) {
|
||||
// Operand size prefix is ignored on this instruction, size purely depends on operating mode.
|
||||
uint64_t GDTAddress = 0xFFFFFFFFFFFE0000ULL;
|
||||
size_t GDTStoreSize = 8;
|
||||
if (!Is64BitMode) {
|
||||
if (!CTX->Config.Is64BitMode) {
|
||||
// Mask off upper bits if 32-bit result.
|
||||
GDTAddress &= ~0U;
|
||||
GDTStoreSize = 4;
|
||||
@@ -3660,7 +3660,7 @@ void OpDispatchBuilder::STOSOp(OpcodeArgs) {
|
||||
// Calculate direction.
|
||||
auto DF = GetRFLAG(FEXCore::X86State::RFLAG_DF_LOC);
|
||||
auto SizeConst = _Constant(Size);
|
||||
auto PtrDir = _SubShift(IR::SizeToOpSize(GetGPRSize()), SizeConst, DF, ShiftType::LSL, FEXCore::ilog2(Size) + 1);
|
||||
auto PtrDir = _SubShift(IR::SizeToOpSize(CTX->GetGPRSize()), SizeConst, DF, ShiftType::LSL, FEXCore::ilog2(Size) + 1);
|
||||
|
||||
// Offset the pointer
|
||||
OrderedNode *TailDest = LoadGPRRegister(X86State::REG_RDI);
|
||||
@@ -3722,7 +3722,7 @@ void OpDispatchBuilder::MOVSOp(OpcodeArgs) {
|
||||
}
|
||||
else {
|
||||
auto SizeConst = _Constant(Size);
|
||||
auto PtrDir = _SubShift(IR::SizeToOpSize(GetGPRSize()), SizeConst, DF, ShiftType::LSL, FEXCore::ilog2(Size) + 1);
|
||||
auto PtrDir = _SubShift(IR::SizeToOpSize(CTX->GetGPRSize()), SizeConst, DF, ShiftType::LSL, FEXCore::ilog2(Size) + 1);
|
||||
|
||||
OrderedNode *RSI = LoadGPRRegister(X86State::REG_RSI);
|
||||
OrderedNode *RDI = LoadGPRRegister(X86State::REG_RDI);
|
||||
@@ -3769,7 +3769,7 @@ void OpDispatchBuilder::CMPSOp(OpcodeArgs) {
|
||||
|
||||
auto DF = GetRFLAG(FEXCore::X86State::RFLAG_DF_LOC);
|
||||
auto SizeConst = _Constant(Size);
|
||||
auto PtrDir = _SubShift(IR::SizeToOpSize(GetGPRSize()), SizeConst, DF, ShiftType::LSL, FEXCore::ilog2(Size) + 1);
|
||||
auto PtrDir = _SubShift(IR::SizeToOpSize(CTX->GetGPRSize()), SizeConst, DF, ShiftType::LSL, FEXCore::ilog2(Size) + 1);
|
||||
|
||||
// Offset the pointer
|
||||
Dest_RDI = _Add(OpSize::i64Bit, Dest_RDI, PtrDir);
|
||||
@@ -3788,7 +3788,7 @@ void OpDispatchBuilder::CMPSOp(OpcodeArgs) {
|
||||
// read DF once
|
||||
auto DF = GetRFLAG(FEXCore::X86State::RFLAG_DF_LOC);
|
||||
auto SizeConst = _Constant(Size);
|
||||
auto PtrDir = _SubShift(IR::SizeToOpSize(GetGPRSize()), SizeConst, DF, ShiftType::LSL, FEXCore::ilog2(Size) + 1);
|
||||
auto PtrDir = _SubShift(IR::SizeToOpSize(CTX->GetGPRSize()), SizeConst, DF, ShiftType::LSL, FEXCore::ilog2(Size) + 1);
|
||||
|
||||
auto JumpStart = Jump();
|
||||
// Make sure to start a new block after ending this one
|
||||
@@ -3882,7 +3882,7 @@ void OpDispatchBuilder::LODSOp(OpcodeArgs) {
|
||||
|
||||
auto DF = GetRFLAG(FEXCore::X86State::RFLAG_DF_LOC);
|
||||
auto SizeConst = _Constant(Size);
|
||||
auto PtrDir = _SubShift(IR::SizeToOpSize(GetGPRSize()), SizeConst, DF, ShiftType::LSL, FEXCore::ilog2(Size) + 1);
|
||||
auto PtrDir = _SubShift(IR::SizeToOpSize(CTX->GetGPRSize()), SizeConst, DF, ShiftType::LSL, FEXCore::ilog2(Size) + 1);
|
||||
|
||||
// Offset the pointer
|
||||
OrderedNode *TailDest_RSI = LoadGPRRegister(X86State::REG_RSI);
|
||||
@@ -3903,7 +3903,7 @@ void OpDispatchBuilder::LODSOp(OpcodeArgs) {
|
||||
// Read DF once
|
||||
auto DF = GetRFLAG(FEXCore::X86State::RFLAG_DF_LOC);
|
||||
auto SizeConst = _Constant(Size);
|
||||
auto PtrDir = _SubShift(IR::SizeToOpSize(GetGPRSize()), SizeConst, DF, ShiftType::LSL, FEXCore::ilog2(Size) + 1);
|
||||
auto PtrDir = _SubShift(IR::SizeToOpSize(CTX->GetGPRSize()), SizeConst, DF, ShiftType::LSL, FEXCore::ilog2(Size) + 1);
|
||||
|
||||
auto JumpStart = Jump();
|
||||
// Make sure to start a new block after ending this one
|
||||
@@ -3980,7 +3980,7 @@ void OpDispatchBuilder::SCASOp(OpcodeArgs) {
|
||||
|
||||
auto DF = GetRFLAG(FEXCore::X86State::RFLAG_DF_LOC);
|
||||
auto SizeConst = _Constant(Size);
|
||||
auto PtrDir = _SubShift(IR::SizeToOpSize(GetGPRSize()), SizeConst, DF, ShiftType::LSL, FEXCore::ilog2(Size) + 1);
|
||||
auto PtrDir = _SubShift(IR::SizeToOpSize(CTX->GetGPRSize()), SizeConst, DF, ShiftType::LSL, FEXCore::ilog2(Size) + 1);
|
||||
|
||||
// Offset the pointer
|
||||
OrderedNode *TailDest_RDI = LoadGPRRegister(X86State::REG_RDI);
|
||||
@@ -3997,7 +3997,7 @@ void OpDispatchBuilder::SCASOp(OpcodeArgs) {
|
||||
// read DF once
|
||||
auto DF = GetRFLAG(FEXCore::X86State::RFLAG_DF_LOC);
|
||||
auto SizeConst = _Constant(Size);
|
||||
auto PtrDir = _SubShift(IR::SizeToOpSize(GetGPRSize()), SizeConst, DF, ShiftType::LSL, FEXCore::ilog2(Size) + 1);
|
||||
auto PtrDir = _SubShift(IR::SizeToOpSize(CTX->GetGPRSize()), SizeConst, DF, ShiftType::LSL, FEXCore::ilog2(Size) + 1);
|
||||
|
||||
auto JumpStart = Jump();
|
||||
// Make sure to start a new block after ending this one
|
||||
@@ -4072,7 +4072,7 @@ void OpDispatchBuilder::BSWAPOp(OpcodeArgs) {
|
||||
Dest = _Constant(0);
|
||||
}
|
||||
else {
|
||||
Dest = LoadSource_WithOpSize(GPRClass, Op, Op->Dest, GetGPRSize(), Op->Flags);
|
||||
Dest = LoadSource_WithOpSize(GPRClass, Op, Op->Dest, CTX->GetGPRSize(), Op->Flags);
|
||||
Dest = _Rev(IR::SizeToOpSize(Size), Dest);
|
||||
}
|
||||
StoreResult(GPRClass, Op, Dest, -1);
|
||||
@@ -4088,7 +4088,7 @@ void OpDispatchBuilder::PUSHFOp(OpcodeArgs) {
|
||||
|
||||
auto OldSP = LoadGPRRegister(X86State::REG_RSP);
|
||||
|
||||
const uint8_t GPRSize = GetGPRSize();
|
||||
const uint8_t GPRSize = CTX->GetGPRSize();
|
||||
auto NewSP = _Push(GPRSize, Size, Src, OldSP);
|
||||
|
||||
// Store the new stack pointer
|
||||
@@ -4145,7 +4145,7 @@ void OpDispatchBuilder::DIVOp(OpcodeArgs) {
|
||||
// This loads the divisor
|
||||
OrderedNode *Divisor = LoadSource(GPRClass, Op, Op->Dest, Op->Flags);
|
||||
|
||||
const auto GPRSize = GetGPRSize();
|
||||
const auto GPRSize = CTX->GetGPRSize();
|
||||
const auto Size = GetSrcSize(Op);
|
||||
|
||||
if (Size == 1) {
|
||||
@@ -4178,7 +4178,7 @@ void OpDispatchBuilder::DIVOp(OpcodeArgs) {
|
||||
StoreGPRRegister(X86State::REG_RDX, URemOp);
|
||||
}
|
||||
else if (Size == 8) {
|
||||
if (!Is64BitMode) {
|
||||
if (!CTX->Config.Is64BitMode) {
|
||||
LogMan::Msg::EFmt("Doesn't exist in 32bit mode");
|
||||
DecodeFailure = true;
|
||||
return;
|
||||
@@ -4198,7 +4198,7 @@ void OpDispatchBuilder::IDIVOp(OpcodeArgs) {
|
||||
// This loads the divisor
|
||||
OrderedNode *Divisor = LoadSource(GPRClass, Op, Op->Dest, Op->Flags);
|
||||
|
||||
const auto GPRSize = GetGPRSize();
|
||||
const auto GPRSize = CTX->GetGPRSize();
|
||||
const auto Size = GetSrcSize(Op);
|
||||
|
||||
if (Size == 1) {
|
||||
@@ -4233,7 +4233,7 @@ void OpDispatchBuilder::IDIVOp(OpcodeArgs) {
|
||||
StoreGPRRegister(X86State::REG_RDX, URemOp);
|
||||
}
|
||||
else if (Size == 8) {
|
||||
if (!Is64BitMode) {
|
||||
if (!CTX->Config.Is64BitMode) {
|
||||
LogMan::Msg::EFmt("Doesn't exist in 32bit mode");
|
||||
DecodeFailure = true;
|
||||
return;
|
||||
@@ -4250,7 +4250,7 @@ void OpDispatchBuilder::IDIVOp(OpcodeArgs) {
|
||||
}
|
||||
|
||||
void OpDispatchBuilder::BSFOp(OpcodeArgs) {
|
||||
const uint8_t GPRSize = GetGPRSize();
|
||||
const uint8_t GPRSize = CTX->GetGPRSize();
|
||||
const uint8_t DstSize = GetDstSize(Op) == 2 ? 2 : GPRSize;
|
||||
OrderedNode *Dest = LoadSource_WithOpSize(GPRClass, Op, Op->Dest, DstSize, Op->Flags);
|
||||
OrderedNode *Src = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags);
|
||||
@@ -4271,7 +4271,7 @@ void OpDispatchBuilder::BSFOp(OpcodeArgs) {
|
||||
}
|
||||
|
||||
void OpDispatchBuilder::BSROp(OpcodeArgs) {
|
||||
const uint8_t GPRSize = GetGPRSize();
|
||||
const uint8_t GPRSize = CTX->GetGPRSize();
|
||||
const uint8_t DstSize = GetDstSize(Op) == 2 ? 2 : GPRSize;
|
||||
OrderedNode *Dest = LoadSource_WithOpSize(GPRClass, Op, Op->Dest, DstSize, Op->Flags);
|
||||
OrderedNode *Src = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags);
|
||||
@@ -4307,7 +4307,7 @@ void OpDispatchBuilder::CMPXCHGOp(OpcodeArgs) {
|
||||
// *Xn = Xt
|
||||
// Xs = MemData
|
||||
|
||||
const auto GPRSize = GetGPRSize();
|
||||
const auto GPRSize = CTX->GetGPRSize();
|
||||
auto Size = GetSrcSize(Op);
|
||||
|
||||
// This is our source register
|
||||
@@ -4505,11 +4505,8 @@ void OpDispatchBuilder::CreateJumpBlocks(fextl::vector<FEXCore::Frontend::Decode
|
||||
}
|
||||
}
|
||||
|
||||
void OpDispatchBuilder::BeginFunction(uint64_t RIP, fextl::vector<FEXCore::Frontend::Decoder::DecodedBlocks> const *Blocks, uint32_t NumInstructions, bool _Is64BitMode) {
|
||||
void OpDispatchBuilder::BeginFunction(uint64_t RIP, fextl::vector<FEXCore::Frontend::Decoder::DecodedBlocks> const *Blocks, uint32_t NumInstructions) {
|
||||
Entry = RIP;
|
||||
Is64BitMode = _Is64BitMode;
|
||||
LOGMAN_THROW_A_FMT(Is64BitMode == CTX->Config.Is64BitMode, "Expected operating mode to not change at runtime!");
|
||||
|
||||
auto IRHeader = _IRHeader(InvalidNode, RIP, 0, NumInstructions);
|
||||
CreateJumpBlocks(Blocks);
|
||||
|
||||
@@ -4524,7 +4521,7 @@ void OpDispatchBuilder::Finalize() {
|
||||
// Calculate flags early.
|
||||
// This usually doesn't emit any IR but in the case of hitting the block instruction limit it will
|
||||
CalculateDeferredFlags();
|
||||
const uint8_t GPRSize = GetGPRSize();
|
||||
const uint8_t GPRSize = CTX->GetGPRSize();
|
||||
|
||||
// Node 0 is invalid node
|
||||
OrderedNode *RealNode = reinterpret_cast<OrderedNode*>(GetNode(1));
|
||||
@@ -4565,7 +4562,7 @@ uint32_t OpDispatchBuilder::GetDstBitSize(X86Tables::DecodedOp Op) const {
|
||||
}
|
||||
|
||||
OrderedNode *OpDispatchBuilder::GetSegment(uint32_t Flags, uint32_t DefaultPrefix, bool Override) {
|
||||
const uint8_t GPRSize = GetGPRSize();
|
||||
const uint8_t GPRSize = CTX->GetGPRSize();
|
||||
|
||||
if (CTX->Config.Is64BitMode) {
|
||||
if (Flags & FEXCore::X86Tables::DecodeFlags::FLAG_FS_PREFIX) {
|
||||
@@ -4712,14 +4709,8 @@ void OpDispatchBuilder::UpdatePrefixFromSegment(OrderedNode *Segment, uint32_t S
|
||||
// Use BFE to extract the selector index in bits [15,3] of the segment register.
|
||||
// In some cases the upper 16-bits of the 32-bit GPR contain garbage to ignore.
|
||||
Segment = _Bfe(OpSize::i32Bit, 16 - 3, 3, Segment);
|
||||
OrderedNode *NewSegment = _LoadContextIndexed(Segment, 8, offsetof(FEXCore::Core::CPUState, gdt[0]), 8, GPRClass);
|
||||
auto NewSegment = _LoadContextIndexed(Segment, 4, offsetof(FEXCore::Core::CPUState, gdt[0]), 4, GPRClass);
|
||||
CheckLegacySegmentWrite(NewSegment, SegmentReg);
|
||||
|
||||
// Extract the 32-bit base from the GDT segment.
|
||||
auto Upper32 = _Lshr(OpSize::i64Bit, NewSegment, _Constant(32));
|
||||
auto Masked = _And(OpSize::i32Bit, Upper32, _Constant(0xFF00'0000));
|
||||
OrderedNode *Merged = _Orlshr(OpSize::i32Bit, Masked, NewSegment, 16);
|
||||
NewSegment = _Bfi(OpSize::i32Bit, 8, 16, Merged, Upper32);
|
||||
switch (SegmentReg) {
|
||||
case FEXCore::X86Tables::DecodeFlags::FLAG_ES_PREFIX:
|
||||
_StoreContext(4, GPRClass, NewSegment, offsetof(FEXCore::Core::CPUState, es_cached));
|
||||
@@ -4757,7 +4748,7 @@ OrderedNode *OpDispatchBuilder::LoadSource_WithOpSize(RegisterClassType Class, X
|
||||
|
||||
OrderedNode *Src {nullptr};
|
||||
bool LoadableType = false;
|
||||
const uint8_t GPRSize = GetGPRSize();
|
||||
const uint8_t GPRSize = CTX->GetGPRSize();
|
||||
const uint32_t AddrSize = (Op->Flags & X86Tables::DecodeFlags::FLAG_ADDRESS_SIZE) != 0 ? (GPRSize >> 1) : GPRSize;
|
||||
|
||||
if (Operand.IsLiteral()) {
|
||||
@@ -4815,7 +4806,7 @@ OrderedNode *OpDispatchBuilder::LoadSource_WithOpSize(RegisterClassType Class, X
|
||||
}
|
||||
}
|
||||
else if (Operand.IsRIPRelative()) {
|
||||
if (Is64BitMode) {
|
||||
if (CTX->Config.Is64BitMode) {
|
||||
Src = GetRelocatedPC(Op, Operand.Data.RIPLiteral.Value.s);
|
||||
}
|
||||
else {
|
||||
@@ -4917,12 +4908,12 @@ OrderedNode *OpDispatchBuilder::LoadSource_WithOpSize(RegisterClassType Class, X
|
||||
}
|
||||
|
||||
OrderedNode *OpDispatchBuilder::GetRelocatedPC(FEXCore::X86Tables::DecodedOp const& Op, int64_t Offset) {
|
||||
const uint8_t GPRSize = GetGPRSize();
|
||||
const uint8_t GPRSize = CTX->GetGPRSize();
|
||||
return _EntrypointOffset(IR::SizeToOpSize(GPRSize), Op->PC + Op->InstSize + Offset - Entry);
|
||||
}
|
||||
|
||||
OrderedNode *OpDispatchBuilder::LoadGPRRegister(uint32_t GPR, int8_t Size, uint8_t Offset, bool AllowUpperGarbage) {
|
||||
const uint8_t GPRSize = GetGPRSize();
|
||||
const uint8_t GPRSize = CTX->GetGPRSize();
|
||||
if (Size == -1) {
|
||||
Size = GPRSize;
|
||||
}
|
||||
@@ -4950,7 +4941,7 @@ OrderedNode *OpDispatchBuilder::LoadXMMRegister(uint32_t XMM) {
|
||||
}
|
||||
|
||||
void OpDispatchBuilder::StoreGPRRegister(uint32_t GPR, OrderedNode *const Src, int8_t Size, uint8_t Offset) {
|
||||
const uint8_t GPRSize = GetGPRSize();
|
||||
const uint8_t GPRSize = CTX->GetGPRSize();
|
||||
if (Size == -1) {
|
||||
Size = GPRSize;
|
||||
}
|
||||
@@ -4993,7 +4984,7 @@ void OpDispatchBuilder::StoreResult_WithOpSize(FEXCore::IR::RegisterClassType Cl
|
||||
// 32bit ops ZEXT the result to 64bit
|
||||
OrderedNode *MemStoreDst {nullptr};
|
||||
bool MemStore = false;
|
||||
const uint8_t GPRSize = GetGPRSize();
|
||||
const uint8_t GPRSize = CTX->GetGPRSize();
|
||||
const uint32_t AddrSize = (Op->Flags & X86Tables::DecodeFlags::FLAG_ADDRESS_SIZE) != 0 ? (GPRSize >> 1) : GPRSize;
|
||||
|
||||
if (Operand.IsLiteral()) {
|
||||
@@ -5071,7 +5062,7 @@ void OpDispatchBuilder::StoreResult_WithOpSize(FEXCore::IR::RegisterClassType Cl
|
||||
}
|
||||
}
|
||||
else if (Operand.IsRIPRelative()) {
|
||||
if (Is64BitMode) {
|
||||
if (CTX->Config.Is64BitMode) {
|
||||
MemStoreDst = GetRelocatedPC(Op, Operand.Data.RIPLiteral.Value.s);
|
||||
}
|
||||
else {
|
||||
@@ -5338,7 +5329,7 @@ void OpDispatchBuilder::INTOp(OpcodeArgs) {
|
||||
// Calculate flags early.
|
||||
CalculateDeferredFlags();
|
||||
|
||||
const uint8_t GPRSize = GetGPRSize();
|
||||
const uint8_t GPRSize = CTX->GetGPRSize();
|
||||
|
||||
if (SetRIPToNext) {
|
||||
BlockSetRIP = SetRIPToNext;
|
||||
@@ -5399,7 +5390,7 @@ void OpDispatchBuilder::LZCNT(OpcodeArgs) {
|
||||
}
|
||||
|
||||
void OpDispatchBuilder::MOVBEOp(OpcodeArgs) {
|
||||
const uint8_t GPRSize = GetGPRSize();
|
||||
const uint8_t GPRSize = CTX->GetGPRSize();
|
||||
const auto SrcSize = GetSrcSize(Op);
|
||||
|
||||
OrderedNode *Src = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags, {.Align = 1});
|
||||
@@ -5489,7 +5480,7 @@ void OpDispatchBuilder::RDTSCPOp(OpcodeArgs) {
|
||||
}
|
||||
|
||||
void OpDispatchBuilder::CRC32(OpcodeArgs) {
|
||||
const uint8_t GPRSize = GetGPRSize();
|
||||
const uint8_t GPRSize = CTX->GetGPRSize();
|
||||
|
||||
// Destination GPR size is always 4 or 8 bytes depending on widening
|
||||
uint8_t DstSize = Op->Flags & FEXCore::X86Tables::DecodeFlags::FLAG_REX_WIDENING ? 8 : 4;
|
||||
@@ -5522,7 +5513,7 @@ void OpDispatchBuilder::UnimplementedOp(OpcodeArgs) {
|
||||
// Ensure flags are calculated on invalid op.
|
||||
CalculateDeferredFlags();
|
||||
|
||||
const uint8_t GPRSize = GetGPRSize();
|
||||
const uint8_t GPRSize = CTX->GetGPRSize();
|
||||
|
||||
// We don't actually support this instruction
|
||||
// Multiblock may hit it though
|
||||
@@ -5547,7 +5538,7 @@ void OpDispatchBuilder::InvalidOp(OpcodeArgs) {
|
||||
// Ensure flags are calculated on invalid op.
|
||||
CalculateDeferredFlags();
|
||||
|
||||
const uint8_t GPRSize = GetGPRSize();
|
||||
const uint8_t GPRSize = CTX->GetGPRSize();
|
||||
|
||||
// We don't actually support this instruction
|
||||
// Multiblock may hit it though
|
||||
|
||||
Reference in new issue
Block a user