From 514532480657ce1a4d81a7da3174d0cc829f2c9a Mon Sep 17 00:00:00 2001 From: LC Date: Fri, 3 Jul 2026 21:07:37 -0400 Subject: [PATCH] [SVE256] EncryptionOps: Handle 256-bit VPCLMULQDQ Since vixl now handles this, we can drop this support right in. --- .../Interface/Core/JIT/EncryptionOps.cpp | 66 +++++++++++++++---- unittests/ASM/Disabled_Tests_Simulator | 3 +- unittests/InstructionCountCI/VEX_map3.json | 26 +++++--- 3 files changed, 71 insertions(+), 24 deletions(-) diff --git a/FEXCore/Source/Interface/Core/JIT/EncryptionOps.cpp b/FEXCore/Source/Interface/Core/JIT/EncryptionOps.cpp index b1c0a4bcc..33dbedf3a 100644 --- a/FEXCore/Source/Interface/Core/JIT/EncryptionOps.cpp +++ b/FEXCore/Source/Interface/Core/JIT/EncryptionOps.cpp @@ -324,24 +324,62 @@ DEF_OP(PCLMUL) { const auto Op = IROp->C(); const auto OpSize = IROp->Size; + const auto Is256Bit = OpSize == IR::OpSize::i256Bit; + LOGMAN_THROW_A_FMT(!Is256Bit || HostSupportsSVE256, "Need SVE256 support in order to use {} with 256-bit operation", __func__); + const auto Dst = GetVReg(Node); const auto Src1 = GetVReg(Op->Src1); const auto Src2 = GetVReg(Op->Src2); - LOGMAN_THROW_A_FMT(OpSize == IR::OpSize::i128Bit, "Currently only supports 128-bit operations."); - - switch (Op->Selector) { - case 0b00000000: pmull(ARMEmitter::SubRegSize::i128Bit, Dst.D(), Src1.D(), Src2.D()); break; - case 0b00000001: - dup(ARMEmitter::SubRegSize::i64Bit, VTMP1.Q(), Src1.Q(), 1); - pmull(ARMEmitter::SubRegSize::i128Bit, Dst.D(), VTMP1.D(), Src2.D()); - break; - case 0b00010000: - dup(ARMEmitter::SubRegSize::i64Bit, VTMP1.Q(), Src2.Q(), 1); - pmull(ARMEmitter::SubRegSize::i128Bit, Dst.D(), VTMP1.D(), Src1.D()); - break; - case 0b00010001: pmull2(ARMEmitter::SubRegSize::i128Bit, Dst.Q(), Src1.Q(), Src2.Q()); break; - default: LOGMAN_MSG_A_FMT("Unknown PCLMUL selector: {}", Op->Selector); break; + if (HostSupportsSVE256 && Is256Bit) { + switch (Op->Selector) { + case 0b00000000: { + pmullb(ARMEmitter::SubRegSize::i128Bit, Dst.Z(), Src1.Z(), Src2.Z()); + break; + } + case 0b00000001: { + trn2(ARMEmitter::SubRegSize::i64Bit, VTMP1.Z(), Src1.Z(), Src1.Z()); + pmullb(ARMEmitter::SubRegSize::i128Bit, Dst.Z(), VTMP1.Z(), Src2.Z()); + break; + } + case 0b00010000: + trn2(ARMEmitter::SubRegSize::i64Bit, VTMP1.Z(), Src2.Z(), Src2.Z()); + pmullb(ARMEmitter::SubRegSize::i128Bit, Dst.Z(), Src1.Z(), VTMP1.Z()); + break; + case 0b00010001: { + pmullt(ARMEmitter::SubRegSize::i128Bit, Dst.Z(), Src1.Z(), Src2.Z()); + break; + } + default: { + LOGMAN_MSG_A_FMT("Unknown PCLMUL selector: {}", Op->Selector); + break; + } + } + } else { + switch (Op->Selector) { + case 0b00000000: { + pmull(ARMEmitter::SubRegSize::i128Bit, Dst.D(), Src1.D(), Src2.D()); + break; + } + case 0b00000001: { + dup(ARMEmitter::SubRegSize::i64Bit, VTMP1.Q(), Src1.Q(), 1); + pmull(ARMEmitter::SubRegSize::i128Bit, Dst.D(), VTMP1.D(), Src2.D()); + break; + } + case 0b00010000: { + dup(ARMEmitter::SubRegSize::i64Bit, VTMP1.Q(), Src2.Q(), 1); + pmull(ARMEmitter::SubRegSize::i128Bit, Dst.D(), VTMP1.D(), Src1.D()); + break; + } + case 0b00010001: { + pmull2(ARMEmitter::SubRegSize::i128Bit, Dst.Q(), Src1.Q(), Src2.Q()); + break; + } + default: { + LOGMAN_MSG_A_FMT("Unknown PCLMUL selector: {}", Op->Selector); + break; + } + } } } diff --git a/unittests/ASM/Disabled_Tests_Simulator b/unittests/ASM/Disabled_Tests_Simulator index 8874d0af5..f3e4a6e03 100644 --- a/unittests/ASM/Disabled_Tests_Simulator +++ b/unittests/ASM/Disabled_Tests_Simulator @@ -1,11 +1,10 @@ -# AES and vpclmul unsupported in 256-bit SVE currently +# AES unsupported in 256-bit SVE currently Test_VEX/vaesdec.asm Test_VEX/vaesdeclast.asm Test_VEX/vaesdec256.asm Test_VEX/vaesdeclast256.asm Test_VEX/vaesenc256.asm Test_VEX/vaesenclast256.asm -Test_VEX/vpclmulqdq_256.asm # Simulator can't handle self-modifying code Test_SelfModifyingCode/Delinking.asm diff --git a/unittests/InstructionCountCI/VEX_map3.json b/unittests/InstructionCountCI/VEX_map3.json index 05b5de0d0..9c2595e41 100644 --- a/unittests/InstructionCountCI/VEX_map3.json +++ b/unittests/InstructionCountCI/VEX_map3.json @@ -3937,31 +3937,41 @@ ] }, "vpclmulqdq ymm0, ymm1, ymm2, 00000b": { - "ExpectedInstructionCount": -1, - "Skip": "Yes", + "ExpectedInstructionCount": 1, "Comment": [ "Map 3 0b01 0x44 256-bit" + ], + "ExpectedArm64ASM": [ + "pmullb z16.q, z17.d, z18.d" ] }, "vpclmulqdq ymm0, ymm1, ymm2, 00001b": { - "ExpectedInstructionCount": -1, - "Skip": "Yes", + "ExpectedInstructionCount": 2, "Comment": [ "Map 3 0b01 0x44 256-bit" + ], + "ExpectedArm64ASM": [ + "trn2 z0.d, z17.d, z17.d", + "pmullb z16.q, z0.d, z18.d" ] }, "vpclmulqdq ymm0, ymm1, ymm2, 10000b": { - "ExpectedInstructionCount": -1, - "Skip": "Yes", + "ExpectedInstructionCount": 2, "Comment": [ "Map 3 0b01 0x44 256-bit" + ], + "ExpectedArm64ASM": [ + "trn2 z0.d, z18.d, z18.d", + "pmullb z16.q, z17.d, z0.d" ] }, "vpclmulqdq ymm0, ymm1, ymm2, 10001b": { - "ExpectedInstructionCount": -1, - "Skip": "Yes", + "ExpectedInstructionCount": 1, "Comment": [ "Map 3 0b01 0x44 256-bit" + ], + "ExpectedArm64ASM": [ + "pmullt z16.q, z17.d, z18.d" ] }, "vperm2i128 ymm0, ymm1, ymm2, 00000000b": {