From dcd71fe126c71064fb20de17ab4424f3a3d7ea6e Mon Sep 17 00:00:00 2001 From: LC Date: Tue, 16 Jun 2026 23:07:10 -0400 Subject: [PATCH] [SVE256] Handle SSE insertions for PMULHW/PMULHRSW See #3799 --- .../Core/OpcodeDispatcher/Vector.cpp | 4 +-- .../ASM/SSELanePreservation/pmulhrsw.asm | 28 +++++++++++++++++++ unittests/ASM/SSELanePreservation/pmulhw.asm | 28 +++++++++++++++++++ .../Secondary_OpSize_SVE256.json | 14 +++++++--- 4 files changed, 68 insertions(+), 6 deletions(-) create mode 100644 unittests/ASM/SSELanePreservation/pmulhrsw.asm create mode 100644 unittests/ASM/SSELanePreservation/pmulhw.asm diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp index 962cea358..56a796444 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp @@ -3715,7 +3715,7 @@ void OpDispatchBuilder::PMULHW(OpcodeArgs, bool Signed) { Ref Src = LoadSourceFPR(Op, Op->Src[0], Op->Flags); Ref Result = PMULHWOpImpl(Op, Signed, Dest, Src); - StoreResultFPR(Op, Result); + StoreResult_WithAVXInsert(VectorOpType::SSE, RegClass::FPR, Op, Result); } void OpDispatchBuilder::VPMULHWOp(OpcodeArgs, bool Signed) { @@ -3767,7 +3767,7 @@ void OpDispatchBuilder::PMULHRSW(OpcodeArgs) { Ref Src = LoadSourceFPR(Op, Op->Src[0], Op->Flags); Ref Result = PMULHRSWOpImpl(OpSizeFromSrc(Op), Dest, Src); - StoreResultFPR(Op, Result); + StoreResult_WithAVXInsert(VectorOpType::SSE, RegClass::FPR, Op, Result); } void OpDispatchBuilder::VPMULHRSWOp(OpcodeArgs) { diff --git a/unittests/ASM/SSELanePreservation/pmulhrsw.asm b/unittests/ASM/SSELanePreservation/pmulhrsw.asm new file mode 100644 index 000000000..feadcee19 --- /dev/null +++ b/unittests/ASM/SSELanePreservation/pmulhrsw.asm @@ -0,0 +1,28 @@ +%ifdef CONFIG +{ + "HostFeatures": ["AVX"], + "RegData": { + "XMM0": ["0xfee6f679457fce8d", "0xbecd1dcd07e90656", "0xccdbcfc31f3ff0f3", "0x108390defebac4be"], + "XMM1": ["0x000023e905a05610", "0x2581228f2ca202aa", "0", "0"], + "XMM2": ["0xc4be43cc1ad6970b", "0x4549bd7eb46a1278", "0xf793ef673dac6e4c", "0xbb7b5b3d85d34271"], + "XMM3": ["0x000043cc1ad6970b", "0x4549bd7eb46a1278", "0xf793ef673dac6e4c", "0xbb7b5b3d85d34271"] + } +} +%endif + +vmovaps ymm0, [rel .data] +vmovaps ymm1, [rel .data + (1 * 32)] +vmovaps ymm2, [rel .data + (2 * 32)] +vmovaps ymm3, [rel .data + (3 * 32)] + +pmulhrsw xmm0, xmm1 +vpmulhrsw xmm1, xmm2, xmm3 + +hlt + +align 32 +.data: +dq 0xfdecd28fab3fa4a5, 0x7d7ccd8836d09fc2, 0xccdbcfc31f3ff0f3, 0x108390defebac4be +dq 0x43cc1ad6970b4549, 0xbd7eb46a1278f793, 0xef673dac6e4cbb7b, 0x5b3d85d342718be9 +dq 0xc4be43cc1ad6970b, 0x4549bd7eb46a1278, 0xf793ef673dac6e4c, 0xbb7b5b3d85d34271 +dq 0x000043cc1ad6970b, 0x4549bd7eb46a1278, 0xf793ef673dac6e4c, 0xbb7b5b3d85d34271 diff --git a/unittests/ASM/SSELanePreservation/pmulhw.asm b/unittests/ASM/SSELanePreservation/pmulhw.asm new file mode 100644 index 000000000..ad2fa5691 --- /dev/null +++ b/unittests/ASM/SSELanePreservation/pmulhw.asm @@ -0,0 +1,28 @@ +%ifdef CONFIG +{ + "HostFeatures": ["AVX"], + "RegData": { + "XMM0": ["0xff73fb3c22bfe746", "0xdf660ee603f4032a", "0xccdbcfc31f3ff0f3", "0x108390defebac4be"], + "XMM1": ["0x000011f402d02b07", "0x12c0114716510155", "0", "0"], + "XMM2": ["0xc4be43cc1ad6970b", "0x4549bd7eb46a1278", "0xf793ef673dac6e4c", "0xbb7b5b3d85d34271"], + "XMM3": ["0x000043cc1ad6970b", "0x4549bd7eb46a1278", "0xf793ef673dac6e4c", "0xbb7b5b3d85d34271"] + } +} +%endif + +vmovaps ymm0, [rel .data] +vmovaps ymm1, [rel .data + (1 * 32)] +vmovaps ymm2, [rel .data + (2 * 32)] +vmovaps ymm3, [rel .data + (3 * 32)] + +pmulhw xmm0, xmm1 +vpmulhw xmm1, xmm2, xmm3 + +hlt + +align 32 +.data: +dq 0xfdecd28fab3fa4a5, 0x7d7ccd8836d09fc2, 0xccdbcfc31f3ff0f3, 0x108390defebac4be +dq 0x43cc1ad6970b4549, 0xbd7eb46a1278f793, 0xef673dac6e4cbb7b, 0x5b3d85d342718be9 +dq 0xc4be43cc1ad6970b, 0x4549bd7eb46a1278, 0xf793ef673dac6e4c, 0xbb7b5b3d85d34271 +dq 0x000043cc1ad6970b, 0x4549bd7eb46a1278, 0xf793ef673dac6e4c, 0xbb7b5b3d85d34271 diff --git a/unittests/InstructionCountCI/Secondary_OpSize_SVE256.json b/unittests/InstructionCountCI/Secondary_OpSize_SVE256.json index 8a08e5d2e..27a477775 100644 --- a/unittests/InstructionCountCI/Secondary_OpSize_SVE256.json +++ b/unittests/InstructionCountCI/Secondary_OpSize_SVE256.json @@ -10,23 +10,29 @@ }, "Instructions": { "pmulhuw xmm0, xmm1": { - "ExpectedInstructionCount": 1, + "ExpectedInstructionCount": 4, "Comment": [ "SVE-256bit changes behaviour slightly", "0x66 0x0f 0xe4" ], "ExpectedArm64ASM": [ - "umulh z16.h, p6/m, z16.h, z17.h" + "movprfx z2, z16", + "umulh z2.h, p6/m, z2.h, z17.h", + "mov z1.q, q2", + "mov z16.b, p6/m, z1.b" ] }, "pmulhw xmm0, xmm1": { - "ExpectedInstructionCount": 1, + "ExpectedInstructionCount": 4, "Comment": [ "SVE-256bit changes behaviour slightly", "0x66 0x0f 0xe5" ], "ExpectedArm64ASM": [ - "smulh z16.h, p6/m, z16.h, z17.h" + "movprfx z2, z16", + "smulh z2.h, p6/m, z2.h, z17.h", + "mov z1.q, q2", + "mov z16.b, p6/m, z1.b" ] } }