From 0879994aff56c79488297f399fb3396af6c00a09 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Mon, 11 Aug 2025 17:01:49 -0700 Subject: [PATCH] FEXCore: Fixes 16-bit operand size Leave Weren't testing this edge case just like enter --- .../Interface/Core/OpcodeDispatcher.cpp | 9 ++++--- unittests/ASM/Primary/Primary_C9_o16.asm | 26 +++++++++++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 unittests/ASM/Primary/Primary_C9_o16.asm diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index 1e8ddb8ba..f04b4d651 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -498,15 +498,18 @@ void OpDispatchBuilder::POPSegmentOp(OpcodeArgs, uint32_t SegmentReg) { } void OpDispatchBuilder::LEAVEOp(OpcodeArgs) { + const auto GPRSize = GetGPROpSize(); + const auto OperandSize = (Op->Flags & FEXCore::X86Tables::DecodeFlags::FLAG_OPERAND_SIZE) ? OpSize::i16Bit : GPRSize; + // First we move RBP in to RSP and then behave effectively like a pop auto SP = _RMWHandle(LoadGPRRegister(X86State::REG_RBP)); - auto NewGPR = Pop(OpSizeFromSrc(Op), SP); + auto NewGPR = Pop(OperandSize, SP); // Store the new stack pointer - StoreGPRRegister(X86State::REG_RSP, SP); + StoreGPRRegister(X86State::REG_RSP, SP, OperandSize); // Store what we loaded to RBP - StoreGPRRegister(X86State::REG_RBP, NewGPR); + StoreGPRRegister(X86State::REG_RBP, NewGPR, OperandSize); } void OpDispatchBuilder::CALLOp(OpcodeArgs) { diff --git a/unittests/ASM/Primary/Primary_C9_o16.asm b/unittests/ASM/Primary/Primary_C9_o16.asm new file mode 100644 index 000000000..149adc6d2 --- /dev/null +++ b/unittests/ASM/Primary/Primary_C9_o16.asm @@ -0,0 +1,26 @@ +%ifdef CONFIG +{ + "RegData": { + "RAX": "0x1", + "RBP": "0xe0004748", + "RSP": "0xe0000020" + } +} +%endif + +mov rsp, 0xe0000020 +mov rbp, 0x4142434445464748 + +; Act like an ENTER frame without using ENTER +sub rsp, 2 +mov [rsp], bp +mov rbp, rsp +call .target +jmp .end + +.target: +mov rax, 1 +o16 leave + +.end: +hlt