diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index 79d3728c6..483dec5f0 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -2627,12 +2627,16 @@ void OpDispatchBuilder::BLSRBMIOp(OpcodeArgs) { GenerateFlags_BLSR(Op, Result, Src); } +// Handles SARX, SHLX, and SHRX void OpDispatchBuilder::BMI2Shift(OpcodeArgs) { - // Handles SARX, SHLX, and SHRX - - auto* Src = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags, -1); - auto* Shift = LoadSource(GPRClass, Op, Op->Src[1], Op->Flags, -1); + // In the event the source is a memory operand, use the + // exact width instead of the GPR size. + const auto GPRSize = CTX->GetGPRSize(); const auto Size = GetSrcSize(Op); + const auto SrcSize = Op->Src[0].IsGPR() ? GPRSize : Size; + + auto* Src = LoadSource_WithOpSize(GPRClass, Op, Op->Src[0], SrcSize, Op->Flags, -1); + auto* Shift = LoadSource_WithOpSize(GPRClass, Op, Op->Src[1], GPRSize, Op->Flags, -1); auto* Result = [&]() -> OrderedNode* { // SARX diff --git a/unittests/InstructionCountCI/VEX_map2.json b/unittests/InstructionCountCI/VEX_map2.json index 4c43d46fd..28e7eea45 100644 --- a/unittests/InstructionCountCI/VEX_map2.json +++ b/unittests/InstructionCountCI/VEX_map2.json @@ -4036,6 +4036,16 @@ ] }, "shlx eax, ebx, ecx": { + "ExpectedInstructionCount": 1, + "Optimal": "Yes", + "Comment": [ + "Map 2 0b01 0xf7 32-bit" + ], + "ExpectedArm64ASM": [ + "lsl w4, w7, w5" + ] + }, + "shlx eax, [ebx], ecx": { "ExpectedInstructionCount": 3, "Optimal": "No", "Comment": [ @@ -4043,8 +4053,8 @@ ], "ExpectedArm64ASM": [ "mov w20, w7", - "mov w21, w5", - "lsl w4, w20, w21" + "ldr w20, [x20]", + "lsl w4, w20, w5" ] }, "shlx rax, rbx, rcx": { @@ -4057,7 +4067,28 @@ "lsl x4, x7, x5" ] }, + "shlx rax, [rbx], rcx": { + "ExpectedInstructionCount": 2, + "Optimal": "Yes", + "Comment": [ + "Map 2 0b01 0xf7 64-bit" + ], + "ExpectedArm64ASM": [ + "ldr x20, [x7]", + "lsl x4, x20, x5" + ] + }, "sarx eax, ebx, ecx": { + "ExpectedInstructionCount": 1, + "Optimal": "Yes", + "Comment": [ + "Map 2 0b10 0xf7 32-bit" + ], + "ExpectedArm64ASM": [ + "asr w4, w7, w5" + ] + }, + "sarx eax, [ebx], ecx": { "ExpectedInstructionCount": 3, "Optimal": "No", "Comment": [ @@ -4065,8 +4096,8 @@ ], "ExpectedArm64ASM": [ "mov w20, w7", - "mov w21, w5", - "asr w4, w20, w21" + "ldr w20, [x20]", + "asr w4, w20, w5" ] }, "sarx rax, rbx, rcx": { @@ -4079,7 +4110,28 @@ "asr x4, x7, x5" ] }, + "sarx rax, [rbx], rcx": { + "ExpectedInstructionCount": 2, + "Optimal": "Yes", + "Comment": [ + "Map 2 0b10 0xf7 64-bit" + ], + "ExpectedArm64ASM": [ + "ldr x20, [x7]", + "asr x4, x20, x5" + ] + }, "shrx eax, ebx, ecx": { + "ExpectedInstructionCount": 1, + "Optimal": "Yes", + "Comment": [ + "Map 2 0b11 0xf7 32-bit" + ], + "ExpectedArm64ASM": [ + "lsr w4, w7, w5" + ] + }, + "shrx eax, [ebx], ecx": { "ExpectedInstructionCount": 3, "Optimal": "No", "Comment": [ @@ -4087,8 +4139,8 @@ ], "ExpectedArm64ASM": [ "mov w20, w7", - "mov w21, w5", - "lsr w4, w20, w21" + "ldr w20, [x20]", + "lsr w4, w20, w5" ] }, "shrx rax, rbx, rcx": { @@ -4100,6 +4152,17 @@ "ExpectedArm64ASM": [ "lsr x4, x7, x5" ] + }, + "shrx rax, [rbx], rcx": { + "ExpectedInstructionCount": 2, + "Optimal": "Yes", + "Comment": [ + "Map 2 0b11 0xf7 64-bit" + ], + "ExpectedArm64ASM": [ + "ldr x20, [x7]", + "lsr x4, x20, x5" + ] } } }