Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OpcodeDispatcher: Add helper for making segment offset addresses #3566

Merged
merged 1 commit into from
Apr 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 42 additions & 65 deletions FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -395,8 +395,8 @@ void OpDispatchBuilder::ADCOp(OpcodeArgs) {
auto ALUOp = _Adc(OpSize, _Constant(0), Src);

HandledLock = true;
OrderedNode *DestMem = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, {.LoadData = false});
DestMem = AppendSegmentOffset(DestMem, Op->Flags);

OrderedNode *DestMem = MakeSegmentAddress(Op, Op->Dest);
Before = _AtomicFetchAdd(IR::SizeToOpSize(Size), ALUOp, DestMem);
}
else {
Expand All @@ -421,9 +421,8 @@ void OpDispatchBuilder::SBBOp(OpcodeArgs) {
OrderedNode *Before{};
if (DestIsLockedMem(Op)) {
HandledLock = true;
OrderedNode *DestMem = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, {.LoadData = false});
DestMem = AppendSegmentOffset(DestMem, Op->Flags);

OrderedNode *DestMem = MakeSegmentAddress(Op, Op->Dest);
auto SrcPlusCF = _Adc(OpSize, _Constant(0), Src);
Before = _AtomicFetchSub(IR::SizeToOpSize(Size), SrcPlusCF, DestMem);
}
Expand Down Expand Up @@ -1305,11 +1304,9 @@ void OpDispatchBuilder::XCHGOp(OpcodeArgs) {
OrderedNode *Src = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags,
{.AllowUpperGarbage = true});
if (DestIsMem(Op)) {
HandledLock = Op->Flags & FEXCore::X86Tables::DecodeFlags::FLAG_LOCK;
OrderedNode *Dest = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, {.LoadData = false});

Dest = AppendSegmentOffset(Dest, Op->Flags);
HandledLock = (Op->Flags & FEXCore::X86Tables::DecodeFlags::FLAG_LOCK) != 0;

OrderedNode *Dest = MakeSegmentAddress(Op, Op->Dest);
auto Result = _AtomicSwap(OpSizeFromSrc(Op), Src, Dest);
StoreResult(GPRClass, Op, Op->Src[0], Result, -1);
}
Expand Down Expand Up @@ -2615,8 +2612,7 @@ void OpDispatchBuilder::BTOp(OpcodeArgs) {
}
} else {
// Load the address to the memory location
OrderedNode *Dest = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, {.LoadData = false});
Dest = AppendSegmentOffset(Dest, Op->Flags);
OrderedNode *Dest = MakeSegmentAddress(Op, Op->Dest);
// Get the bit selection from the src
OrderedNode *BitSelect = _Bfe(IR::SizeToOpSize(std::max<uint8_t>(4u, GetOpSize(Src))), 3, 0, Src);

Expand Down Expand Up @@ -2883,8 +2879,7 @@ void OpDispatchBuilder::NOTOp(OpcodeArgs) {

if (DestIsLockedMem(Op)) {
HandledLock = true;
OrderedNode *DestMem = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, {.LoadData = false});
DestMem = AppendSegmentOffset(DestMem, Op->Flags);
OrderedNode *DestMem = MakeSegmentAddress(Op, Op->Dest);
_AtomicXor(IR::SizeToOpSize(Size), MaskConst, DestMem);
} else if (!Op->Dest.IsGPR()) {
// GPR version plays fast and loose with sizes, be safe for memory tho.
Expand Down Expand Up @@ -3089,10 +3084,10 @@ void OpDispatchBuilder::AADOp(OpcodeArgs) {
}

void OpDispatchBuilder::XLATOp(OpcodeArgs) {
OrderedNode *Src = LoadGPRRegister(X86State::REG_RBX);
OrderedNode *Src = MakeSegmentAddress(X86State::REG_RBX, Op->Flags,
X86Tables::DecodeFlags::FLAG_DS_PREFIX);
OrderedNode *Offset = LoadGPRRegister(X86State::REG_RAX, 1);

Src = AppendSegmentOffset(Src, Op->Flags, FEXCore::X86Tables::DecodeFlags::FLAG_DS_PREFIX);
Src = _Add(OpSize::i64Bit, Src, Offset);

auto Res = _LoadMemAutoTSO(GPRClass, 1, Src, 1);
Expand Down Expand Up @@ -3234,10 +3229,9 @@ void OpDispatchBuilder::INCOp(OpcodeArgs) {

if (IsLocked) {
HandledLock = true;
auto DestAddress = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, {.LoadData = false});
DestAddress = AppendSegmentOffset(DestAddress, Op->Flags);
Dest = _AtomicFetchAdd(OpSizeFromSrc(Op), OneConst, DestAddress);

OrderedNode *DestAddress = MakeSegmentAddress(Op, Op->Dest);
Dest = _AtomicFetchAdd(OpSizeFromSrc(Op), OneConst, DestAddress);
} else {
Dest = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, {.AllowUpperGarbage = Size >= 32});
}
Expand Down Expand Up @@ -3282,8 +3276,8 @@ void OpDispatchBuilder::DECOp(OpcodeArgs) {

if (IsLocked) {
HandledLock = true;
auto DestAddress = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, {.LoadData = false});
DestAddress = AppendSegmentOffset(DestAddress, Op->Flags);

OrderedNode *DestAddress = MakeSegmentAddress(Op, Op->Dest);

// Use Add instead of Sub to avoid a NEG
Dest = _AtomicFetchAdd(OpSizeFromSrc(Op), _Constant(Size, -1), DestAddress);
Expand Down Expand Up @@ -3328,10 +3322,9 @@ void OpDispatchBuilder::STOSOp(OpcodeArgs) {
if (!Repeat) {
// Src is used only for a store of the same size so allow garbage
OrderedNode *Src = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags, {.AllowUpperGarbage = true});
OrderedNode *Dest = LoadGPRRegister(X86State::REG_RDI);

// Only ES prefix
Dest = AppendSegmentOffset(Dest, 0, FEXCore::X86Tables::DecodeFlags::FLAG_ES_PREFIX, true);
OrderedNode *Dest = MakeSegmentAddress(X86State::REG_RDI, 0, X86Tables::DecodeFlags::FLAG_ES_PREFIX, true);

// Store to memory where RDI points
_StoreMemAutoTSO(GPRClass, Size, Dest, Src, Size);
Expand Down Expand Up @@ -3390,10 +3383,8 @@ void OpDispatchBuilder::MOVSOp(OpcodeArgs) {
StoreGPRRegister(X86State::REG_RSI, Result_Src);
}
else {
OrderedNode *RSI = LoadGPRRegister(X86State::REG_RSI);
OrderedNode *RDI = LoadGPRRegister(X86State::REG_RDI);
RDI= AppendSegmentOffset(RDI, 0, FEXCore::X86Tables::DecodeFlags::FLAG_ES_PREFIX, true);
RSI = AppendSegmentOffset(RSI, Op->Flags, FEXCore::X86Tables::DecodeFlags::FLAG_DS_PREFIX);
OrderedNode *RSI = MakeSegmentAddress(X86State::REG_RSI, Op->Flags, X86Tables::DecodeFlags::FLAG_DS_PREFIX);
OrderedNode *RDI = MakeSegmentAddress(X86State::REG_RDI, 0, X86Tables::DecodeFlags::FLAG_ES_PREFIX, true);

auto Src = _LoadMemAutoTSO(GPRClass, Size, RSI, Size);

Expand All @@ -3420,13 +3411,12 @@ void OpDispatchBuilder::CMPSOp(OpcodeArgs) {

bool Repeat = Op->Flags & (FEXCore::X86Tables::DecodeFlags::FLAG_REPNE_PREFIX | FEXCore::X86Tables::DecodeFlags::FLAG_REP_PREFIX);
if (!Repeat) {
OrderedNode *Dest_RSI = LoadGPRRegister(X86State::REG_RSI);
OrderedNode *Dest_RDI = LoadGPRRegister(X86State::REG_RDI);

// Only ES prefix
Dest_RDI = AppendSegmentOffset(Dest_RDI, 0, FEXCore::X86Tables::DecodeFlags::FLAG_ES_PREFIX, true);
// Default DS prefix
Dest_RSI = AppendSegmentOffset(Dest_RSI, Op->Flags, FEXCore::X86Tables::DecodeFlags::FLAG_DS_PREFIX);
OrderedNode *Dest_RSI = MakeSegmentAddress(X86State::REG_RSI, Op->Flags,
X86Tables::DecodeFlags::FLAG_DS_PREFIX);
// Only ES prefix
OrderedNode *Dest_RDI = MakeSegmentAddress(X86State::REG_RDI, 0,
X86Tables::DecodeFlags::FLAG_ES_PREFIX, true);

auto Src1 = _LoadMemAutoTSO(GPRClass, Size, Dest_RDI, Size);
auto Src2 = _LoadMemAutoTSO(GPRClass, Size, Dest_RSI, Size);
Expand Down Expand Up @@ -3470,13 +3460,12 @@ void OpDispatchBuilder::CMPSOp(OpcodeArgs) {

// Working loop
{
OrderedNode *Dest_RSI = LoadGPRRegister(X86State::REG_RSI);
OrderedNode *Dest_RDI = LoadGPRRegister(X86State::REG_RDI);

// Only ES prefix
Dest_RDI = AppendSegmentOffset(Dest_RDI, 0, FEXCore::X86Tables::DecodeFlags::FLAG_ES_PREFIX, true);
// Default DS prefix
Dest_RSI = AppendSegmentOffset(Dest_RSI, Op->Flags, FEXCore::X86Tables::DecodeFlags::FLAG_DS_PREFIX);
OrderedNode *Dest_RSI = MakeSegmentAddress(X86State::REG_RSI, Op->Flags,
X86Tables::DecodeFlags::FLAG_DS_PREFIX);
// Only ES prefix
OrderedNode *Dest_RDI = MakeSegmentAddress(X86State::REG_RDI, 0,
X86Tables::DecodeFlags::FLAG_ES_PREFIX, true);

auto Src1 = _LoadMemAutoTSO(GPRClass, Size, Dest_RDI, Size);
auto Src2 = _LoadMem(GPRClass, Size, Dest_RSI, Size);
Expand Down Expand Up @@ -3548,8 +3537,8 @@ void OpDispatchBuilder::LODSOp(OpcodeArgs) {
const bool Repeat = (Op->Flags & (FEXCore::X86Tables::DecodeFlags::FLAG_REP_PREFIX | FEXCore::X86Tables::DecodeFlags::FLAG_REPNE_PREFIX)) != 0;

if (!Repeat) {
OrderedNode *Dest_RSI = LoadGPRRegister(X86State::REG_RSI);
Dest_RSI = AppendSegmentOffset(Dest_RSI, Op->Flags, FEXCore::X86Tables::DecodeFlags::FLAG_DS_PREFIX);
OrderedNode *Dest_RSI = MakeSegmentAddress(X86State::REG_RSI, Op->Flags,
X86Tables::DecodeFlags::FLAG_DS_PREFIX);

auto Src = _LoadMemAutoTSO(GPRClass, Size, Dest_RSI, Size);

Expand Down Expand Up @@ -3591,9 +3580,8 @@ void OpDispatchBuilder::LODSOp(OpcodeArgs) {

// Working loop
{
OrderedNode *Dest_RSI = LoadGPRRegister(X86State::REG_RSI);

Dest_RSI = AppendSegmentOffset(Dest_RSI, Op->Flags, FEXCore::X86Tables::DecodeFlags::FLAG_DS_PREFIX);
OrderedNode *Dest_RSI = MakeSegmentAddress(X86State::REG_RSI, Op->Flags,
X86Tables::DecodeFlags::FLAG_DS_PREFIX);

auto Src = _LoadMemAutoTSO(GPRClass, Size, Dest_RSI, Size);

Expand Down Expand Up @@ -3635,8 +3623,8 @@ void OpDispatchBuilder::SCASOp(OpcodeArgs) {
const bool Repeat = (Op->Flags & (FEXCore::X86Tables::DecodeFlags::FLAG_REPNE_PREFIX | FEXCore::X86Tables::DecodeFlags::FLAG_REP_PREFIX)) != 0;

if (!Repeat) {
OrderedNode *Dest_RDI = LoadGPRRegister(X86State::REG_RDI);
Dest_RDI = AppendSegmentOffset(Dest_RDI, 0, FEXCore::X86Tables::DecodeFlags::FLAG_ES_PREFIX, true);
OrderedNode *Dest_RDI = MakeSegmentAddress(X86State::REG_RDI, 0,
X86Tables::DecodeFlags::FLAG_ES_PREFIX, true);

auto Src1 = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags, {.AllowUpperGarbage = true});
auto Src2 = _LoadMemAutoTSO(GPRClass, Size, Dest_RDI, Size);
Expand Down Expand Up @@ -3675,9 +3663,8 @@ void OpDispatchBuilder::SCASOp(OpcodeArgs) {

// Working loop
{
OrderedNode *Dest_RDI = LoadGPRRegister(X86State::REG_RDI);

Dest_RDI = AppendSegmentOffset(Dest_RDI, 0, FEXCore::X86Tables::DecodeFlags::FLAG_ES_PREFIX, true);
OrderedNode *Dest_RDI = MakeSegmentAddress(X86State::REG_RDI, 0,
X86Tables::DecodeFlags::FLAG_ES_PREFIX, true);

auto Src1 = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags, {.AllowUpperGarbage = true});
auto Src2 = _LoadMemAutoTSO(GPRClass, Size, Dest_RDI, Size);
Expand Down Expand Up @@ -3776,9 +3763,7 @@ void OpDispatchBuilder::NEGOp(OpcodeArgs) {
auto ZeroConst = _Constant(0);

if (DestIsLockedMem(Op)) {
OrderedNode *DestMem = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, {.LoadData = false});
DestMem = AppendSegmentOffset(DestMem, Op->Flags);

OrderedNode *DestMem = MakeSegmentAddress(Op, Op->Dest);
OrderedNode *Dest = _AtomicFetchNeg(IR::SizeToOpSize(Size), DestMem);
CalculateFlags_SUB(Size, ZeroConst, Dest);
}
Expand Down Expand Up @@ -4041,9 +4026,7 @@ void OpDispatchBuilder::CMPXCHGOp(OpcodeArgs) {
Src3Lower = Src3;
}
// If this is a memory location then we want the pointer to it
OrderedNode *Src1 = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, {.LoadData = false});

Src1 = AppendSegmentOffset(Src1, Op->Flags);
OrderedNode *Src1 = MakeSegmentAddress(Op, Op->Dest);

// DataSrc = *Src1
// if (DataSrc == Src3) { *Src1 == Src2; } Src2 = DataSrc
Expand Down Expand Up @@ -4076,10 +4059,9 @@ void OpDispatchBuilder::CMPXCHGPairOp(OpcodeArgs) {
uint8_t Size = Op->Flags & FEXCore::X86Tables::DecodeFlags::FLAG_REX_WIDENING ? 8 : 4;

HandledLock = (Op->Flags & FEXCore::X86Tables::DecodeFlags::FLAG_LOCK) != 0;
// If this is a memory location then we want the pointer to it
OrderedNode *Src1 = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, {.LoadData = false});

Src1 = AppendSegmentOffset(Src1, Op->Flags);
// If this is a memory location then we want the pointer to it
OrderedNode *Src1 = MakeSegmentAddress(Op, Op->Dest);

OrderedNode *Expected_Lower = LoadGPRRegister(X86State::REG_RAX, Size);
OrderedNode *Expected_Upper = LoadGPRRegister(X86State::REG_RDX, Size);
Expand Down Expand Up @@ -4862,9 +4844,7 @@ void OpDispatchBuilder::ALUOpImpl(OpcodeArgs, FEXCore::IR::IROps ALUIROp, FEXCor

if (DestIsLockedMem(Op)) {
HandledLock = true;
OrderedNode *DestMem = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, {.LoadData = false});
DestMem = AppendSegmentOffset(DestMem, Op->Flags);

OrderedNode *DestMem = MakeSegmentAddress(Op, Op->Dest);
DeriveOp(FetchOp, AtomicFetchOp, _AtomicFetchAdd(IR::SizeToOpSize(Size), Src, DestMem));
Dest = FetchOp;
}
Expand Down Expand Up @@ -5055,14 +5035,12 @@ void OpDispatchBuilder::MOVBEOp(OpcodeArgs) {
}

void OpDispatchBuilder::CLWB(OpcodeArgs) {
OrderedNode *DestMem = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, {.LoadData = false});
DestMem = AppendSegmentOffset(DestMem, Op->Flags);
OrderedNode *DestMem = MakeSegmentAddress(Op, Op->Dest);
_CacheLineClean(DestMem);
}

void OpDispatchBuilder::CLFLUSHOPT(OpcodeArgs) {
OrderedNode *DestMem = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, {.LoadData = false});
DestMem = AppendSegmentOffset(DestMem, Op->Flags);
OrderedNode *DestMem = MakeSegmentAddress(Op, Op->Dest);
_CacheLineClear(DestMem, false);
}

Expand Down Expand Up @@ -5093,8 +5071,7 @@ void OpDispatchBuilder::StoreFenceOrCLFlush(OpcodeArgs) {
}
else {
// This is a CLFlush
OrderedNode *DestMem = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, {.LoadData = false});
DestMem = AppendSegmentOffset(DestMem, Op->Flags);
OrderedNode *DestMem = MakeSegmentAddress(Op, Op->Dest);
_CacheLineClear(DestMem, true);
}
}
Expand Down
14 changes: 14 additions & 0 deletions FEXCore/Source/Interface/Core/OpcodeDispatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -1236,6 +1236,20 @@ friend class FEXCore::IR::PassManager;
void StoreResult(FEXCore::IR::RegisterClassType Class, FEXCore::X86Tables::DecodedOp Op, FEXCore::X86Tables::DecodedOperand const& Operand, OrderedNode *const Src, int8_t Align, MemoryAccessType AccessType = MemoryAccessType::DEFAULT);
void StoreResult(FEXCore::IR::RegisterClassType Class, FEXCore::X86Tables::DecodedOp Op, OrderedNode *const Src, int8_t Align, MemoryAccessType AccessType = MemoryAccessType::DEFAULT);

// In several instances, it's desirable to get a base address with the segment offset
// applied to it. This pulls all the common-case appending into a single set of functions.
[[nodiscard]] OrderedNode *MakeSegmentAddress(const X86Tables::DecodedOp& Op, const X86Tables::DecodedOperand& Operand, uint8_t OpSize) {
OrderedNode *Mem = LoadSource_WithOpSize(GPRClass, Op, Operand, OpSize, Op->Flags, {.LoadData = false});
return AppendSegmentOffset(Mem, Op->Flags);
}
[[nodiscard]] OrderedNode *MakeSegmentAddress(const X86Tables::DecodedOp& Op, const X86Tables::DecodedOperand& Operand) {
return MakeSegmentAddress(Op, Operand, GetSrcSize(Op));
}
[[nodiscard]] OrderedNode *MakeSegmentAddress(X86State::X86Reg Reg, uint32_t Flags, uint32_t DefaultPrefix = 0, bool Override = false) {
OrderedNode *Address = LoadGPRRegister(Reg);
return AppendSegmentOffset(Address, Flags, DefaultPrefix, Override);
}

constexpr OpSize GetGuestVectorLength() const {
return CTX->HostFeatures.SupportsAVX ? OpSize::i256Bit : OpSize::i128Bit;
}
Expand Down
26 changes: 7 additions & 19 deletions FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1758,10 +1758,7 @@ void OpDispatchBuilder::VBROADCASTOp(OpcodeArgs) {
Result = _VDupElement(DstSize, ElementSize, Src, 0);
} else {
// Get the address to broadcast from into a GPR.
OrderedNode *Address = LoadSource_WithOpSize(GPRClass, Op, Op->Src[0], CTX->GetGPRSize(), Op->Flags,
{.LoadData = false});
Address = AppendSegmentOffset(Address, Op->Flags);

OrderedNode *Address = MakeSegmentAddress(Op, Op->Src[0], CTX->GetGPRSize());
Result = _VBroadcastFromMem(DstSize, ElementSize, Address);
}

Expand Down Expand Up @@ -2807,11 +2804,8 @@ void OpDispatchBuilder::MASKMOVOp(OpcodeArgs) {
// Vector that will overwrite byte elements.
OrderedNode *VectorSrc = LoadSource(GPRClass, Op, Op->Dest, Op->Flags);

// RDI source
auto MemDest = LoadGPRRegister(X86State::REG_RDI);

// DS prefix by default.
MemDest = AppendSegmentOffset(MemDest, Op->Flags, FEXCore::X86Tables::DecodeFlags::FLAG_DS_PREFIX);
// RDI source (DS prefix by default)
auto MemDest = MakeSegmentAddress(X86State::REG_RDI, Op->Flags, X86Tables::DecodeFlags::FLAG_DS_PREFIX);

OrderedNode *XMMReg = _LoadMem(FPRClass, Size, MemDest, 1);

Expand All @@ -2825,9 +2819,7 @@ void OpDispatchBuilder::VMASKMOVOpImpl(OpcodeArgs, size_t ElementSize, size_t Da
const X86Tables::DecodedOperand& DataOp) {

const auto MakeAddress = [this, Op](const X86Tables::DecodedOperand& Data) {
OrderedNode *BaseAddr = LoadSource_WithOpSize(GPRClass, Op, Data, CTX->GetGPRSize(), Op->Flags,
{.LoadData = false});
return AppendSegmentOffset(BaseAddr, Op->Flags);
return MakeSegmentAddress(Op, Data, CTX->GetGPRSize());
};

OrderedNode *Mask = LoadSource_WithOpSize(FPRClass, Op, MaskOp, DataSize, Op->Flags);
Expand Down Expand Up @@ -2988,8 +2980,7 @@ template
void OpDispatchBuilder::AVXVFCMPOp<8>(OpcodeArgs);

void OpDispatchBuilder::FXSaveOp(OpcodeArgs) {
OrderedNode *Mem = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, {.LoadData = false});
Mem = AppendSegmentOffset(Mem, Op->Flags);
OrderedNode *Mem = MakeSegmentAddress(Op, Op->Dest);

SaveX87State(Op, Mem);
SaveSSEState(Mem);
Expand All @@ -3001,8 +2992,7 @@ void OpDispatchBuilder::XSaveOp(OpcodeArgs) {
}

OrderedNode *OpDispatchBuilder::XSaveBase(X86Tables::DecodedOp Op) {
OrderedNode *Mem = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, {.LoadData = false});
return AppendSegmentOffset(Mem, Op->Flags);
return MakeSegmentAddress(Op, Op->Dest);
}

void OpDispatchBuilder::XSaveOpImpl(OpcodeArgs) {
Expand Down Expand Up @@ -3195,9 +3185,7 @@ OrderedNode *OpDispatchBuilder::GetMXCSR() {

void OpDispatchBuilder::FXRStoreOp(OpcodeArgs) {
const auto OpSize = IR::SizeToOpSize(CTX->GetGPRSize());

OrderedNode *Mem = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags, {.LoadData = false});
Mem = AppendSegmentOffset(Mem, Op->Flags);
OrderedNode *Mem = MakeSegmentAddress(Op, Op->Src[0]);

RestoreX87State(Mem);
RestoreSSEState(Mem);
Expand Down
Loading
Loading