From 77511c5f929c6358f14812a1274af9874f828346 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Tue, 29 Sep 2020 16:37:46 -0700 Subject: [PATCH 1/2] Fixes unsigned multiply zext mechanics 32bit wasn't zexting correctly --- .../Source/Interface/Core/OpcodeDispatcher.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index 26db6503d..a8ebaae0e 100644 --- a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -2615,6 +2615,8 @@ void OpDispatchBuilder::IMULOp(OpcodeArgs) { void OpDispatchBuilder::MULOp(OpcodeArgs) { uint8_t Size = GetSrcSize(Op); + uint8_t GPRSize = CTX->Config.Is64BitMode ? 8 : 4; + OrderedNode *Src1 = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, -1); OrderedNode *Src2 = _LoadContext(Size, offsetof(FEXCore::Core::CPUState, gregs[FEXCore::X86State::REG_RAX]), GPRClass); if (Size != 8) { @@ -2639,11 +2641,10 @@ void OpDispatchBuilder::MULOp(OpcodeArgs) { else if (Size == 4) { // 32bits stored in EAX // 32bits stored in EDX - OrderedNode *ResultLow = _Bfe(32, 0, Result); - ResultHigh = _Bfe(32, 32, Result); - _StoreContext(GPRClass, 4, offsetof(FEXCore::Core::CPUState, gregs[FEXCore::X86State::REG_RAX]), ResultLow); - _StoreContext(GPRClass, 4, offsetof(FEXCore::Core::CPUState, gregs[FEXCore::X86State::REG_RDX]), ResultHigh); - + OrderedNode *ResultLow = _Bfe(GPRSize, 32, 0, Result); + ResultHigh = _Bfe(GPRSize, 32, 32, Result); + _StoreContext(GPRClass, GPRSize, offsetof(FEXCore::Core::CPUState, gregs[FEXCore::X86State::REG_RAX]), ResultLow); + _StoreContext(GPRClass, GPRSize, offsetof(FEXCore::Core::CPUState, gregs[FEXCore::X86State::REG_RDX]), ResultHigh); } else if (Size == 8) { LogMan::Throw::A(CTX->Config.Is64BitMode, "Doesn't exist in 32bit mode"); From 6af0bace1a80fad67fe7f7e59b71fd29d1a0267b Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Tue, 29 Sep 2020 16:38:28 -0700 Subject: [PATCH 2/2] Unit tests to ensure MUL zexting behaviour --- unittests/ASM/PrimaryGroup/3_F6_04.asm | 9 ++++++++- unittests/ASM/PrimaryGroup/3_F7_04.asm | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/unittests/ASM/PrimaryGroup/3_F6_04.asm b/unittests/ASM/PrimaryGroup/3_F6_04.asm index c3d1dcb3c..528f4376e 100644 --- a/unittests/ASM/PrimaryGroup/3_F6_04.asm +++ b/unittests/ASM/PrimaryGroup/3_F6_04.asm @@ -1,7 +1,8 @@ %ifdef CONFIG { "RegData": { - "RAX": "0x414243444546008E" + "RAX": "0x414243444546008E", + "RBX": "0xFFFFFFFFFFFF0004" }, "MemoryRegions": { "0x100000000": "4096" @@ -20,6 +21,12 @@ mov al, 2 mul byte [rdx + 8 * 0 + 1] mov word [rdx + 8 * 0], ax +; Ensure this inserts in to AX +mov rax, 0xFFFFFFFFFFFFFF02 +mov rbx, 0xFFFFFFFFFFFFFF02 +mul bl +mov rbx, rax + mov rax, [rdx + 8 * 0] hlt diff --git a/unittests/ASM/PrimaryGroup/3_F7_04.asm b/unittests/ASM/PrimaryGroup/3_F7_04.asm index b9d52d9f6..4b910c194 100644 --- a/unittests/ASM/PrimaryGroup/3_F7_04.asm +++ b/unittests/ASM/PrimaryGroup/3_F7_04.asm @@ -3,6 +3,8 @@ "RegData": { "RAX": "0x414243441F968610", "RBX": "0x25D1437D318C1BE0", + "RCX": "0xFFFFFFFFFFFF0004", + "RDX": "0x0000000000000004", "RSI": "0xFC1B5FC85401D0C0", "RSP": "0x2B27F79B13618682" }, @@ -36,6 +38,19 @@ mul qword [r15 + 8 * 2 + 0] mov rsi, rax mov rsp, rdx +; Ensure zext handling is correct +; 16bit +mov rax, 0xFFFFFFFFFFFF0002 +mov rbx, 0xFFFFFFFFFFFF0002 +mul bx +mov rcx, rax + +; 32bit +mov rax, 0xFFFFFFFF00000002 +mov rbx, 0xFFFFFFFF00000002 +mul ebx +mov rdx, rax + mov rax, [r15 + 8 * 0] mov rbx, [r15 + 8 * 1]