diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index 2e07e7805..93d89a8aa 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -2163,6 +2163,7 @@ void OpDispatchBuilder::RCRSmallerOp(OpcodeArgs) { Calculate_ShiftVariable(Op, Src, [this, Op, Size]() { // Rematerialized to avoid crossblock liveness Ref Src = LoadSource(GPRClass, Op, Op->Src[1], Op->Flags, {.AllowUpperGarbage = true}); + Src = AndConst(OpSize::i32Bit, Src, 0x1F); auto CF = GetRFLAG(FEXCore::X86State::RFLAG_CF_RAW_LOC); diff --git a/unittests/ASM/FEX_bugs/LargeRotatesForSmallSizes_More.asm b/unittests/ASM/FEX_bugs/LargeRotatesForSmallSizes_More.asm new file mode 100644 index 000000000..fb87d8407 --- /dev/null +++ b/unittests/ASM/FEX_bugs/LargeRotatesForSmallSizes_More.asm @@ -0,0 +1,90 @@ +%ifdef CONFIG +{ + "RegData": { + "RAX": "0x41424344454647a4", + "RBX": "0x4142434445464790", + "RCX": "0x4142434445464724", + "RDX": "0x4142434445464790", + "RSI": "0x4142434445468e90", + "RDI": "0x414243444546a3a4", + "RBP": "0x41424344454623a4", + "RSP": "0x4142434445468e90", + "R8": "0x4142434445464729", + "R9": "0x4142434445464741", + "R10": "0x4142434445464729", + "R11": "0x4142434445464741", + "R12": "0x4142434445464729", + "R13": "0x4142434445464741", + "R14": "0x4142434445464729", + "R15": "0x4142434445464741" + } +} +%endif + +; FEX-Emu had a bug where 8-bit and 16-bit rotates with carry generated incorrect results when the rotate amount was larger than the data size. +; These are additional tests to capture more edge cases in the implementation. +; This is well defined in x86 semantics. + +mov rax, 0x4142434445464748 +mov rbx, 0x4142434445464748 +mov rdx, 0x4142434445464748 +mov rdi, 0x4142434445464748 +mov rsi, 0x4142434445464748 +mov rbp, 0x4142434445464748 +mov rsp, 0x4142434445464748 +mov r8, 0x4142434445464748 +mov r9, 0x4142434445464748 +mov r10, 0x4142434445464748 +mov r11, 0x4142434445464748 +mov r12, 0x4142434445464748 +mov r13, 0x4142434445464748 +mov r14, 0x4142434445464748 +mov r15, 0x4142434445464748 + +mov rcx, 0x515253545556571E +jmp .test +.test: +; 8-bit cl, carry +stc +rcr r8b, cl +rcl r9b, cl + +; 8-bit cl, no-carry +stc +rcr r10b, cl +rcl r11b, cl + +; 16-bit cl, carry +stc +rcr r12b, cl +rcl r13b, cl + +; 16-bit cl, no-carry +stc +rcr r14b, cl +rcl r15b, cl + +; Fix RCX since we used it +mov rcx, 0x4142434445464748 + +; 8-bit const, carry +stc +rcr al, 0x21 +rcl bl, 0x21 + +; 8-bit const, no-carry +clc +rcr cl, 0x21 +rcl dl, 0x21 + +; 16-bit const, carry +stc +rcr di, 0x21 +rcl si, 0x21 + +; 16-bit const, no-carry +clc +rcr bp, 0x21 +rcl sp, 0x21 + +hlt diff --git a/unittests/InstructionCountCI/FlagM/PrimaryGroup.json b/unittests/InstructionCountCI/FlagM/PrimaryGroup.json index 637baee98..6b12d5441 100644 --- a/unittests/InstructionCountCI/FlagM/PrimaryGroup.json +++ b/unittests/InstructionCountCI/FlagM/PrimaryGroup.json @@ -1602,23 +1602,24 @@ ] }, "rcr al, cl": { - "ExpectedInstructionCount": 15, + "ExpectedInstructionCount": 16, "Comment": "GROUP2 0xd2 /3", "ExpectedArm64ASM": [ "and w20, w5, #0x1f", - "cbz x20, #+0x38", - "cset w20, hs", - "uxtb w21, w4", - "bfi x21, x20, #8, #1", - "bfi x21, x21, #9, #9", - "bfi x21, x21, #18, #18", - "bfi x21, x21, #36, #9", - "lsr x20, x21, x5", - "bfxil x4, x20, #0, #8", - "sub w22, w5, #0x1 (1)", - "lsr w21, w21, w22", - "rmif x21, #63, #nzCv", - "eor w20, w20, w20, lsr #1", + "cbz x20, #+0x3c", + "and w20, w5, #0x1f", + "cset w21, hs", + "uxtb w22, w4", + "bfi x22, x21, #8, #1", + "bfi x22, x22, #9, #9", + "bfi x22, x22, #18, #18", + "bfi x22, x22, #36, #9", + "lsr x21, x22, x20", + "bfxil x4, x21, #0, #8", + "sub w20, w20, #0x1 (1)", + "lsr w20, w22, w20", + "rmif x20, #63, #nzCv", + "eor w20, w21, w21, lsr #1", "rmif x20, #6, #nzcV" ] }, @@ -1830,22 +1831,23 @@ ] }, "rcr ax, cl": { - "ExpectedInstructionCount": 14, + "ExpectedInstructionCount": 15, "Comment": "GROUP2 0xd3 /3", "ExpectedArm64ASM": [ "and w20, w5, #0x1f", - "cbz x20, #+0x34", - "cset w20, hs", - "uxth w21, w4", - "bfi x21, x20, #16, #1", - "bfi x21, x21, #17, #17", - "bfi x21, x21, #34, #17", - "lsr x20, x21, x5", - "bfxil x4, x20, #0, #16", - "sub w22, w5, #0x1 (1)", - "lsr w21, w21, w22", - "rmif x21, #63, #nzCv", - "eor w20, w20, w20, lsr #1", + "cbz x20, #+0x38", + "and w20, w5, #0x1f", + "cset w21, hs", + "uxth w22, w4", + "bfi x22, x21, #16, #1", + "bfi x22, x22, #17, #17", + "bfi x22, x22, #34, #17", + "lsr x21, x22, x20", + "bfxil x4, x21, #0, #16", + "sub w20, w20, #0x1 (1)", + "lsr w20, w22, w20", + "rmif x20, #63, #nzCv", + "eor w20, w21, w21, lsr #1", "rmif x20, #14, #nzcV" ] }, diff --git a/unittests/InstructionCountCI/PrimaryGroup.json b/unittests/InstructionCountCI/PrimaryGroup.json index c35c36402..1b0bd1370 100644 --- a/unittests/InstructionCountCI/PrimaryGroup.json +++ b/unittests/InstructionCountCI/PrimaryGroup.json @@ -1889,25 +1889,26 @@ ] }, "rcr al, cl": { - "ExpectedInstructionCount": 19, + "ExpectedInstructionCount": 20, "Comment": "GROUP2 0xd2 /3", "ExpectedArm64ASM": [ "and w20, w5, #0x1f", - "cbz x20, #+0x48", - "cset w20, hs", - "uxtb w21, w4", - "bfi x21, x20, #8, #1", - "bfi x21, x21, #9, #9", - "bfi x21, x21, #18, #18", - "bfi x21, x21, #36, #9", - "lsr x20, x21, x5", - "bfxil x4, x20, #0, #8", - "sub w22, w5, #0x1 (1)", - "lsr w21, w21, w22", - "ubfx x21, x21, #0, #1", + "cbz x20, #+0x4c", + "and w20, w5, #0x1f", + "cset w21, hs", + "uxtb w22, w4", + "bfi x22, x21, #8, #1", + "bfi x22, x22, #9, #9", + "bfi x22, x22, #18, #18", + "bfi x22, x22, #36, #9", + "lsr x21, x22, x20", + "bfxil x4, x21, #0, #8", + "sub w20, w20, #0x1 (1)", + "lsr w20, w22, w20", + "ubfx x20, x20, #0, #1", "mrs x22, nzcv", - "bfi w22, w21, #29, #1", - "eor w20, w20, w20, lsr #1", + "bfi w22, w20, #29, #1", + "eor w20, w21, w21, lsr #1", "ubfx x20, x20, #6, #1", "bfi w22, w20, #28, #1", "msr nzcv, x22" @@ -2165,24 +2166,25 @@ ] }, "rcr ax, cl": { - "ExpectedInstructionCount": 18, + "ExpectedInstructionCount": 19, "Comment": "GROUP2 0xd3 /3", "ExpectedArm64ASM": [ "and w20, w5, #0x1f", - "cbz x20, #+0x44", - "cset w20, hs", - "uxth w21, w4", - "bfi x21, x20, #16, #1", - "bfi x21, x21, #17, #17", - "bfi x21, x21, #34, #17", - "lsr x20, x21, x5", - "bfxil x4, x20, #0, #16", - "sub w22, w5, #0x1 (1)", - "lsr w21, w21, w22", - "ubfx x21, x21, #0, #1", + "cbz x20, #+0x48", + "and w20, w5, #0x1f", + "cset w21, hs", + "uxth w22, w4", + "bfi x22, x21, #16, #1", + "bfi x22, x22, #17, #17", + "bfi x22, x22, #34, #17", + "lsr x21, x22, x20", + "bfxil x4, x21, #0, #16", + "sub w20, w20, #0x1 (1)", + "lsr w20, w22, w20", + "ubfx x20, x20, #0, #1", "mrs x22, nzcv", - "bfi w22, w21, #29, #1", - "eor w20, w20, w20, lsr #1", + "bfi w22, w20, #29, #1", + "eor w20, w21, w21, lsr #1", "ubfx x20, x20, #14, #1", "bfi w22, w20, #28, #1", "msr nzcv, x22"