diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index 33f01904c..45a9df7b7 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -4307,6 +4307,7 @@ AddressMode OpDispatchBuilder::DecodeAddress(const X86Tables::DecodedOp& Op, con } } else if (Operand.IsGPR()) { // Not an address, let the caller deal with it + A.AddrSize = GPRSize; } else if (Operand.IsGPRDirect()) { A.Base = LoadGPRRegister(Operand.Data.GPR.GPR, GPRSize); A.NonTSO |= IsNonTSOReg(AccessType, Operand.Data.GPR.GPR); diff --git a/unittests/ASM/FEX_bugs/mov_address_size_override.asm b/unittests/ASM/FEX_bugs/mov_address_size_override.asm new file mode 100644 index 000000000..2f63ec1a0 --- /dev/null +++ b/unittests/ASM/FEX_bugs/mov_address_size_override.asm @@ -0,0 +1,21 @@ +%ifdef CONFIG +{ + "RegData": { + "RDX": "0x5152535455565758", + "R8": "0x5152535455565758" + } +} +%endif +; FEX-Emu had a bug where address size override was overriding destination and source sizes on operations not affecting memory. +; This showed up as a bug in OpenSSL where GCC was padding move instructions with the address size prefix, knowing that it wouldn't do anything. +; FEX interpreted this address size prefix as making the destination 32-bit resulting in zero-extending the 64-bit source. +; Ensure this doesn't happen again. +mov rdx, 0x414243444546748 +mov r8, 0x5152535455565758 +jmp .test +.test: + +; Add a couple address size prefixes +db 0x67, 0x67 +mov rdx, r8 +hlt