Merge pull request #3400 from Sonicadvance1/revert_runtime_longmode_switch

Revert #3303
This commit is contained in:
Mai 2024-02-02 11:53:44 -05:00 committed by GitHub
commit 6993f4fd8d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
35 changed files with 2789 additions and 2900 deletions

View File

@ -336,6 +336,8 @@ namespace FEXCore::Context {
void CopyMemoryMapping(FEXCore::Core::InternalThreadState *ParentThread, FEXCore::Core::InternalThreadState *ChildThread);
uint8_t GetGPRSize() const { return Config.Is64BitMode ? 8 : 4; }
FEXCore::JITSymbols Symbols;
void GetVDSOSigReturn(VDSOSigReturn *VDSOPointers) override {

View File

@ -569,22 +569,6 @@ namespace FEXCore::Context {
Thread->CurrentFrame->State.gregs[X86State::REG_RSP] = StackPointer;
Thread->CurrentFrame->State.rip = InitialRIP;
// Set up default code segment.
// Default code segment indexes match the numbers that the Linux kernel uses.
Thread->CurrentFrame->State.cs_idx = 6 << 3;
auto &GDT = Thread->CurrentFrame->State.gdt[Thread->CurrentFrame->State.cs_idx >> 3];
Thread->CurrentFrame->State.SetGDTBase(&GDT, 0);
Thread->CurrentFrame->State.SetGDTLimit(&GDT, 0xF'FFFFU);
if (Config.Is64BitMode) {
GDT.L = 1; // L = Long Mode = 64-bit
GDT.D = 0; // D = Default Operand SIze = Reserved
}
else {
GDT.L = 0; // L = Long Mode = 32-bit
GDT.D = 1; // D = Default Operand Size = 32-bit
}
// Copy over the new thread state to the new object
if (NewThreadState) {
memcpy(&Thread->CurrentFrame->State, NewThreadState, sizeof(FEXCore::Core::CPUState));
@ -777,7 +761,7 @@ namespace FEXCore::Context {
bool HadDispatchError {false};
Thread->FrontendDecoder->DecodeInstructionsAtEntry(Thread, GuestCode, GuestRIP, MaxInst, [Thread](uint64_t BlockEntry, uint64_t Start, uint64_t Length) {
Thread->FrontendDecoder->DecodeInstructionsAtEntry(GuestCode, GuestRIP, MaxInst, [Thread](uint64_t BlockEntry, uint64_t Start, uint64_t Length) {
if (Thread->LookupCache->AddBlockExecutableRange(BlockEntry, Start, Length)) {
static_cast<ContextImpl*>(Thread->CTX)->SyscallHandler->MarkGuestExecutableRange(Thread, Start, Length);
}
@ -786,9 +770,9 @@ namespace FEXCore::Context {
auto BlockInfo = Thread->FrontendDecoder->GetDecodedBlockInfo();
auto CodeBlocks = &BlockInfo->Blocks;
Thread->OpDispatcher->BeginFunction(GuestRIP, CodeBlocks, BlockInfo->TotalInstructionCount, BlockInfo->Is64BitMode);
Thread->OpDispatcher->BeginFunction(GuestRIP, CodeBlocks, BlockInfo->TotalInstructionCount);
const uint8_t GPRSize = Thread->OpDispatcher->GetGPRSize();
const uint8_t GPRSize = GetGPRSize();
for (size_t j = 0; j < CodeBlocks->size(); ++j) {
FEXCore::Frontend::Decoder::DecodedBlocks const &Block = CodeBlocks->at(j);
@ -873,6 +857,8 @@ namespace FEXCore::Context {
}
if (NeedsBlockEnd) {
const uint8_t GPRSize = GetGPRSize();
// We had some instructions. Early exit
Thread->OpDispatcher->_ExitFunction(Thread->OpDispatcher->_EntrypointOffset(IR::SizeToOpSize(GPRSize), Block.Entry + BlockInstructionsLength - GuestRIP));
break;

View File

@ -310,7 +310,7 @@ bool Decoder::NormalOp(FEXCore::X86Tables::X86InstInfo const *Info, uint16_t Op,
uint8_t DestSize{};
const bool HasWideningDisplacement = (FEXCore::X86Tables::DecodeFlags::GetOpAddr(DecodeInst->Flags, 0) & FEXCore::X86Tables::DecodeFlags::FLAG_WIDENING_SIZE_LAST) != 0 ||
(Options.w && BlockInfo.Is64BitMode);
(Options.w && CTX->Config.Is64BitMode);
const bool HasNarrowingDisplacement = (FEXCore::X86Tables::DecodeFlags::GetOpAddr(DecodeInst->Flags, 0) & FEXCore::X86Tables::DecodeFlags::FLAG_OPERAND_SIZE_LAST) != 0;
const bool HasXMMFlags = (Info->Flags & InstFlags::FLAGS_XMM_FLAGS) != 0;
@ -331,7 +331,7 @@ bool Decoder::NormalOp(FEXCore::X86Tables::X86InstInfo const *Info, uint16_t Op,
const bool HasMODRM = !!(Info->Flags & FEXCore::X86Tables::InstFlags::FLAGS_MODRM);
const bool HasREX = !!(DecodeInst->Flags & DecodeFlags::FLAG_REX_PREFIX);
const bool Has16BitAddressing = !BlockInfo.Is64BitMode &&
const bool Has16BitAddressing = !CTX->Config.Is64BitMode &&
DecodeInst->Flags & DecodeFlags::FLAG_ADDRESS_SIZE;
// This is used for ModRM register modification
@ -386,7 +386,7 @@ bool Decoder::NormalOp(FEXCore::X86Tables::X86InstInfo const *Info, uint16_t Op,
DestSize = 2;
}
else if (
(HasXMMDst || HasMMDst || BlockInfo.Is64BitMode) &&
(HasXMMDst || HasMMDst || CTX->Config.Is64BitMode) &&
(HasWideningDisplacement ||
DstSizeFlag == FEXCore::X86Tables::InstFlags::SIZE_64BIT ||
DstSizeFlag == FEXCore::X86Tables::InstFlags::SIZE_64BITDEF)) {
@ -424,7 +424,7 @@ bool Decoder::NormalOp(FEXCore::X86Tables::X86InstInfo const *Info, uint16_t Op,
DecodeInst->Flags |= DecodeFlags::GenSizeSrcSize(DecodeFlags::SIZE_16BIT);
}
else if (
(HasXMMSrc || HasMMSrc || BlockInfo.Is64BitMode) &&
(HasXMMSrc || HasMMSrc || CTX->Config.Is64BitMode) &&
(HasWideningDisplacement ||
SrcSizeFlag == FEXCore::X86Tables::InstFlags::SIZE_64BIT ||
SrcSizeFlag == FEXCore::X86Tables::InstFlags::SIZE_64BITDEF)) {
@ -692,7 +692,7 @@ bool Decoder::NormalOpHeader(FEXCore::X86Tables::X86InstInfo const *Info, uint16
DecodedHeader options{};
if ((Byte1 & 0b10000000) == 0) {
LOGMAN_THROW_A_FMT(BlockInfo.Is64BitMode, "VEX.R shouldn't be 0 in 32-bit mode!");
LOGMAN_THROW_A_FMT(CTX->Config.Is64BitMode, "VEX.R shouldn't be 0 in 32-bit mode!");
DecodeInst->Flags |= DecodeFlags::FLAG_REX_XGPR_R;
}
@ -709,10 +709,10 @@ bool Decoder::NormalOpHeader(FEXCore::X86Tables::X86InstInfo const *Info, uint16
options.w = (Byte2 & 0b10000000) != 0;
options.L = (Byte2 & 0b100) != 0;
if ((Byte1 & 0b01000000) == 0) {
LOGMAN_THROW_A_FMT(BlockInfo.Is64BitMode, "VEX.X shouldn't be 0 in 32-bit mode!");
LOGMAN_THROW_A_FMT(CTX->Config.Is64BitMode, "VEX.X shouldn't be 0 in 32-bit mode!");
DecodeInst->Flags |= DecodeFlags::FLAG_REX_XGPR_X;
}
if (BlockInfo.Is64BitMode && (Byte1 & 0b00100000) == 0) {
if (CTX->Config.Is64BitMode && (Byte1 & 0b00100000) == 0) {
DecodeInst->Flags |= DecodeFlags::FLAG_REX_XGPR_B;
}
if (!(map_select >= 1 && map_select <= 3)) {
@ -787,7 +787,7 @@ bool Decoder::DecodeInstruction(uint64_t PC) {
FEXCore::X86Tables::ModRMDecoded ModRM;
ModRM.Hex = DecodeInst->ModRM;
const bool Has16BitAddressing = !BlockInfo.Is64BitMode &&
const bool Has16BitAddressing = !CTX->Config.Is64BitMode &&
DecodeInst->Flags & DecodeFlags::FLAG_ADDRESS_SIZE;
// All 3DNow! instructions have the second argument as the rm handler
@ -898,17 +898,17 @@ bool Decoder::DecodeInstruction(uint64_t PC) {
DecodeInst->Flags |= DecodeFlags::FLAG_ADDRESS_SIZE;
break;
case 0x26: // ES legacy prefix
if (!BlockInfo.Is64BitMode) {
if (!CTX->Config.Is64BitMode) {
DecodeInst->Flags |= DecodeFlags::FLAG_ES_PREFIX;
}
break;
case 0x2E: // CS legacy prefix
if (!BlockInfo.Is64BitMode) {
if (!CTX->Config.Is64BitMode) {
DecodeInst->Flags |= DecodeFlags::FLAG_CS_PREFIX;
}
break;
case 0x36: // SS legacy prefix
if (!BlockInfo.Is64BitMode) {
if (!CTX->Config.Is64BitMode) {
DecodeInst->Flags |= DecodeFlags::FLAG_SS_PREFIX;
}
break;
@ -916,7 +916,7 @@ bool Decoder::DecodeInstruction(uint64_t PC) {
// Annoyingly GCC generates NOP ops with these prefixes
// Just ignore them for now
// eg. 66 2e 0f 1f 84 00 00 00 00 00 nop WORD PTR cs:[rax+rax*1+0x0]
if (!BlockInfo.Is64BitMode) {
if (!CTX->Config.Is64BitMode) {
DecodeInst->Flags |= DecodeFlags::FLAG_DS_PREFIX;
}
break;
@ -942,7 +942,7 @@ bool Decoder::DecodeInstruction(uint64_t PC) {
auto Info = &FEXCore::X86Tables::BaseOps[Op];
if (Info->Type == FEXCore::X86Tables::TYPE_REX_PREFIX) {
LOGMAN_THROW_A_FMT(BlockInfo.Is64BitMode, "Got REX prefix in 32bit mode");
LOGMAN_THROW_A_FMT(CTX->Config.Is64BitMode, "Got REX prefix in 32bit mode");
DecodeInst->Flags |= DecodeFlags::FLAG_REX_PREFIX;
// Widening displacement
@ -985,7 +985,7 @@ void Decoder::BranchTargetInMultiblockRange() {
// If the RIP setting is conditional AND within our symbol range then it can be considered for multiblock
uint64_t TargetRIP = 0;
const uint8_t GPRSize = GetGPRSize();
const uint8_t GPRSize = CTX->GetGPRSize();
bool Conditional = true;
switch (DecodeInst->OP) {
@ -1052,7 +1052,7 @@ bool Decoder::BranchTargetCanContinue(bool FinalInstruction) const {
}
uint64_t TargetRIP = 0;
const uint8_t GPRSize = GetGPRSize();
const uint8_t GPRSize = CTX->GetGPRSize();
if (DecodeInst->OP == 0xE8) { // Call - immediate target
const uint64_t NextRIP = DecodeInst->PC + DecodeInst->InstSize;
@ -1094,7 +1094,7 @@ const uint8_t *Decoder::AdjustAddrForSpecialRegion(uint8_t const* _InstStream, u
return _InstStream - EntryPoint + RIP;
}
void Decoder::DecodeInstructionsAtEntry(FEXCore::Core::InternalThreadState *Thread, uint8_t const* _InstStream, uint64_t PC, uint64_t MaxInst, std::function<void(uint64_t BlockEntry, uint64_t Start, uint64_t Length)> AddContainedCodePage) {
void Decoder::DecodeInstructionsAtEntry(uint8_t const* _InstStream, uint64_t PC, uint64_t MaxInst, std::function<void(uint64_t BlockEntry, uint64_t Start, uint64_t Length)> AddContainedCodePage) {
FEXCORE_PROFILE_SCOPED("DecodeInstructions");
BlockInfo.TotalInstructionCount = 0;
BlockInfo.Blocks.clear();
@ -1106,11 +1106,6 @@ void Decoder::DecodeInstructionsAtEntry(FEXCore::Core::InternalThreadState *Thre
MaxCondBranchBackwards = ~0ULL;
DecodedBuffer = PoolObject.ReownOrClaimBuffer();
// Decode operating mode from thread's CS segment.
const auto CSSegment = Thread->CurrentFrame->State.gdt[Thread->CurrentFrame->State.cs_idx >> 3];
BlockInfo.Is64BitMode = CSSegment.L == 1;
LOGMAN_THROW_A_FMT(BlockInfo.Is64BitMode == CTX->Config.Is64BitMode, "Expected operating mode to not change at runtime!");
// XXX: Load symbol data
SymbolAvailable = false;
EntryPoint = PC;

View File

@ -29,13 +29,12 @@ public:
struct DecodedBlockInformation final {
uint64_t TotalInstructionCount;
bool Is64BitMode{};
fextl::vector<DecodedBlocks> Blocks;
};
Decoder(FEXCore::Context::ContextImpl *ctx);
~Decoder();
void DecodeInstructionsAtEntry(FEXCore::Core::InternalThreadState *Thread, uint8_t const* InstStream, uint64_t PC, uint64_t MaxInst, std::function<void(uint64_t BlockEntry, uint64_t Start, uint64_t Length)> AddContainedCodePage);
void DecodeInstructionsAtEntry(uint8_t const* InstStream, uint64_t PC, uint64_t MaxInst, std::function<void(uint64_t BlockEntry, uint64_t Start, uint64_t Length)> AddContainedCodePage);
DecodedBlockInformation const *GetDecodedBlockInfo() const {
return &BlockInfo;
@ -82,7 +81,6 @@ private:
size_t DecodedSize {};
uint8_t const *InstStream;
uint8_t GetGPRSize() const { return BlockInfo.Is64BitMode ? 8 : 4; }
static constexpr size_t MAX_INST_SIZE = 15;
uint8_t InstructionSize;

View File

@ -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

View File

@ -185,7 +185,7 @@ public:
auto it = JumpTargets.find(NextRIP);
if (it == JumpTargets.end()) {
const uint8_t GPRSize = GetGPRSize();
const uint8_t GPRSize = CTX->GetGPRSize();
// If we don't have a jump target to a new block then we have to leave
// Set the RIP to the next instruction and leave
auto RelocatedNextRIP = _EntrypointOffset(IR::SizeToOpSize(GPRSize), NextRIP - Entry);
@ -245,7 +245,7 @@ public:
void SetDumpIR(bool DumpIR) { ShouldDump = DumpIR; }
bool ShouldDumpIR() const { return ShouldDump; }
void BeginFunction(uint64_t RIP, fextl::vector<FEXCore::Frontend::Decoder::DecodedBlocks> const *Blocks, uint32_t NumInstructions, bool Is64BitMode);
void BeginFunction(uint64_t RIP, fextl::vector<FEXCore::Frontend::Decoder::DecodedBlocks> const *Blocks, uint32_t NumInstructions);
void Finalize();
// Dispatch builder functions
@ -923,8 +923,6 @@ public:
}
}
uint8_t GetGPRSize() const { return Is64BitMode ? 8 : 4; }
protected:
void SaveNZCV(IROps Op = OP_DUMMY) override {
/* Some opcodes are conservatively marked as clobbering flags, but in fact
@ -1367,9 +1365,9 @@ private:
if (IsNZCV(BitOffset)) {
InsertNZCV(BitOffset, Value, ValueOffset, MustMask);
} else if (BitOffset == FEXCore::X86State::RFLAG_PF_RAW_LOC) {
_StoreRegister(Value, false, offsetof(FEXCore::Core::CPUState, pf_raw), GPRClass, GPRFixedClass, GetGPRSize());
_StoreRegister(Value, false, offsetof(FEXCore::Core::CPUState, pf_raw), GPRClass, GPRFixedClass, CTX->GetGPRSize());
} else if (BitOffset == FEXCore::X86State::RFLAG_AF_RAW_LOC) {
_StoreRegister(Value, false, offsetof(FEXCore::Core::CPUState, af_raw), GPRClass, GPRFixedClass, GetGPRSize());
_StoreRegister(Value, false, offsetof(FEXCore::Core::CPUState, af_raw), GPRClass, GPRFixedClass, CTX->GetGPRSize());
} else {
if (ValueOffset || MustMask)
Value = _Bfe(OpSize::i32Bit, 1, ValueOffset, Value);
@ -1423,9 +1421,9 @@ private:
_Constant(1), _Constant(0));
}
} else if (BitOffset == FEXCore::X86State::RFLAG_PF_RAW_LOC) {
return _LoadRegister(false, offsetof(FEXCore::Core::CPUState, pf_raw), GPRClass, GPRFixedClass, GetGPRSize());
return _LoadRegister(false, offsetof(FEXCore::Core::CPUState, pf_raw), GPRClass, GPRFixedClass, CTX->GetGPRSize());
} else if (BitOffset == FEXCore::X86State::RFLAG_AF_RAW_LOC) {
return _LoadRegister(false, offsetof(FEXCore::Core::CPUState, af_raw), GPRClass, GPRFixedClass, GetGPRSize());
return _LoadRegister(false, offsetof(FEXCore::Core::CPUState, af_raw), GPRClass, GPRFixedClass, CTX->GetGPRSize());
} else {
return _LoadFlag(BitOffset);
}
@ -2160,7 +2158,6 @@ private:
bool Multiblock{};
uint64_t Entry;
bool Is64BitMode{};
OrderedNode* _StoreMemAutoTSO(FEXCore::IR::RegisterClassType Class, uint8_t Size, OrderedNode *Addr, OrderedNode *Value, uint8_t Align = 1) {
if (CTX->IsAtomicTSOEnabled())

View File

@ -698,7 +698,7 @@ OrderedNode* OpDispatchBuilder::InsertCVTGPR_To_FPRImpl(OpcodeArgs,
if (Src2Op.IsGPR()) {
// If the source is a GPR then convert directly from the GPR.
auto Src2 = LoadSource_WithOpSize(GPRClass, Op, Src2Op, GetGPRSize(), Op->Flags);
auto Src2 = LoadSource_WithOpSize(GPRClass, Op, Src2Op, CTX->GetGPRSize(), Op->Flags);
return _VSToFGPRInsert(IR::SizeToOpSize(DstSize), DstElementSize, SrcSize, Src1, Src2, ZeroUpperBits);
}
else if (SrcSize != DstElementSize) {
@ -1060,7 +1060,7 @@ void OpDispatchBuilder::MOVMSKOp(OpcodeArgs) {
GPR = _Bfi(OpSize::i64Bit, 32, 31, GPR, GPR);
// Shift right to only get the two sign bits we care about.
GPR = _Lshr(OpSize::i64Bit, GPR, _Constant(62));
StoreResult_WithOpSize(GPRClass, Op, Op->Dest, GPR, GetGPRSize(), -1);
StoreResult_WithOpSize(GPRClass, Op, Op->Dest, GPR, CTX->GetGPRSize(), -1);
}
else if (Size == 16 && ElementSize == 4) {
// Shift all the sign bits to the bottom of their respective elements.
@ -1073,7 +1073,7 @@ void OpDispatchBuilder::MOVMSKOp(OpcodeArgs) {
Src = _VAddV(Size, 4, Src);
// Extract to a GPR.
OrderedNode *GPR = _VExtractToGPR(Size, 4, Src, 0);
StoreResult_WithOpSize(GPRClass, Op, Op->Dest, GPR, GetGPRSize(), -1);
StoreResult_WithOpSize(GPRClass, Op, Op->Dest, GPR, CTX->GetGPRSize(), -1);
}
else {
OrderedNode *CurrentVal = _Constant(0);
@ -1759,7 +1759,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], GetGPRSize(), Op->Flags,
OrderedNode *Address = LoadSource_WithOpSize(GPRClass, Op, Op->Src[0], CTX->GetGPRSize(), Op->Flags,
{.LoadData = false});
Address = AppendSegmentOffset(Address, Op->Flags);
@ -1795,7 +1795,7 @@ OrderedNode* OpDispatchBuilder::PINSROpImpl(OpcodeArgs, size_t ElementSize,
if (Src2Op.IsGPR()) {
// If the source is a GPR then convert directly from the GPR.
auto Src2 = LoadSource_WithOpSize(GPRClass, Op, Src2Op, GetGPRSize(), Op->Flags);
auto Src2 = LoadSource_WithOpSize(GPRClass, Op, Src2Op, CTX->GetGPRSize(), Op->Flags);
return _VInsGPR(Size, ElementSize, Index, Src1, Src2);
}
@ -1924,7 +1924,7 @@ void OpDispatchBuilder::PExtrOp(OpcodeArgs) {
Index &= NumElements - 1;
if (Op->Dest.IsGPR()) {
const uint8_t GPRSize = GetGPRSize();
const uint8_t GPRSize = CTX->GetGPRSize();
// Extract already zero extends the result.
OrderedNode *Result = _VExtractToGPR(16, OverridenElementSize, Src, Index);
StoreResult_WithOpSize(GPRClass, Op, Op->Dest, Result, GPRSize, -1);
@ -2477,7 +2477,7 @@ OrderedNode* OpDispatchBuilder::CVTGPR_To_FPRImpl(OpcodeArgs, size_t DstElementS
OrderedNode *Converted{};
if (Src2Op.IsGPR()) {
// If the source is a GPR then convert directly from the GPR.
auto Src2 = LoadSource_WithOpSize(GPRClass, Op, Src2Op, GetGPRSize(), Op->Flags);
auto Src2 = LoadSource_WithOpSize(GPRClass, Op, Src2Op, CTX->GetGPRSize(), Op->Flags);
Converted = _Float_FromGPR_S(DstElementSize, SrcSize, Src2);
}
else if (SrcSize != DstElementSize) {
@ -2826,7 +2826,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, GetGPRSize(), Op->Flags,
OrderedNode *BaseAddr = LoadSource_WithOpSize(GPRClass, Op, Data, CTX->GetGPRSize(), Op->Flags,
{.LoadData = false});
return AppendSegmentOffset(BaseAddr, Op->Flags);
};
@ -2877,7 +2877,7 @@ void OpDispatchBuilder::MOVBetweenGPR_FPR(OpcodeArgs) {
Op->Dest.Data.GPR.GPR >= FEXCore::X86State::REG_XMM_0) {
if (Op->Src[0].IsGPR()) {
// Loading from GPR and moving to Vector.
OrderedNode *Src = LoadSource_WithOpSize(FPRClass, Op, Op->Src[0], GetGPRSize(), Op->Flags);
OrderedNode *Src = LoadSource_WithOpSize(FPRClass, Op, Op->Src[0], CTX->GetGPRSize(), Op->Flags);
// zext to 128bit
auto Converted = _VCastFromGPR(16, GetSrcSize(Op), Src);
StoreResult(FPRClass, Op, Op->Dest, Converted, -1);
@ -3011,7 +3011,7 @@ void OpDispatchBuilder::XSaveOpImpl(OpcodeArgs) {
// for features that are in the lower 32 bits, so EAX only is sufficient.
OrderedNode *Mask = LoadGPRRegister(X86State::REG_RAX);
OrderedNode *Base = XSaveBase();
const auto OpSize = IR::SizeToOpSize(GetGPRSize());
const auto OpSize = IR::SizeToOpSize(CTX->GetGPRSize());
const auto StoreIfFlagSet = [&](uint32_t BitIndex, auto fn, uint32_t FieldSize = 1){
OrderedNode *BitFlag = _Bfe(OpSize, FieldSize, BitIndex, Mask);
@ -3065,7 +3065,7 @@ void OpDispatchBuilder::XSaveOpImpl(OpcodeArgs) {
}
void OpDispatchBuilder::SaveX87State(OpcodeArgs, OrderedNode *MemBase) {
const auto OpSize = IR::SizeToOpSize(GetGPRSize());
const auto OpSize = IR::SizeToOpSize(CTX->GetGPRSize());
// Saves 512bytes to the memory location provided
// Header changes depending on if REX.W is set or not
if (Op->Flags & X86Tables::DecodeFlags::FLAG_REX_WIDENING) {
@ -3151,8 +3151,8 @@ void OpDispatchBuilder::SaveX87State(OpcodeArgs, OrderedNode *MemBase) {
}
void OpDispatchBuilder::SaveSSEState(OrderedNode *MemBase) {
const auto OpSize = IR::SizeToOpSize(GetGPRSize());
const auto NumRegs = Is64BitMode ? 16U : 8U;
const auto OpSize = IR::SizeToOpSize(CTX->GetGPRSize());
const auto NumRegs = CTX->Config.Is64BitMode ? 16U : 8U;
for (uint32_t i = 0; i < NumRegs; ++i) {
OrderedNode *XMMReg = LoadXMMRegister(i);
@ -3163,7 +3163,7 @@ void OpDispatchBuilder::SaveSSEState(OrderedNode *MemBase) {
}
void OpDispatchBuilder::SaveMXCSRState(OrderedNode *MemBase) {
const auto OpSize = IR::SizeToOpSize(GetGPRSize());
const auto OpSize = IR::SizeToOpSize(CTX->GetGPRSize());
OrderedNode *MXCSR = GetMXCSR();
OrderedNode *MXCSRLocation = _Add(OpSize, MemBase, _Constant(24));
@ -3175,8 +3175,8 @@ void OpDispatchBuilder::SaveMXCSRState(OrderedNode *MemBase) {
}
void OpDispatchBuilder::SaveAVXState(OrderedNode *MemBase) {
const auto OpSize = IR::SizeToOpSize(GetGPRSize());
const auto NumRegs = Is64BitMode ? 16U : 8U;
const auto OpSize = IR::SizeToOpSize(CTX->GetGPRSize());
const auto NumRegs = CTX->Config.Is64BitMode ? 16U : 8U;
for (uint32_t i = 0; i < NumRegs; ++i) {
OrderedNode *Upper = _VDupElement(32, 16, LoadXMMRegister(i), 1);
@ -3194,7 +3194,7 @@ OrderedNode *OpDispatchBuilder::GetMXCSR() {
}
void OpDispatchBuilder::FXRStoreOp(OpcodeArgs) {
const auto OpSize = IR::SizeToOpSize(GetGPRSize());
const auto OpSize = IR::SizeToOpSize(CTX->GetGPRSize());
OrderedNode *Mem = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags, {.LoadData = false});
Mem = AppendSegmentOffset(Mem, Op->Flags);
@ -3208,7 +3208,7 @@ void OpDispatchBuilder::FXRStoreOp(OpcodeArgs) {
}
void OpDispatchBuilder::XRstorOpImpl(OpcodeArgs) {
const auto OpSize = IR::SizeToOpSize(GetGPRSize());
const auto OpSize = IR::SizeToOpSize(CTX->GetGPRSize());
const auto XSaveBase = [this, Op] {
OrderedNode *Mem = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, {.LoadData = false});
@ -3283,7 +3283,7 @@ void OpDispatchBuilder::XRstorOpImpl(OpcodeArgs) {
}
void OpDispatchBuilder::RestoreX87State(OrderedNode *MemBase) {
const auto OpSize = IR::SizeToOpSize(GetGPRSize());
const auto OpSize = IR::SizeToOpSize(CTX->GetGPRSize());
auto NewFCW = _LoadMem(GPRClass, 2, MemBase, 2);
_StoreContext(2, GPRClass, NewFCW, offsetof(FEXCore::Core::CPUState, FCW));
@ -3309,8 +3309,8 @@ void OpDispatchBuilder::RestoreX87State(OrderedNode *MemBase) {
}
void OpDispatchBuilder::RestoreSSEState(OrderedNode *MemBase) {
const auto OpSize = IR::SizeToOpSize(GetGPRSize());
const auto NumRegs = Is64BitMode ? 16U : 8U;
const auto OpSize = IR::SizeToOpSize(CTX->GetGPRSize());
const auto NumRegs = CTX->Config.Is64BitMode ? 16U : 8U;
for (uint32_t i = 0; i < NumRegs; ++i) {
OrderedNode *MemLocation = _Add(OpSize, MemBase, _Constant(i * 16 + 160));
@ -3326,8 +3326,8 @@ void OpDispatchBuilder::RestoreMXCSRState(OrderedNode *MXCSR) {
}
void OpDispatchBuilder::RestoreAVXState(OrderedNode *MemBase) {
const auto OpSize = IR::SizeToOpSize(GetGPRSize());
const auto NumRegs = Is64BitMode ? 16U : 8U;
const auto OpSize = IR::SizeToOpSize(CTX->GetGPRSize());
const auto NumRegs = CTX->Config.Is64BitMode ? 16U : 8U;
for (uint32_t i = 0; i < NumRegs; ++i) {
OrderedNode *XMMReg = LoadXMMRegister(i);
@ -3352,7 +3352,7 @@ void OpDispatchBuilder::DefaultX87State(OpcodeArgs) {
}
void OpDispatchBuilder::DefaultSSEState() {
const auto NumRegs = Is64BitMode ? 16U : 8U;
const auto NumRegs = CTX->Config.Is64BitMode ? 16U : 8U;
OrderedNode *ZeroVector = LoadAndCacheNamedVectorConstant(Core::CPUState::XMM_SSE_REG_SIZE, FEXCore::IR::NamedVectorConstant::NAMED_VECTOR_ZERO);
for (uint32_t i = 0; i < NumRegs; ++i) {
@ -3361,7 +3361,7 @@ void OpDispatchBuilder::DefaultSSEState() {
}
void OpDispatchBuilder::DefaultAVXState() {
const auto NumRegs = Is64BitMode ? 16U : 8U;
const auto NumRegs = CTX->Config.Is64BitMode ? 16U : 8U;
for (uint32_t i = 0; i < NumRegs; i++) {
OrderedNode* Reg = LoadXMMRegister(i);
@ -5346,7 +5346,7 @@ void OpDispatchBuilder::VPBLENDWOp(OpcodeArgs) {
void OpDispatchBuilder::VZEROOp(OpcodeArgs) {
const auto DstSize = GetDstSize(Op);
const auto IsVZEROALL = DstSize == Core::CPUState::XMM_AVX_REG_SIZE;
const auto NumRegs = Is64BitMode ? 16U : 8U;
const auto NumRegs = CTX->Config.Is64BitMode ? 16U : 8U;
if (IsVZEROALL) {
// NOTE: Despite the name being VZEROALL, this will still only ever
@ -5550,7 +5550,7 @@ void OpDispatchBuilder::PCMPXSTRXOpImpl(OpcodeArgs, bool IsExplicit, bool IsMask
OrderedNode *Result = _Select(IR::COND_EQ, ResultNoFlags, ZeroConst,
IfZero, IfNotZero);
const uint8_t GPRSize = GetGPRSize();
const uint8_t GPRSize = CTX->GetGPRSize();
if (GPRSize == 8) {
// If being stored to an 8-byte register, zero extend the 4-byte result.
Result = _Bfe(OpSize::i64Bit, 32, 0, Result);

View File

@ -240,7 +240,7 @@ namespace FEXCore {
IRHeader.first->Blocks = emit->WrapNode(Block);
emit->SetCurrentCodeBlock(Block);
const uint8_t GPRSize = CTX->Config.Is64BitMode ? 8 : 4;
const uint8_t GPRSize = CTX->GetGPRSize();
if (GPRSize == 8) {
emit->_StoreRegister(emit->_Constant(Entrypoint), false, offsetof(Core::CPUState, gregs[X86State::REG_R11]), IR::GPRClass, IR::GPRFixedClass, GPRSize);

View File

@ -107,48 +107,9 @@ namespace FEXCore::Core {
uint64_t mm[8][2]{};
// 32bit x86 state
struct gdt_segment {
uint16_t Limit0;
uint16_t Base0;
uint16_t Base1 : 8;
uint16_t Type : 4;
uint16_t S : 1;
uint16_t DPL : 2;
uint16_t P : 1;
uint16_t Limit1 : 4;
uint16_t AVL : 1;
uint16_t L : 1;
uint16_t D : 1;
uint16_t G : 1;
uint16_t Base2 : 8;
struct {
uint32_t base;
} gdt[32]{};
static uint32_t CalculateGDTBase(gdt_segment GDT) {
uint32_t Base{};
Base |= GDT.Base2 << 24;
Base |= GDT.Base1 << 16;
Base |= GDT.Base0;
return Base;
}
static uint32_t CalculateGDTLimit(gdt_segment GDT) {
uint32_t Limit{};
Limit |= GDT.Limit1 << 16;
Limit |= GDT.Limit0;
return Limit;
}
static void SetGDTBase(gdt_segment *GDT, uint32_t Base) {
GDT->Base0 = Base;
GDT->Base1 = Base >> 16;
GDT->Base2 = Base >> 24;
}
static void SetGDTLimit(gdt_segment *GDT, uint32_t Limit) {
GDT->Limit0 = Limit;
GDT->Limit1 = Limit >> 16;
}
uint16_t FCW { 0x37F };
uint8_t AbridgedFTW{};
@ -161,7 +122,6 @@ namespace FEXCore::Core {
static constexpr size_t FLAG_SIZE = sizeof(flags[0]);
static constexpr size_t GDT_SIZE = sizeof(gdt[0]);
static_assert(GDT_SIZE == sizeof(uint64_t), "Segments required to be 8-byte in size.");
static constexpr size_t GPR_REG_SIZE = sizeof(gregs[0]);
static constexpr size_t XMM_AVX_REG_SIZE = sizeof(xmm.avx.data[0]);
static constexpr size_t XMM_SSE_REG_SIZE = XMM_AVX_REG_SIZE / 2;

View File

@ -512,12 +512,12 @@ namespace FEX::HLE {
Frame->State.gs_idx = guest_uctx->sc.gs;
Frame->State.ss_idx = guest_uctx->sc.ss;
Frame->State.cs_cached = Frame->State.CalculateGDTBase(Frame->State.gdt[Frame->State.cs_idx >> 3]);
Frame->State.ds_cached = Frame->State.CalculateGDTBase(Frame->State.gdt[Frame->State.ds_idx >> 3]);
Frame->State.es_cached = Frame->State.CalculateGDTBase(Frame->State.gdt[Frame->State.es_idx >> 3]);
Frame->State.fs_cached = Frame->State.CalculateGDTBase(Frame->State.gdt[Frame->State.fs_idx >> 3]);
Frame->State.gs_cached = Frame->State.CalculateGDTBase(Frame->State.gdt[Frame->State.gs_idx >> 3]);
Frame->State.ss_cached = Frame->State.CalculateGDTBase(Frame->State.gdt[Frame->State.ss_idx >> 3]);
Frame->State.cs_cached = Frame->State.gdt[Frame->State.cs_idx >> 3].base;
Frame->State.ds_cached = Frame->State.gdt[Frame->State.ds_idx >> 3].base;
Frame->State.es_cached = Frame->State.gdt[Frame->State.es_idx >> 3].base;
Frame->State.fs_cached = Frame->State.gdt[Frame->State.fs_idx >> 3].base;
Frame->State.gs_cached = Frame->State.gdt[Frame->State.gs_idx >> 3].base;
Frame->State.ss_cached = Frame->State.gdt[Frame->State.ss_idx >> 3].base;
#define COPY_REG(x, y) \
Frame->State.gregs[FEXCore::X86State::REG_##x] = guest_uctx->sc.y;
@ -592,12 +592,12 @@ namespace FEX::HLE {
Frame->State.gs_idx = guest_uctx->uc.uc_mcontext.gregs[FEXCore::x86::FEX_REG_GS];
Frame->State.ss_idx = guest_uctx->uc.uc_mcontext.gregs[FEXCore::x86::FEX_REG_SS];
Frame->State.cs_cached = Frame->State.CalculateGDTBase(Frame->State.gdt[Frame->State.cs_idx >> 3]);
Frame->State.ds_cached = Frame->State.CalculateGDTBase(Frame->State.gdt[Frame->State.ds_idx >> 3]);
Frame->State.es_cached = Frame->State.CalculateGDTBase(Frame->State.gdt[Frame->State.es_idx >> 3]);
Frame->State.fs_cached = Frame->State.CalculateGDTBase(Frame->State.gdt[Frame->State.fs_idx >> 3]);
Frame->State.gs_cached = Frame->State.CalculateGDTBase(Frame->State.gdt[Frame->State.gs_idx >> 3]);
Frame->State.ss_cached = Frame->State.CalculateGDTBase(Frame->State.gdt[Frame->State.ss_idx >> 3]);
Frame->State.cs_cached = Frame->State.gdt[Frame->State.cs_idx >> 3].base;
Frame->State.ds_cached = Frame->State.gdt[Frame->State.ds_idx >> 3].base;
Frame->State.es_cached = Frame->State.gdt[Frame->State.es_idx >> 3].base;
Frame->State.fs_cached = Frame->State.gdt[Frame->State.fs_idx >> 3].base;
Frame->State.gs_cached = Frame->State.gdt[Frame->State.gs_idx >> 3].base;
Frame->State.ss_cached = Frame->State.gdt[Frame->State.ss_idx >> 3].base;
#define COPY_REG(x) \
Frame->State.gregs[FEXCore::X86State::REG_##x] = guest_uctx->uc.uc_mcontext.gregs[FEXCore::x86::FEX_REG_##x];

View File

@ -53,8 +53,8 @@ namespace FEX::HLE::x32 {
if (u_info->entry_number == -1) {
for (uint32_t i = TLS_NextEntry; i < TLS_MaxEntry; ++i) {
auto GDT = &Frame->State.gdt[i];
if (Frame->State.CalculateGDTLimit(*GDT) == 0) {
// If the limit is zero then it isn't present in our setup.
if (GDT->base == 0) {
// If the base is zero then it isn't present with our setup
u_info->entry_number = i;
break;
}
@ -68,29 +68,29 @@ namespace FEX::HLE::x32 {
// Now we need to update the thread's GDT to handle this change
auto GDT = &Frame->State.gdt[u_info->entry_number];
Frame->State.SetGDTBase(GDT, u_info->base_addr);
GDT->base = u_info->base_addr;
// With the segment register optimization we need to check all of the segment registers and update.
const auto GetEntry = [](auto value) {
return value >> 3;
};
if (GetEntry(Frame->State.cs_idx) == u_info->entry_number) {
Frame->State.cs_cached = Frame->State.CalculateGDTBase(*GDT);
Frame->State.cs_cached = GDT->base;
}
if (GetEntry(Frame->State.ds_idx) == u_info->entry_number) {
Frame->State.ds_cached = Frame->State.CalculateGDTBase(*GDT);
Frame->State.ds_cached = GDT->base;
}
if (GetEntry(Frame->State.es_idx) == u_info->entry_number) {
Frame->State.es_cached = Frame->State.CalculateGDTBase(*GDT);
Frame->State.es_cached = GDT->base;
}
if (GetEntry(Frame->State.fs_idx) == u_info->entry_number) {
Frame->State.fs_cached = Frame->State.CalculateGDTBase(*GDT);
Frame->State.fs_cached = GDT->base;
}
if (GetEntry(Frame->State.gs_idx) == u_info->entry_number) {
Frame->State.gs_cached = Frame->State.CalculateGDTBase(*GDT);
Frame->State.gs_cached = GDT->base;
}
if (GetEntry(Frame->State.ss_idx) == u_info->entry_number) {
Frame->State.ss_cached = Frame->State.CalculateGDTBase(*GDT);
Frame->State.ss_cached = GDT->base;
}
return 0;
}
@ -150,7 +150,8 @@ namespace FEX::HLE::x32 {
memset(u_info, 0, sizeof(*u_info));
u_info->base_addr = Frame->State.CalculateGDTBase(*GDT);
// FEX only stores base instead of the full GDT
u_info->base_addr = GDT->base;
// Fill the rest of the structure with expected data (even if wrong at the moment)
if (u_info->base_addr) {

View File

@ -146,8 +146,7 @@ namespace Context {
State.gs_idx = Context->SegGs & 0xffff;
// The TEB is the only populated GDT entry by default
State.SetGDTBase(&State.gdt[(Context->SegFs & 0xffff) >> 3], WowTEB);
State.SetGDTLimit(&State.gdt[(Context->SegFs & 0xffff) >> 3], 0xF'FFFFU);
State.gdt[(Context->SegFs & 0xffff) >> 3].base = WowTEB;
State.fs_cached = WowTEB;
State.es_cached = 0;
State.cs_cached = 0;

View File

@ -55,7 +55,7 @@
"0x66 0x0f 0x3a 0xdf"
],
"ExpectedArm64ASM": [
"ldr q2, [x28, #2208]",
"ldr q2, [x28, #2080]",
"movi v3.2d, #0x0",
"mov v16.16b, v17.16b",
"unimplemented (Unimplemented)",
@ -68,7 +68,7 @@
"0x66 0x0f 0x3a 0xdf"
],
"ExpectedArm64ASM": [
"ldr q2, [x28, #2208]",
"ldr q2, [x28, #2080]",
"movi v3.2d, #0x0",
"mov v16.16b, v17.16b",
"unimplemented (Unimplemented)",

View File

@ -199,10 +199,10 @@
"ldr q19, [x11, #272]",
"ldr q24, [x11]",
"ldr q23, [x11, #16]",
"ldr x0, [x28, #1816]",
"ldr x0, [x28, #1688]",
"ldr q2, [x0, #2832]",
"tbl v16.16b, {v18.16b}, v2.16b",
"ldr x0, [x28, #1816]",
"ldr x0, [x28, #1688]",
"ldr q3, [x0, #432]",
"tbl v18.16b, {v19.16b}, v3.16b",
"ldr q22, [x11, #32]",
@ -346,7 +346,7 @@
"mov v4.s[1], w21",
"mov v20.16b, v4.16b",
"mov v20.s[0], w23",
"ldr x0, [x28, #1816]",
"ldr x0, [x28, #1688]",
"ldr q4, [x0, #224]",
"tbl v16.16b, {v16.16b}, v4.16b",
"mov w20, v20.s[3]",

View File

@ -1200,7 +1200,7 @@
"ExpectedInstructionCount": 58,
"Comment": "GROUP15 0x0F 0xAE /0",
"ExpectedArm64ASM": [
"ldrh w20, [x28, #1152]",
"ldrh w20, [x28, #1024]",
"strh w20, [x4]",
"mov w20, #0x0",
"ldrb w21, [x28, #747]",
@ -1214,7 +1214,7 @@
"orr x20, x20, x23, lsl #10",
"orr x20, x20, x24, lsl #14",
"strh w20, [x4, #2]",
"ldrb w20, [x28, #1154]",
"ldrb w20, [x28, #1026]",
"strb w20, [x4, #4]",
"ldr q2, [x28, #768]",
"str q2, [x4, #32]",
@ -1279,7 +1279,7 @@
"Comment": "GROUP15 0x0F 0xAE /1",
"ExpectedArm64ASM": [
"ldrh w20, [x4]",
"strh w20, [x28, #1152]",
"strh w20, [x28, #1024]",
"ldrh w20, [x4, #2]",
"ubfx w21, w20, #11, #3",
"strb w21, [x28, #747]",
@ -1292,7 +1292,7 @@
"strb w23, [x28, #746]",
"strb w20, [x28, #750]",
"ldrb w20, [x4, #4]",
"strb w20, [x28, #1154]",
"strb w20, [x28, #1026]",
"ldr q2, [x4, #32]",
"str q2, [x28, #768]",
"ldr q2, [x4, #48]",
@ -1417,7 +1417,7 @@
"ubfx x22, x20, #0, #1",
"cbnz x22, #+0x8",
"b #+0x84",
"ldrh w22, [x28, #1152]",
"ldrh w22, [x28, #1024]",
"strh w22, [x21]",
"mov w22, #0x0",
"ldrb w23, [x28, #747]",
@ -1431,7 +1431,7 @@
"orr x22, x22, x25, lsl #10",
"orr x22, x22, x30, lsl #14",
"strh w22, [x21, #2]",
"ldrb w22, [x28, #1154]",
"ldrb w22, [x28, #1026]",
"strb w22, [x21, #4]",
"ldr q2, [x28, #768]",
"str q2, [x21, #32]",
@ -1502,7 +1502,7 @@
"cbnz x22, #+0x8",
"b #+0x84",
"ldrh w22, [x20]",
"strh w22, [x28, #1152]",
"strh w22, [x28, #1024]",
"ldrh w22, [x20, #2]",
"ubfx w23, w22, #11, #3",
"strb w23, [x28, #747]",
@ -1515,7 +1515,7 @@
"strb w25, [x28, #746]",
"strb w22, [x28, #750]",
"ldrb w22, [x20, #4]",
"strb w22, [x28, #1154]",
"strb w22, [x28, #1026]",
"ldr q2, [x20, #32]",
"str q2, [x28, #768]",
"ldr q2, [x20, #48]",
@ -1535,13 +1535,13 @@
"b #+0x4c",
"mov w22, #0x0",
"mov w23, #0x37f",
"strh w23, [x28, #1152]",
"strh w23, [x28, #1024]",
"strb w22, [x28, #747]",
"strb w22, [x28, #744]",
"strb w22, [x28, #745]",
"strb w22, [x28, #746]",
"strb w22, [x28, #750]",
"strb w22, [x28, #1154]",
"strb w22, [x28, #1026]",
"movi v2.2d, #0x0",
"str q2, [x28, #768]",
"str q2, [x28, #784]",

View File

@ -42,8 +42,8 @@
"st1 {v24.2d, v25.2d, v26.2d, v27.2d}, [x3], #64",
"st1 {v28.2d, v29.2d, v30.2d, v31.2d}, [x3], #64",
"mov w1, w5",
"ldr x0, [x28, #1240]",
"ldr x2, [x28, #1256]",
"ldr x0, [x28, #1112]",
"ldr x2, [x28, #1128]",
"blr x2",
"ldr w4, [x28, #728]",
"msr nzcv, x4",
@ -85,7 +85,7 @@
"str w0, [x28, #728]",
"str x8, [x28, #40]",
"mov w0, #0x100",
"str x0, [x28, #1184]",
"str x0, [x28, #1056]",
"sub sp, sp, #0x10 (16)",
"mov w8, #0xa8",
"mov x0, sp",
@ -96,7 +96,7 @@
"ldr w8, [x28, #728]",
"msr nzcv, x8",
"ldr x8, [x28, #40]",
"str xzr, [x28, #1184]",
"str xzr, [x28, #1056]",
"orr x5, x0, x1, lsl #12"
]
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -624,7 +624,7 @@
"0x66 0x0f 0x38 0x41"
],
"ExpectedArm64ASM": [
"ldr q2, [x28, #2096]",
"ldr q2, [x28, #1968]",
"zip1 v3.8h, v2.8h, v17.8h",
"zip2 v2.8h, v2.8h, v17.8h",
"umin v2.4s, v3.4s, v2.4s",

View File

@ -315,7 +315,7 @@
"0x66 0x0f 0x3a 0x0c"
],
"ExpectedArm64ASM": [
"ldr q2, [x28, #2224]",
"ldr q2, [x28, #2096]",
"tbx v16.16b, {v17.16b}, v2.16b"
]
},
@ -325,7 +325,7 @@
"0x66 0x0f 0x3a 0x0c"
],
"ExpectedArm64ASM": [
"ldr q2, [x28, #2240]",
"ldr q2, [x28, #2112]",
"tbx v16.16b, {v17.16b}, v2.16b"
]
},
@ -344,7 +344,7 @@
"0x66 0x0f 0x3a 0x0c"
],
"ExpectedArm64ASM": [
"ldr q2, [x28, #2256]",
"ldr q2, [x28, #2128]",
"tbx v16.16b, {v17.16b}, v2.16b"
]
},
@ -364,7 +364,7 @@
"0x66 0x0f 0x3a 0x0c"
],
"ExpectedArm64ASM": [
"ldr q2, [x28, #2272]",
"ldr q2, [x28, #2144]",
"tbx v16.16b, {v17.16b}, v2.16b"
]
},
@ -383,7 +383,7 @@
"0x66 0x0f 0x3a 0x0c"
],
"ExpectedArm64ASM": [
"ldr q2, [x28, #2288]",
"ldr q2, [x28, #2160]",
"tbx v16.16b, {v17.16b}, v2.16b"
]
},
@ -393,7 +393,7 @@
"0x66 0x0f 0x3a 0x0c"
],
"ExpectedArm64ASM": [
"ldr q2, [x28, #2304]",
"ldr q2, [x28, #2176]",
"tbx v16.16b, {v17.16b}, v2.16b"
]
},
@ -462,7 +462,7 @@
"0x66 0x0f 0x3a 0x0e"
],
"ExpectedArm64ASM": [
"ldr x0, [x28, #1848]",
"ldr x0, [x28, #1720]",
"ldr q2, [x0, #3440]",
"tbx v16.16b, {v17.16b}, v2.16b"
]

View File

@ -2671,50 +2671,38 @@
"Comment": "0x8e"
},
"mov es, ax": {
"ExpectedInstructionCount": 10,
"ExpectedInstructionCount": 6,
"Comment": "0x8e",
"ExpectedArm64ASM": [
"uxth w20, w4",
"strh w20, [x28, #136]",
"ubfx w20, w20, #3, #13",
"add x0, x28, x20, lsl #3",
"ldr x20, [x0, #896]",
"lsr x21, x20, #32",
"and w22, w21, #0xff000000",
"orr w20, w22, w20, lsr #16",
"bfi w20, w21, #16, #8",
"add x0, x28, x20, lsl #2",
"ldr w20, [x0, #896]",
"str w20, [x28, #152]"
]
},
"mov ss, ax": {
"ExpectedInstructionCount": 10,
"ExpectedInstructionCount": 6,
"Comment": "0x8e",
"ExpectedArm64ASM": [
"uxth w20, w4",
"strh w20, [x28, #140]",
"ubfx w20, w20, #3, #13",
"add x0, x28, x20, lsl #3",
"ldr x20, [x0, #896]",
"lsr x21, x20, #32",
"and w22, w21, #0xff000000",
"orr w20, w22, w20, lsr #16",
"bfi w20, w21, #16, #8",
"add x0, x28, x20, lsl #2",
"ldr w20, [x0, #896]",
"str w20, [x28, #160]"
]
},
"mov ds, ax": {
"ExpectedInstructionCount": 10,
"ExpectedInstructionCount": 6,
"Comment": "0x8e",
"ExpectedArm64ASM": [
"uxth w20, w4",
"strh w20, [x28, #142]",
"ubfx w20, w20, #3, #13",
"add x0, x28, x20, lsl #3",
"ldr x20, [x0, #896]",
"lsr x21, x20, #32",
"and w22, w21, #0xff000000",
"orr w20, w22, w20, lsr #16",
"bfi w20, w21, #16, #8",
"add x0, x28, x20, lsl #2",
"ldr w20, [x0, #896]",
"str w20, [x28, #164]"
]
},

View File

@ -3052,7 +3052,7 @@
"mov x0, x6",
"mov x1, x20",
"mov x2, x7",
"ldr x3, [x28, #2352]",
"ldr x3, [x28, #2224]",
"str x30, [sp, #-16]!",
"blr x3",
"ldr x30, [sp], #16",
@ -3063,7 +3063,7 @@
"mov x0, x6",
"mov x1, x20",
"mov x2, x7",
"ldr x3, [x28, #2368]",
"ldr x3, [x28, #2240]",
"str x30, [sp, #-16]!",
"blr x3",
"ldr x30, [sp], #16",
@ -3124,7 +3124,7 @@
"mov x0, x6",
"mov x1, x20",
"mov x2, x7",
"ldr x3, [x28, #2360]",
"ldr x3, [x28, #2232]",
"str x30, [sp, #-16]!",
"blr x3",
"ldr x30, [sp], #16",
@ -3137,7 +3137,7 @@
"mov x0, x6",
"mov x1, x20",
"mov x2, x7",
"ldr x3, [x28, #2376]",
"ldr x3, [x28, #2248]",
"str x30, [sp, #-16]!",
"blr x3",
"ldr x30, [sp], #16",

View File

@ -19,19 +19,15 @@
]
},
"pop es": {
"ExpectedInstructionCount": 11,
"ExpectedInstructionCount": 7,
"Comment": "0x07",
"ExpectedArm64ASM": [
"ldr w20, [x8]",
"add x8, x8, #0x4 (4)",
"strh w20, [x28, #136]",
"ubfx w20, w20, #3, #13",
"add x0, x28, x20, lsl #3",
"ldr x20, [x0, #896]",
"lsr x21, x20, #32",
"and w22, w21, #0xff000000",
"orr w20, w22, w20, lsr #16",
"bfi w20, w21, #16, #8",
"add x0, x28, x20, lsl #2",
"ldr w20, [x0, #896]",
"str w20, [x28, #152]"
]
},
@ -52,19 +48,15 @@
]
},
"pop ss": {
"ExpectedInstructionCount": 11,
"ExpectedInstructionCount": 7,
"Comment": "0x17",
"ExpectedArm64ASM": [
"ldr w20, [x8]",
"add x8, x8, #0x4 (4)",
"strh w20, [x28, #140]",
"ubfx w20, w20, #3, #13",
"add x0, x28, x20, lsl #3",
"ldr x20, [x0, #896]",
"lsr x21, x20, #32",
"and w22, w21, #0xff000000",
"orr w20, w22, w20, lsr #16",
"bfi w20, w21, #16, #8",
"add x0, x28, x20, lsl #2",
"ldr w20, [x0, #896]",
"str w20, [x28, #160]"
]
},
@ -77,19 +69,15 @@
]
},
"pop ds": {
"ExpectedInstructionCount": 11,
"ExpectedInstructionCount": 7,
"Comment": "0x1f",
"ExpectedArm64ASM": [
"ldr w20, [x8]",
"add x8, x8, #0x4 (4)",
"strh w20, [x28, #142]",
"ubfx w20, w20, #3, #13",
"add x0, x28, x20, lsl #3",
"ldr x20, [x0, #896]",
"lsr x21, x20, #32",
"and w22, w21, #0xff000000",
"orr w20, w22, w20, lsr #16",
"bfi w20, w21, #16, #8",
"add x0, x28, x20, lsl #2",
"ldr w20, [x0, #896]",
"str w20, [x28, #164]"
]
},

View File

@ -23,7 +23,7 @@
"Comment": "0x0f 0x0b",
"ExpectedArm64ASM": [
"mov w20, #0x0",
"strb w20, [x28, #1154]"
"strb w20, [x28, #1026]"
]
},
"movups xmm0, xmm0": {
@ -646,7 +646,7 @@
"Comment": "0x0f 0x50",
"ExpectedArm64ASM": [
"ushr v2.4s, v16.4s, #31",
"ldr q3, [x28, #2192]",
"ldr q3, [x28, #2064]",
"ushl v2.4s, v2.4s, v3.4s",
"addv s2, v2.4s",
"mov w4, v2.s[0]"
@ -657,7 +657,7 @@
"Comment": "0x0f 0x50",
"ExpectedArm64ASM": [
"ushr v2.4s, v16.4s, #31",
"ldr q3, [x28, #2192]",
"ldr q3, [x28, #2064]",
"ushl v2.4s, v2.4s, v3.4s",
"addv s2, v2.4s",
"mov w4, v2.s[0]"
@ -1041,7 +1041,7 @@
"Comment": "0x0f 0x70",
"ExpectedArm64ASM": [
"ldr d2, [x28, #784]",
"ldr x0, [x28, #1800]",
"ldr x0, [x28, #1672]",
"ldr d3, [x0, #16]",
"tbl v2.8b, {v2.16b}, v3.8b",
"str d2, [x28, #768]"
@ -1052,7 +1052,7 @@
"Comment": "0x0f 0x70",
"ExpectedArm64ASM": [
"ldr d2, [x4]",
"ldr x0, [x28, #1800]",
"ldr x0, [x28, #1672]",
"ldr d3, [x0, #16]",
"tbl v2.8b, {v2.16b}, v3.8b",
"str d2, [x28, #768]"
@ -1111,7 +1111,7 @@
"Comment": "0x0f 0x77",
"ExpectedArm64ASM": [
"mov w20, #0x0",
"strb w20, [x28, #1154]"
"strb w20, [x28, #1026]"
]
},
"movd eax, mm0": {
@ -1297,19 +1297,15 @@
]
},
"pop fs": {
"ExpectedInstructionCount": 11,
"ExpectedInstructionCount": 7,
"Comment": "0x0f 0xa1",
"ExpectedArm64ASM": [
"ldr x20, [x8]",
"add x8, x8, #0x8 (8)",
"strh w20, [x28, #146]",
"ubfx w20, w20, #3, #13",
"add x0, x28, x20, lsl #3",
"ldr x20, [x0, #896]",
"lsr x21, x20, #32",
"and w22, w21, #0xff000000",
"orr w20, w22, w20, lsr #16",
"bfi w20, w21, #16, #8",
"add x0, x28, x20, lsl #2",
"ldr w20, [x0, #896]",
"str w20, [x28, #176]"
]
},
@ -1696,19 +1692,15 @@
]
},
"pop gs": {
"ExpectedInstructionCount": 11,
"ExpectedInstructionCount": 7,
"Comment": "0x0f 0xa9",
"ExpectedArm64ASM": [
"ldr x20, [x8]",
"add x8, x8, #0x8 (8)",
"strh w20, [x28, #144]",
"ubfx w20, w20, #3, #13",
"add x0, x28, x20, lsl #3",
"ldr x20, [x0, #896]",
"lsr x21, x20, #32",
"and w22, w21, #0xff000000",
"orr w20, w22, w20, lsr #16",
"bfi w20, w21, #16, #8",
"add x0, x28, x20, lsl #2",
"ldr w20, [x0, #896]",
"str w20, [x28, #168]"
]
},
@ -3386,7 +3378,7 @@
"ExpectedInstructionCount": 3,
"Comment": "0x0f 0xc6",
"ExpectedArm64ASM": [
"ldr x0, [x28, #1824]",
"ldr x0, [x28, #1696]",
"ldr q2, [x0, #16]",
"tbl v16.16b, {v16.16b, v17.16b}, v2.16b"
]
@ -3395,7 +3387,7 @@
"ExpectedInstructionCount": 5,
"Comment": "0x0f 0xc6",
"ExpectedArm64ASM": [
"ldr x0, [x28, #1824]",
"ldr x0, [x28, #1696]",
"ldr q2, [x0, #16]",
"mov v0.16b, v17.16b",
"mov v1.16b, v16.16b",
@ -3407,7 +3399,7 @@
"Comment": "0x0f 0xc6",
"ExpectedArm64ASM": [
"ldr q2, [x4]",
"ldr x0, [x28, #1824]",
"ldr x0, [x28, #1696]",
"ldr q3, [x0, #16]",
"mov v0.16b, v16.16b",
"mov v1.16b, v2.16b",

View File

@ -1332,7 +1332,7 @@
"ExpectedInstructionCount": 58,
"Comment": "GROUP15 0x0F 0xAE /0",
"ExpectedArm64ASM": [
"ldrh w20, [x28, #1152]",
"ldrh w20, [x28, #1024]",
"strh w20, [x4]",
"mov w20, #0x0",
"ldrb w21, [x28, #747]",
@ -1346,7 +1346,7 @@
"orr x20, x20, x23, lsl #10",
"orr x20, x20, x24, lsl #14",
"strh w20, [x4, #2]",
"ldrb w20, [x28, #1154]",
"ldrb w20, [x28, #1026]",
"strb w20, [x4, #4]",
"ldr q2, [x28, #768]",
"str q2, [x4, #32]",
@ -1411,7 +1411,7 @@
"Comment": "GROUP15 0x0F 0xAE /1",
"ExpectedArm64ASM": [
"ldrh w20, [x4]",
"strh w20, [x28, #1152]",
"strh w20, [x28, #1024]",
"ldrh w20, [x4, #2]",
"ubfx w21, w20, #11, #3",
"strb w21, [x28, #747]",
@ -1424,7 +1424,7 @@
"strb w23, [x28, #746]",
"strb w20, [x28, #750]",
"ldrb w20, [x4, #4]",
"strb w20, [x28, #1154]",
"strb w20, [x28, #1026]",
"ldr q2, [x4, #32]",
"str q2, [x28, #768]",
"ldr q2, [x4, #48]",
@ -1549,7 +1549,7 @@
"ubfx x22, x20, #0, #1",
"cbnz x22, #+0x8",
"b #+0x84",
"ldrh w22, [x28, #1152]",
"ldrh w22, [x28, #1024]",
"strh w22, [x21]",
"mov w22, #0x0",
"ldrb w23, [x28, #747]",
@ -1563,7 +1563,7 @@
"orr x22, x22, x25, lsl #10",
"orr x22, x22, x30, lsl #14",
"strh w22, [x21, #2]",
"ldrb w22, [x28, #1154]",
"ldrb w22, [x28, #1026]",
"strb w22, [x21, #4]",
"ldr q2, [x28, #768]",
"str q2, [x21, #32]",
@ -1634,7 +1634,7 @@
"cbnz x22, #+0x8",
"b #+0x84",
"ldrh w22, [x20]",
"strh w22, [x28, #1152]",
"strh w22, [x28, #1024]",
"ldrh w22, [x20, #2]",
"ubfx w23, w22, #11, #3",
"strb w23, [x28, #747]",
@ -1647,7 +1647,7 @@
"strb w25, [x28, #746]",
"strb w22, [x28, #750]",
"ldrb w22, [x20, #4]",
"strb w22, [x28, #1154]",
"strb w22, [x28, #1026]",
"ldr q2, [x20, #32]",
"str q2, [x28, #768]",
"ldr q2, [x20, #48]",
@ -1667,13 +1667,13 @@
"b #+0x4c",
"mov w22, #0x0",
"mov w23, #0x37f",
"strh w23, [x28, #1152]",
"strh w23, [x28, #1024]",
"strb w22, [x28, #747]",
"strb w22, [x28, #744]",
"strb w22, [x28, #745]",
"strb w22, [x28, #746]",
"strb w22, [x28, #750]",
"strb w22, [x28, #1154]",
"strb w22, [x28, #1026]",
"movi v2.2d, #0x0",
"str q2, [x28, #768]",
"str q2, [x28, #784]",

View File

@ -42,8 +42,8 @@
"st1 {v24.2d, v25.2d, v26.2d, v27.2d}, [x3], #64",
"st1 {v28.2d, v29.2d, v30.2d, v31.2d}, [x3], #64",
"mov w1, w5",
"ldr x0, [x28, #1240]",
"ldr x2, [x28, #1256]",
"ldr x0, [x28, #1112]",
"ldr x2, [x28, #1128]",
"blr x2",
"ldr w4, [x28, #728]",
"msr nzcv, x4",
@ -85,7 +85,7 @@
"str w0, [x28, #728]",
"str x8, [x28, #40]",
"mov w0, #0x100",
"str x0, [x28, #1184]",
"str x0, [x28, #1056]",
"sub sp, sp, #0x10 (16)",
"mov w8, #0xa8",
"mov x0, sp",
@ -96,7 +96,7 @@
"ldr w8, [x28, #728]",
"msr nzcv, x8",
"ldr x8, [x28, #40]",
"str xzr, [x28, #1184]",
"str xzr, [x28, #1056]",
"orr x5, x0, x1, lsl #12"
]
},

View File

@ -17,19 +17,15 @@
]
},
"pop fs": {
"ExpectedInstructionCount": 11,
"ExpectedInstructionCount": 7,
"Comment": "0x0f 0xa1",
"ExpectedArm64ASM": [
"ldr w20, [x8]",
"add x8, x8, #0x4 (4)",
"strh w20, [x28, #146]",
"ubfx w20, w20, #3, #13",
"add x0, x28, x20, lsl #3",
"ldr x20, [x0, #896]",
"lsr x21, x20, #32",
"and w22, w21, #0xff000000",
"orr w20, w22, w20, lsr #16",
"bfi w20, w21, #16, #8",
"add x0, x28, x20, lsl #2",
"ldr w20, [x0, #896]",
"str w20, [x28, #176]"
]
},
@ -42,19 +38,15 @@
]
},
"pop gs": {
"ExpectedInstructionCount": 11,
"ExpectedInstructionCount": 7,
"Comment": "0x0f 0xa9",
"ExpectedArm64ASM": [
"ldr w20, [x8]",
"add x8, x8, #0x4 (4)",
"strh w20, [x28, #144]",
"ubfx w20, w20, #3, #13",
"add x0, x28, x20, lsl #3",
"ldr x20, [x0, #896]",
"lsr x21, x20, #32",
"and w22, w21, #0xff000000",
"orr w20, w22, w20, lsr #16",
"bfi w20, w21, #16, #8",
"add x0, x28, x20, lsl #2",
"ldr w20, [x0, #896]",
"str w20, [x28, #168]"
]
}

View File

@ -522,7 +522,7 @@
"0x66 0x0f 0x70"
],
"ExpectedArm64ASM": [
"ldr x0, [x28, #1816]",
"ldr x0, [x28, #1688]",
"ldr q2, [x0, #16]",
"tbl v16.16b, {v17.16b}, v2.16b"
]
@ -536,7 +536,7 @@
],
"ExpectedArm64ASM": [
"ldr q2, [x4]",
"ldr x0, [x28, #1816]",
"ldr x0, [x28, #1688]",
"ldr q3, [x0, #16]",
"tbl v16.16b, {v2.16b}, v3.16b"
]
@ -1014,7 +1014,7 @@
"ExpectedInstructionCount": 3,
"Comment": "0x66 0x0f 0xd0",
"ExpectedArm64ASM": [
"ldr q2, [x28, #2160]",
"ldr q2, [x28, #2032]",
"eor v2.16b, v17.16b, v2.16b",
"fadd v16.2d, v16.2d, v2.2d"
]

View File

@ -354,7 +354,7 @@
"0xf3 0x0f 0x70"
],
"ExpectedArm64ASM": [
"ldr x0, [x28, #1808]",
"ldr x0, [x28, #1680]",
"ldr q2, [x0, #16]",
"tbl v16.16b, {v17.16b}, v2.16b"
]

View File

@ -296,7 +296,7 @@
"0xf2 0x0f 0x70"
],
"ExpectedArm64ASM": [
"ldr x0, [x28, #1800]",
"ldr x0, [x28, #1672]",
"ldr q2, [x0, #16]",
"tbl v16.16b, {v17.16b}, v2.16b"
]
@ -452,7 +452,7 @@
"ExpectedInstructionCount": 3,
"Comment": "0xf2 0x0f 0xd0",
"ExpectedArm64ASM": [
"ldr q2, [x28, #2128]",
"ldr q2, [x28, #2000]",
"eor v2.16b, v17.16b, v2.16b",
"fadd v16.4s, v16.4s, v2.4s"
]

View File

@ -2755,7 +2755,7 @@
"Map 1 0b00 0xC6 128-bit"
],
"ExpectedArm64ASM": [
"ldr x0, [x28, #1824]",
"ldr x0, [x28, #1696]",
"ldr q2, [x0, #16]",
"tbl v16.16b, {v17.16b, v18.16b}, v2.16b"
]
@ -2824,7 +2824,7 @@
"Map 1 0b00 0xC6 128-bit"
],
"ExpectedArm64ASM": [
"ldr x0, [x28, #1824]",
"ldr x0, [x28, #1696]",
"ldr q2, [x0, #32]",
"tbl v16.16b, {v17.16b, v18.16b}, v2.16b"
]
@ -2893,7 +2893,7 @@
"Map 1 0b00 0xC6 128-bit"
],
"ExpectedArm64ASM": [
"ldr x0, [x28, #1824]",
"ldr x0, [x28, #1696]",
"ldr q2, [x0, #48]",
"tbl v16.16b, {v17.16b, v18.16b}, v2.16b"
]
@ -4338,7 +4338,7 @@
"Map 1 0b01 0xd0 128-bit"
],
"ExpectedArm64ASM": [
"ldr q2, [x28, #2160]",
"ldr q2, [x28, #2032]",
"eor v2.16b, v18.16b, v2.16b",
"fadd v16.2d, v17.2d, v2.2d"
]
@ -4349,7 +4349,7 @@
"Map 1 0b01 0xd0 256-bit"
],
"ExpectedArm64ASM": [
"ldr x0, [x28, #1720]",
"ldr x0, [x28, #1592]",
"ld1b {z2.b}, p7/z, [x0]",
"eor z2.d, z18.d, z2.d",
"fadd z16.d, z17.d, z2.d"
@ -4361,7 +4361,7 @@
"Map 1 0b11 0xd0 128-bit"
],
"ExpectedArm64ASM": [
"ldr q2, [x28, #2128]",
"ldr q2, [x28, #2000]",
"eor v2.16b, v18.16b, v2.16b",
"fadd v16.4s, v17.4s, v2.4s"
]
@ -4372,7 +4372,7 @@
"Map 1 0b11 0xd0 256-bit"
],
"ExpectedArm64ASM": [
"ldr x0, [x28, #1704]",
"ldr x0, [x28, #1576]",
"ld1b {z2.b}, p7/z, [x0]",
"eor z2.d, z18.d, z2.d",
"fadd z16.s, z17.s, z2.s"

View File

@ -1575,7 +1575,7 @@
"Map 2 0b01 0x41 256-bit"
],
"ExpectedArm64ASM": [
"ldr q2, [x28, #2096]",
"ldr q2, [x28, #1968]",
"zip1 v3.8h, v2.8h, v17.8h",
"zip2 v2.8h, v2.8h, v17.8h",
"umin v2.4s, v3.4s, v2.4s",

View File

@ -4799,7 +4799,7 @@
"Map 3 0b01 0xdf 128-bit"
],
"ExpectedArm64ASM": [
"ldr q2, [x28, #2208]",
"ldr q2, [x28, #2080]",
"movi v3.2d, #0x0",
"mov v16.16b, v17.16b",
"unimplemented (Unimplemented)",
@ -4812,7 +4812,7 @@
"Map 3 0b01 0xdf 128-bit"
],
"ExpectedArm64ASM": [
"ldr q2, [x28, #2208]",
"ldr q2, [x28, #2080]",
"movi v3.2d, #0x0",
"mov v16.16b, v17.16b",
"unimplemented (Unimplemented)",

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff