From adc5df4578194fd2b0238b853765f79ea930964c Mon Sep 17 00:00:00 2001 From: Alan Hayward Date: Mon, 20 Apr 2026 09:48:05 +0100 Subject: [PATCH 01/11] Add Sm4 and SVE Sm4 APIs Fixes #94426 Fixes #98696 --- src/coreclr/jit/emitarm64.cpp | 1 + src/coreclr/jit/hwintrinsic.cpp | 4 +- src/coreclr/jit/hwintrinsiccodegenarm64.cpp | 5 + src/coreclr/jit/hwintrinsiclistarm64.h | 11 ++- src/coreclr/jit/hwintrinsiclistarm64sve.h | 12 ++- .../ILLink.Substitutions.NoArmIntrinsics.xml | 12 +++ .../System.Private.CoreLib.Shared.projitems | 8 +- .../Arm/Sm4.PlatformNotSupported.cs | 51 ++++++++++ .../src/System/Runtime/Intrinsics/Arm/Sm4.cs | 51 ++++++++++ .../Arm/SveSm4.PlatformNotSupported.cs | 54 ++++++++++ .../System/Runtime/Intrinsics/Arm/SveSm4.cs | 54 ++++++++++ .../ref/System.Runtime.Intrinsics.cs | 28 ++++++ .../Arm/AdvSimdTests.cs | 7 ++ .../GenerateHWIntrinsicTests/Arm/SveTests.cs | 6 ++ .../GenerateHWIntrinsicTests_Arm.cs | 4 +- .../HardwareIntrinsics/Arm/Shared/Helpers.cs | 99 +++++++++++++++++++ .../HardwareIntrinsics/Arm/Shared/Program.cs | 4 +- .../HardwareIntrinsics/Arm/Sm4/Program.Sm4.cs | 16 +++ .../HardwareIntrinsics/Arm/Sm4/Sm4_r.csproj | 14 +++ .../HardwareIntrinsics/Arm/Sm4/Sm4_ro.csproj | 14 +++ .../Arm/SveSm4/Program.SveSm4.cs | 16 +++ .../Arm/SveSm4/SveSm4_r.csproj | 14 +++ .../Arm/SveSm4/SveSm4_ro.csproj | 14 +++ 23 files changed, 491 insertions(+), 8 deletions(-) create mode 100644 src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sm4.PlatformNotSupported.cs create mode 100644 src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sm4.cs create mode 100644 src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/SveSm4.PlatformNotSupported.cs create mode 100644 src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/SveSm4.cs create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/Sm4/Program.Sm4.cs create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/Sm4/Sm4_r.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/Sm4/Sm4_ro.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/SveSm4/Program.SveSm4.cs create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/SveSm4/SveSm4_r.csproj create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/SveSm4/SveSm4_ro.csproj diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp index 34b98a4c6b84de..7b9de72c1b643f 100644 --- a/src/coreclr/jit/emitarm64.cpp +++ b/src/coreclr/jit/emitarm64.cpp @@ -6101,6 +6101,7 @@ void emitter::emitIns_R_R_R(instruction ins, FALLTHROUGH; case INS_sadalp: + case INS_sm4e: case INS_suqadd: case INS_uadalp: case INS_usqadd: diff --git a/src/coreclr/jit/hwintrinsic.cpp b/src/coreclr/jit/hwintrinsic.cpp index bd3211c738aa21..2e811b65e645c6 100644 --- a/src/coreclr/jit/hwintrinsic.cpp +++ b/src/coreclr/jit/hwintrinsic.cpp @@ -1027,10 +1027,10 @@ static const HWIntrinsicIsaRange hwintrinsicIsaRangeArray[] = { { FIRST_NI_Sve, LAST_NI_Sve }, // Sve { FIRST_NI_Sve2, LAST_NI_Sve2 }, // Sve2 { FIRST_NI_Sha3, LAST_NI_Sha3 }, // Sha3 - { NI_Illegal, NI_Illegal }, // Sm4 + { FIRST_NI_Sm4, LAST_NI_Sm4 }, // Sm4 { NI_Illegal, NI_Illegal }, // SveAes { FIRST_NI_SveSha3, LAST_NI_SveSha3 }, // SveSha3 - { NI_Illegal, NI_Illegal }, // SveSm4 + { FIRST_NI_SveSm4, LAST_NI_SveSm4 }, // SveSm4 { FIRST_NI_ArmBase_Arm64, LAST_NI_ArmBase_Arm64 }, // ArmBase_Arm64 { FIRST_NI_AdvSimd_Arm64, LAST_NI_AdvSimd_Arm64 }, // AdvSimd_Arm64 { NI_Illegal, NI_Illegal }, // Aes_Arm64 diff --git a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp index f1ee187b6e69ef..92b1be7c09f113 100644 --- a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp +++ b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp @@ -1230,8 +1230,13 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) if (HWIntrinsicInfo::SupportsContainment(intrin.id) && intrin.op2->isContained() && intrin.op2->IsVectorZero()) { + assert(!isRMW); GetEmitter()->emitIns_R_R(ins, emitSize, targetReg, op1Reg, opt); } + else if (isRMW) + { + GetEmitter()->emitIns_R_R(ins, emitSize, targetReg, op2Reg, opt); + } else { GetEmitter()->emitIns_R_R_R(ins, emitSize, targetReg, op1Reg, op2Reg, opt); diff --git a/src/coreclr/jit/hwintrinsiclistarm64.h b/src/coreclr/jit/hwintrinsiclistarm64.h index bfda592a20c866..c6436e25a33951 100644 --- a/src/coreclr/jit/hwintrinsiclistarm64.h +++ b/src/coreclr/jit/hwintrinsiclistarm64.h @@ -901,7 +901,7 @@ HARDWARE_INTRINSIC(Sha256, ScheduleUpdate1, // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // ISA Function name SIMD size NumArg EncodesExtraTypeArg Instructions Category Flags -// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} +// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // Sha3 #define FIRST_NI_Sha3 NI_Sha3_BitwiseClearXor @@ -911,6 +911,15 @@ HARDWARE_INTRINSIC(Sha3, Xor, HARDWARE_INTRINSIC(Sha3, XorRotateRight, 16, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_xar, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_HasImmediateOperand) #define LAST_NI_Sha3 NI_Sha3_XorRotateRight +// *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** +// ISA Function name SIMD size NumArg EncodesExtraTypeArg Instructions Category Flags +// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} +// *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** +// Sm4 +#define FIRST_NI_Sm4 NI_Sm4_Encode +HARDWARE_INTRINSIC(Sm4, Encode, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sm4e, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sm4, KeyUpdate, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sm4ekey, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_NoFlag) +#define LAST_NI_Sm4 NI_Sm4_KeyUpdate #endif // FEATURE_HW_INTRINSIC diff --git a/src/coreclr/jit/hwintrinsiclistarm64sve.h b/src/coreclr/jit/hwintrinsiclistarm64sve.h index c473a0edd9e0df..551ca59feb3630 100644 --- a/src/coreclr/jit/hwintrinsiclistarm64sve.h +++ b/src/coreclr/jit/hwintrinsiclistarm64sve.h @@ -537,11 +537,21 @@ HARDWARE_INTRINSIC(Sve2, XorRotateRight, // ISA Function name SIMD size NumArg Instructions Category Flags // {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** -// Sha3 +// SveSha3 #define FIRST_NI_SveSha3 NI_SveSha3_BitwiseRotateLeftBy1AndXor HARDWARE_INTRINSIC(SveSha3, BitwiseRotateLeftBy1AndXor, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_rax1, INS_sve_rax1, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen) #define LAST_NI_SveSha3 NI_SveSha3_BitwiseRotateLeftBy1AndXor +// *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** +// ISA Function name SIMD size NumArg Instructions Category Flags +// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} +// *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** +// SveSm4 +#define FIRST_NI_SveSm4 NI_SveSm4_Encode +HARDWARE_INTRINSIC(SveSm4, Encode, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_sm4e, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(SveSm4, KeyUpdate, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_sm4ekey, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable) +#define LAST_NI_SveSm4 NI_SveSm4_KeyUpdate + // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // ISA Function name SIMD size NumArg Instructions Category Flags // {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} diff --git a/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Substitutions.NoArmIntrinsics.xml b/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Substitutions.NoArmIntrinsics.xml index 1215252fbffd2a..3303fbf4dd5c61 100644 --- a/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Substitutions.NoArmIntrinsics.xml +++ b/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Substitutions.NoArmIntrinsics.xml @@ -69,11 +69,23 @@ + + + + + + + + + + + + diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index fba53e000e31bd..b3ebee4c4888bb 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -2873,10 +2873,12 @@ + + - + @@ -2887,10 +2889,12 @@ + + - + diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sm4.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sm4.PlatformNotSupported.cs new file mode 100644 index 00000000000000..171f1acf3af089 --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sm4.PlatformNotSupported.cs @@ -0,0 +1,51 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; + +namespace System.Runtime.Intrinsics.Arm +{ + /// Provides access to the ARM Sm4 hardware instructions via intrinsics. + [Intrinsic] + [CLSCompliant(false)] + public abstract class Sm4 : ArmBase + { + internal Sm4() { } + + /// Gets a value that indicates whether the APIs in this class are supported. + /// if the APIs are supported; otherwise, . + /// A value of indicates that the APIs will throw . + public static new bool IsSupported { get => IsSupported; } + + /// Provides access to the ARM Sm4 hardware instructions, that are only available to 64-bit processes, via intrinsics. + [Intrinsic] + public new abstract class Arm64 : ArmBase.Arm64 + { + internal Arm64() { } + + /// Gets a value that indicates whether the APIs in this class are supported. + /// if the APIs are supported; otherwise, . + /// A value of indicates that the APIs will throw . + public static new bool IsSupported { get => IsSupported; } + } + + + // SM4 encryption and decryption + + /// + /// uint32x4_t vsm4eq_u32(uint32x4_t a, uint32x4_t b) + /// SM4E Vd.4S,Vn.4S + /// + public static unsafe Vector128 Encode(Vector128 a, Vector128 b) { throw new PlatformNotSupportedException(); } + + // SM4 key updates + + /// + /// uint32x4_t vsm4ekeyq_u32(uint32x4_t a, uint32x4_t b) + /// SM4EKEY Vd.4S,Vn.4S,Vm.4S + /// + public static unsafe Vector128 KeyUpdate(Vector128 a, Vector128 b) { throw new PlatformNotSupportedException(); } + + } +} diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sm4.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sm4.cs new file mode 100644 index 00000000000000..16fe6325993a91 --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sm4.cs @@ -0,0 +1,51 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; + +namespace System.Runtime.Intrinsics.Arm +{ + /// Provides access to the ARM Sm4 hardware instructions via intrinsics. + [Intrinsic] + [CLSCompliant(false)] + public abstract class Sm4 : ArmBase + { + internal Sm4() { } + + /// Gets a value that indicates whether the APIs in this class are supported. + /// if the APIs are supported; otherwise, . + /// A value of indicates that the APIs will throw . + public static new bool IsSupported { get => IsSupported; } + + /// Provides access to the ARM Sm4 hardware instructions, that are only available to 64-bit processes, via intrinsics. + [Intrinsic] + public new abstract class Arm64 : ArmBase.Arm64 + { + internal Arm64() { } + + /// Gets a value that indicates whether the APIs in this class are supported. + /// if the APIs are supported; otherwise, . + /// A value of indicates that the APIs will throw . + public static new bool IsSupported { get => IsSupported; } + } + + + // SM4 encryption and decryption + + /// + /// uint32x4_t vsm4eq_u32(uint32x4_t a, uint32x4_t b) + /// SM4E Vd.4S,Vn.4S + /// + public static unsafe Vector128 Encode(Vector128 a, Vector128 b) => Encode(a, b); + + // SM4 key updates + + /// + /// uint32x4_t vsm4ekeyq_u32(uint32x4_t a, uint32x4_t b) + /// SM4EKEY Vd.4S,Vn.4S,Vm.4S + /// + public static unsafe Vector128 KeyUpdate(Vector128 a, Vector128 b) => KeyUpdate(a, b); + + } +} diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/SveSm4.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/SveSm4.PlatformNotSupported.cs new file mode 100644 index 00000000000000..0d5b15a94f4bf6 --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/SveSm4.PlatformNotSupported.cs @@ -0,0 +1,54 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics.CodeAnalysis; +using System.Numerics; +using System.Runtime.CompilerServices; + +namespace System.Runtime.Intrinsics.Arm +{ + /// Provides access to the ARM SveSm4 hardware instructions via intrinsics. + [Intrinsic] + [CLSCompliant(false)] + [Experimental(Experimentals.ArmSveDiagId, UrlFormat = Experimentals.SharedUrlFormat)] + public abstract class SveSm4 : ArmBase + { + internal SveSm4() { } + + /// Gets a value that indicates whether the APIs in this class are supported. + /// if the APIs are supported; otherwise, . + /// A value of indicates that the APIs will throw . + public static new bool IsSupported { get => IsSupported; } + + /// Provides access to the ARM SveSm4 hardware instructions, that are only available to 64-bit processes, via intrinsics. + [Intrinsic] + public new abstract class Arm64 : ArmBase.Arm64 + { + internal Arm64() { } + + /// Gets a value that indicates whether the APIs in this class are supported. + /// if the APIs are supported; otherwise, . + /// A value of indicates that the APIs will throw . + public static new bool IsSupported { get => IsSupported; } + } + + + // SM4 encryption and decryption + + /// + /// svuint32_t svsm4e[_u32](svuint32_t op1, svuint32_t op2) + /// SM4E Ztied1.S, Ztied1.S, Zop2.S + /// + public static unsafe Vector Encode(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + + // SM4 key updates + + /// + /// svuint32_t svsm4ekey[_u32](svuint32_t op1, svuint32_t op2) + /// SM4EKEY Zresult.S, Zop1.S, Zop2.S + /// + public static unsafe Vector KeyUpdate(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + } +} diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/SveSm4.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/SveSm4.cs new file mode 100644 index 00000000000000..269f9c1eab3c76 --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/SveSm4.cs @@ -0,0 +1,54 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics.CodeAnalysis; +using System.Numerics; +using System.Runtime.CompilerServices; + +namespace System.Runtime.Intrinsics.Arm +{ + /// Provides access to the ARM SveSm4 hardware instructions via intrinsics. + [Intrinsic] + [CLSCompliant(false)] + [Experimental(Experimentals.ArmSveDiagId, UrlFormat = Experimentals.SharedUrlFormat)] + public abstract class SveSm4 : ArmBase + { + internal SveSm4() { } + + /// Gets a value that indicates whether the APIs in this class are supported. + /// if the APIs are supported; otherwise, . + /// A value of indicates that the APIs will throw . + public static new bool IsSupported { get => IsSupported; } + + /// Provides access to the ARM SveSm4 hardware instructions, that are only available to 64-bit processes, via intrinsics. + [Intrinsic] + public new abstract class Arm64 : ArmBase.Arm64 + { + internal Arm64() { } + + /// Gets a value that indicates whether the APIs in this class are supported. + /// if the APIs are supported; otherwise, . + /// A value of indicates that the APIs will throw . + public static new bool IsSupported { get => IsSupported; } + } + + + // SM4 encryption and decryption + + /// + /// svuint32_t svsm4e[_u32](svuint32_t op1, svuint32_t op2) + /// SM4E Ztied1.S, Ztied1.S, Zop2.S + /// + public static unsafe Vector Encode(Vector left, Vector right) => Encode(left, right); + + + // SM4 key updates + + /// + /// svuint32_t svsm4ekey[_u32](svuint32_t op1, svuint32_t op2) + /// SM4EKEY Zresult.S, Zop1.S, Zop2.S + /// + public static unsafe Vector KeyUpdate(Vector left, Vector right) => KeyUpdate(left, right); + + } +} diff --git a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs index fc60e6690163a1..fedac8ed9185d6 100644 --- a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs +++ b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs @@ -4700,6 +4700,20 @@ internal Arm64() { } } } [System.CLSCompliantAttribute(false)] + public abstract partial class Sm4 : System.Runtime.Intrinsics.Arm.ArmBase + { + internal Sm4() { } + public static new bool IsSupported { get { throw null; } } + + public static Vector128 Encode(System.Runtime.Intrinsics.Vector128 a, System.Runtime.Intrinsics.Vector128 b) { throw null; } + public static Vector128 KeyUpdate(System.Runtime.Intrinsics.Vector128 a, System.Runtime.Intrinsics.Vector128 b) { throw null; } + public new abstract partial class Arm64 : System.Runtime.Intrinsics.Arm.ArmBase.Arm64 + { + internal Arm64() { } + public static new bool IsSupported { get { throw null; } } + } + } + [System.CLSCompliantAttribute(false)] [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] public abstract partial class Sve : System.Runtime.Intrinsics.Arm.AdvSimd { @@ -7309,6 +7323,20 @@ internal Arm64() { } public static new bool IsSupported { get { throw null; } } } } + [System.CLSCompliantAttribute(false)] + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] + public abstract partial class SveSm4 : System.Runtime.Intrinsics.Arm.ArmBase + { + internal SveSm4() { } + public static new bool IsSupported { get { throw null; } } + public static System.Numerics.Vector Encode(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector KeyUpdate(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public new abstract partial class Arm64 : System.Runtime.Intrinsics.Arm.ArmBase.Arm64 + { + internal Arm64() { } + public static new bool IsSupported { get { throw null; } } + } + } public enum SveMaskPattern : byte { diff --git a/src/tests/Common/GenerateHWIntrinsicTests/Arm/AdvSimdTests.cs b/src/tests/Common/GenerateHWIntrinsicTests/Arm/AdvSimdTests.cs index 723d3aa106a330..f9772f06375f96 100644 --- a/src/tests/Common/GenerateHWIntrinsicTests/Arm/AdvSimdTests.cs +++ b/src/tests/Common/GenerateHWIntrinsicTests/Arm/AdvSimdTests.cs @@ -2762,4 +2762,11 @@ static class AdvSimdTests (Templates.VecImmBinOpTest, new Dictionary { ["TestName"] = "Sha3_XorRotateRight_ulong", ["Method"] = "XorRotateRight", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Imm"] = "62", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["LargestVectorSize"] = "16", ["ValidateIterResult"] = "result[i] != Helpers.XorRotateRight(firstOp[i], secondOp[i], Imm)" }), ]); + + + public static TestGroup Sm4Inputs = new TestGroup(Isa:"Sm4", LoadIsa:"AdvSimd", + [ + (Templates.VecBinOpTest, new Dictionary { ["TestName"] = "Sm4_Encode_uint", ["Method"] = "Encode", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["LargestVectorSize"] = "16", ["ValidateIterResult"] = "result[i] != Helpers.Encode(i, left, right)",}), + (Templates.VecBinOpTest, new Dictionary { ["TestName"] = "Sm4_KeyUpdate_uint", ["Method"] = "KeyUpdate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["LargestVectorSize"] = "16", ["ValidateIterResult"] = "result[i] != Helpers.KeyUpdate(i, left, right)",}), + ]); } diff --git a/src/tests/Common/GenerateHWIntrinsicTests/Arm/SveTests.cs b/src/tests/Common/GenerateHWIntrinsicTests/Arm/SveTests.cs index e03cf691540f85..cdbd770f5d78b6 100644 --- a/src/tests/Common/GenerateHWIntrinsicTests/Arm/SveTests.cs +++ b/src/tests/Common/GenerateHWIntrinsicTests/Arm/SveTests.cs @@ -1755,4 +1755,10 @@ static class SveTests (Templates.SveVecBinOpTest, new Dictionary { ["TestName"] = "SveSha3_BitwiseRotateLeftBy1AndXor_long", ["Method"] = "BitwiseRotateLeftBy1AndXor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result[i] != Helpers.BitwiseRotateLeftBy1AndXor(left[i], right[i])", ["GetIterResult"] = "Helpers.BitwiseRotateLeftBy1AndXor(left[i], right[i])"}), (Templates.SveVecBinOpTest, new Dictionary { ["TestName"] = "SveSha3_BitwiseRotateLeftBy1AndXor_ulong", ["Method"] = "BitwiseRotateLeftBy1AndXor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "result[i] != Helpers.BitwiseRotateLeftBy1AndXor(left[i], right[i])", ["GetIterResult"] = "Helpers.BitwiseRotateLeftBy1AndXor(left[i], right[i])"}), ]); + + public static TestGroup SveSm4Inputs = new TestGroup(Isa:"SveSm4", LoadIsa:"Sve", + [ + (Templates.SveVecBinOpTest, new Dictionary { ["TestName"] = "SveSm4_Encode_uint", ["Method"] = "Encode", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result[i] != Helpers.Encode(i, left, right)", ["GetIterResult"] = "Helpers.Encode(i, left, right)"}), + (Templates.SveVecBinOpTest, new Dictionary { ["TestName"] = "SveSm4_KeyUpdate_uint", ["Method"] = "KeyUpdate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result[i] != Helpers.KeyUpdate(i, left, right)", ["GetIterResult"] = "Helpers.KeyUpdate(i, left, right)"}), + ]); } diff --git a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs index 5af6607da77caa..c91238261d9490 100644 --- a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs +++ b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs @@ -101,13 +101,15 @@ static void Main(string[] args) ProcessInputs(AdvSimdTests.Rdm_Arm64Inputs); ProcessInputs(AdvSimdTests.Sha1Inputs); ProcessInputs(AdvSimdTests.Sha256Inputs); + ProcessInputs(AdvSimdTests.Sha3Inputs); + ProcessInputs(AdvSimdTests.Sm4Inputs); ProcessInputs(BaseTests.ArmBaseInputs); ProcessInputs(BaseTests.ArmBase_Arm64Inputs); ProcessInputs(BaseTests.Crc32Inputs); ProcessInputs(SveTests.SveInputs); ProcessInputs(Sve2Tests.Sve2Inputs); - ProcessInputs(AdvSimdTests.Sha3Inputs); ProcessInputs(SveTests.SveSha3Inputs); + ProcessInputs(SveTests.SveSm4Inputs); void ProcessInputs(TestGroup testGroup) { diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs index 6ee5ba237ff01d..51640a474d8590 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs @@ -8530,5 +8530,104 @@ public static ulong BitwiseRotateLeftBy1AndXor(ulong op1, ulong op2) public static long BitwiseRotateLeftBy1AndXor(long op1, long op2) => op1 ^ unchecked((long)RotateLeft1((ulong)op2)); + + private static readonly byte[] SBox = + { + 0xd6,0x90,0xe9,0xfe,0xcc,0xe1,0x3d,0xb7,0x16,0xb6,0x14,0xc2,0x28,0xfb,0x2c,0x05, + 0x2b,0x67,0x9a,0x76,0x2a,0xbe,0x04,0xc3,0xaa,0x44,0x13,0x26,0x49,0x86,0x06,0x99, + 0x9c,0x42,0x50,0xf4,0x91,0xef,0x98,0x7a,0x33,0x54,0x0b,0x43,0xed,0xcf,0xac,0x62, + 0xe4,0xb3,0x1c,0xa9,0xc9,0x08,0xe8,0x95,0x80,0xdf,0x94,0xfa,0x75,0x8f,0x3f,0xa6, + 0x47,0x07,0xa7,0xfc,0xf3,0x73,0x17,0xba,0x83,0x59,0x3c,0x19,0xe6,0x85,0x4f,0xa8, + 0x68,0x6b,0x81,0xb2,0x71,0x64,0xda,0x8b,0xf8,0xeb,0x0f,0x4b,0x70,0x56,0x9d,0x35, + 0x1e,0x24,0x0e,0x5e,0x63,0x58,0xd1,0xa2,0x25,0x22,0x7c,0x3b,0x01,0x21,0x78,0x87, + 0xd4,0x00,0x46,0x57,0x9f,0xd3,0x27,0x52,0x4c,0x36,0x02,0xe7,0xa0,0xc4,0xc8,0x9e, + 0xea,0xbf,0x8a,0xd2,0x40,0xc7,0x38,0xb5,0xa3,0xf7,0xf2,0xce,0xf9,0x61,0x15,0xa1, + 0xe0,0xae,0x5d,0xa4,0x9b,0x34,0x1a,0x55,0xad,0x93,0x32,0x30,0xf5,0x8c,0xb1,0xe3, + 0x1d,0xf6,0xe2,0x2e,0x82,0x66,0xca,0x60,0xc0,0x29,0x23,0xab,0x0d,0x53,0x4e,0x6f, + 0xd5,0xdb,0x37,0x45,0xde,0xfd,0x8e,0x2f,0x03,0xff,0x6a,0x72,0x6d,0x6c,0x5b,0x51, + 0x8d,0x1b,0xaf,0x92,0xbb,0xdd,0xbc,0x7f,0x11,0xd9,0x5c,0x41,0x1f,0x10,0x5a,0xd8, + 0x0a,0xc1,0x31,0x88,0xa5,0xcd,0x7b,0xbd,0x2d,0x74,0xd0,0x12,0xb8,0xe5,0xb4,0xb0, + 0x89,0x69,0x97,0x4a,0x0c,0x96,0x77,0x7e,0x65,0xb9,0xf1,0x09,0xc5,0x6e,0xc6,0x84, + 0x18,0xf0,0x7d,0xec,0x3a,0xdc,0x4d,0x20,0x79,0xee,0x5f,0x3e,0xd7,0xcb,0x39,0x48 + }; + + private static uint Tau(uint x) + { + return (uint)(SBox[x & 0xff] + | (SBox[(x >> 8) & 0xff] << 8) + | (SBox[(x >> 16) & 0xff] << 16) + | (SBox[(x >> 24) & 0xff] << 24)); + } + + public static uint Encode(int index, uint[] data, uint[] roundKeys) + { + uint[] result = new uint[data.Length]; + + for (int s = 0; s < data.Length; s += 4) + { + uint x0 = data[s + 0]; + uint x1 = data[s + 1]; + uint x2 = data[s + 2]; + uint x3 = data[s + 3]; + + for (int i = 0; i < 4; i++) + { + uint t = x1 ^ x2 ^ x3 ^ roundKeys[s + i]; + t = Tau(t); + t ^= BitOperations.RotateLeft(t, 2) + ^ BitOperations.RotateLeft(t, 10) + ^ BitOperations.RotateLeft(t, 18) + ^ BitOperations.RotateLeft(t, 24); + t ^= x0; + + x0 = x1; + x1 = x2; + x2 = x3; + x3 = t; + } + + result[s + 0] = x0; + result[s + 1] = x1; + result[s + 2] = x2; + result[s + 3] = x3; + } + + return result[index]; + } + + public static uint KeyUpdate(int index, uint[] key, uint[] constants) + { + uint[] result = new uint[key.Length]; + + for (int s = 0; s < key.Length; s += 4) + { + uint k0 = key[s + 0]; + uint k1 = key[s + 1]; + uint k2 = key[s + 2]; + uint k3 = key[s + 3]; + + for (int i = 0; i < 4; i++) + { + uint t = k1 ^ k2 ^ k3 ^ constants[s + i]; + t = Tau(t); + t ^= BitOperations.RotateLeft(t, 13) + ^ BitOperations.RotateLeft(t, 23); + t ^= k0; + + k0 = k1; + k1 = k2; + k2 = k3; + k3 = t; + } + + result[s + 0] = k0; + result[s + 1] = k1; + result[s + 2] = k2; + result[s + 3] = k3; + } + + return result[index]; + } + } } diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Program.cs b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Program.cs index 378f0d6f2b0cbe..1c95c5ac4f23fb 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Program.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Program.cs @@ -21,10 +21,12 @@ public static void PrintSupportedIsa() TestLibrary.TestFramework.LogInformation($" Rdm: {Rdm.IsSupported}"); TestLibrary.TestFramework.LogInformation($" Sha1: {Sha1.IsSupported}"); TestLibrary.TestFramework.LogInformation($" Sha256: {Sha256.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" Sha3: {Sha3.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" Sm4: {Sm4.IsSupported}"); TestLibrary.TestFramework.LogInformation($" Sve: {Sve.IsSupported}"); TestLibrary.TestFramework.LogInformation($" Sve2: {Sve2.IsSupported}"); - TestLibrary.TestFramework.LogInformation($" Sha3: {Sha3.IsSupported}"); TestLibrary.TestFramework.LogInformation($" SveSha3: {SveSha3.IsSupported}"); + TestLibrary.TestFramework.LogInformation($" SveSm4: {SveSm4.IsSupported}"); TestLibrary.TestFramework.LogInformation(string.Empty); } } diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Sm4/Program.Sm4.cs b/src/tests/JIT/HardwareIntrinsics/Arm/Sm4/Program.Sm4.cs new file mode 100644 index 00000000000000..74cac244122f1e --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Sm4/Program.Sm4.cs @@ -0,0 +1,16 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; + +namespace JIT.HardwareIntrinsics.Arm._Sm4 +{ + public static partial class Program + { + static Program() + { + JIT.HardwareIntrinsics.Arm.Program.PrintSupportedIsa(); + } + } +} diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Sm4/Sm4_r.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/Sm4/Sm4_r.csproj new file mode 100644 index 00000000000000..b5d2e8fa7af42e --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Sm4/Sm4_r.csproj @@ -0,0 +1,14 @@ + + + true + + + Embedded + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Sm4/Sm4_ro.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/Sm4/Sm4_ro.csproj new file mode 100644 index 00000000000000..c53bf392866175 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Sm4/Sm4_ro.csproj @@ -0,0 +1,14 @@ + + + true + + + Embedded + True + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/SveSm4/Program.SveSm4.cs b/src/tests/JIT/HardwareIntrinsics/Arm/SveSm4/Program.SveSm4.cs new file mode 100644 index 00000000000000..7b229e33e7571e --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/SveSm4/Program.SveSm4.cs @@ -0,0 +1,16 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; + +namespace JIT.HardwareIntrinsics.Arm._SveSm4 +{ + public static partial class Program + { + static Program() + { + JIT.HardwareIntrinsics.Arm.Program.PrintSupportedIsa(); + } + } +} diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/SveSm4/SveSm4_r.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/SveSm4/SveSm4_r.csproj new file mode 100644 index 00000000000000..e120218bcf26d4 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/SveSm4/SveSm4_r.csproj @@ -0,0 +1,14 @@ + + + true + + + Embedded + + + + + + + + diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/SveSm4/SveSm4_ro.csproj b/src/tests/JIT/HardwareIntrinsics/Arm/SveSm4/SveSm4_ro.csproj new file mode 100644 index 00000000000000..6257d8b1c611c6 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/SveSm4/SveSm4_ro.csproj @@ -0,0 +1,14 @@ + + + true + + + Embedded + True + + + + + + + From e8a14fde99a769f429b8064dd5530f1161923925 Mon Sep 17 00:00:00 2001 From: Alan Hayward Date: Tue, 30 Jun 2026 17:28:41 +0100 Subject: [PATCH 02/11] fix IsSupported --- .../System/Runtime/Intrinsics/Arm/Sm4.PlatformNotSupported.cs | 4 +--- .../Runtime/Intrinsics/Arm/SveSm4.PlatformNotSupported.cs | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sm4.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sm4.PlatformNotSupported.cs index 171f1acf3af089..c5c8004bade4e7 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sm4.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sm4.PlatformNotSupported.cs @@ -7,7 +7,6 @@ namespace System.Runtime.Intrinsics.Arm { /// Provides access to the ARM Sm4 hardware instructions via intrinsics. - [Intrinsic] [CLSCompliant(false)] public abstract class Sm4 : ArmBase { @@ -16,10 +15,9 @@ internal Sm4() { } /// Gets a value that indicates whether the APIs in this class are supported. /// if the APIs are supported; otherwise, . /// A value of indicates that the APIs will throw . - public static new bool IsSupported { get => IsSupported; } + public static new bool IsSupported { [Intrinsic] get => false; } /// Provides access to the ARM Sm4 hardware instructions, that are only available to 64-bit processes, via intrinsics. - [Intrinsic] public new abstract class Arm64 : ArmBase.Arm64 { internal Arm64() { } diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/SveSm4.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/SveSm4.PlatformNotSupported.cs index 0d5b15a94f4bf6..25d4cd31549c04 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/SveSm4.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/SveSm4.PlatformNotSupported.cs @@ -8,7 +8,6 @@ namespace System.Runtime.Intrinsics.Arm { /// Provides access to the ARM SveSm4 hardware instructions via intrinsics. - [Intrinsic] [CLSCompliant(false)] [Experimental(Experimentals.ArmSveDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public abstract class SveSm4 : ArmBase @@ -18,10 +17,9 @@ internal SveSm4() { } /// Gets a value that indicates whether the APIs in this class are supported. /// if the APIs are supported; otherwise, . /// A value of indicates that the APIs will throw . - public static new bool IsSupported { get => IsSupported; } + public static new bool IsSupported { [Intrinsic] get => false; } /// Provides access to the ARM SveSm4 hardware instructions, that are only available to 64-bit processes, via intrinsics. - [Intrinsic] public new abstract class Arm64 : ArmBase.Arm64 { internal Arm64() { } From ffcce4ea28c2aa9ceca4408d879e354a7f2de926 Mon Sep 17 00:00:00 2001 From: Alan Hayward Date: Tue, 30 Jun 2026 17:30:47 +0100 Subject: [PATCH 03/11] fix System.Runtime.Intrinsics.cs --- .../ref/System.Runtime.Intrinsics.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs index fedac8ed9185d6..0bf5c5e3291547 100644 --- a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs +++ b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs @@ -4705,8 +4705,8 @@ public abstract partial class Sm4 : System.Runtime.Intrinsics.Arm.ArmBase internal Sm4() { } public static new bool IsSupported { get { throw null; } } - public static Vector128 Encode(System.Runtime.Intrinsics.Vector128 a, System.Runtime.Intrinsics.Vector128 b) { throw null; } - public static Vector128 KeyUpdate(System.Runtime.Intrinsics.Vector128 a, System.Runtime.Intrinsics.Vector128 b) { throw null; } + public static System.Runtime.Intrinsics.Vector128 Encode(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 roundKeys) { throw null; } + public static System.Runtime.Intrinsics.Vector128 KeyUpdate(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 constant) { throw null; } public new abstract partial class Arm64 : System.Runtime.Intrinsics.Arm.ArmBase.Arm64 { internal Arm64() { } @@ -7329,8 +7329,8 @@ public abstract partial class SveSm4 : System.Runtime.Intrinsics.Arm.ArmBase { internal SveSm4() { } public static new bool IsSupported { get { throw null; } } - public static System.Numerics.Vector Encode(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector KeyUpdate(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Encode(System.Numerics.Vector value, System.Numerics.Vector roundKeys) { throw null; } + public static System.Numerics.Vector KeyUpdate(System.Numerics.Vector value, System.Numerics.Vector constant) { throw null; } public new abstract partial class Arm64 : System.Runtime.Intrinsics.Arm.ArmBase.Arm64 { internal Arm64() { } From 6a3bdb2fc42e2a42f329ebdd29af9c6a66c1c71e Mon Sep 17 00:00:00 2001 From: Alan Hayward Date: Tue, 30 Jun 2026 17:36:22 +0100 Subject: [PATCH 04/11] fix variable names --- .../System/Runtime/Intrinsics/Arm/Sm4.PlatformNotSupported.cs | 4 ++-- .../src/System/Runtime/Intrinsics/Arm/Sm4.cs | 4 ++-- .../Runtime/Intrinsics/Arm/SveSm4.PlatformNotSupported.cs | 4 ++-- .../src/System/Runtime/Intrinsics/Arm/SveSm4.cs | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sm4.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sm4.PlatformNotSupported.cs index c5c8004bade4e7..986654cfc37b2f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sm4.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sm4.PlatformNotSupported.cs @@ -35,7 +35,7 @@ internal Arm64() { } /// uint32x4_t vsm4eq_u32(uint32x4_t a, uint32x4_t b) /// SM4E Vd.4S,Vn.4S /// - public static unsafe Vector128 Encode(Vector128 a, Vector128 b) { throw new PlatformNotSupportedException(); } + public static unsafe Vector128 Encode(Vector128 value, Vector128 roundKeys) { throw new PlatformNotSupportedException(); } // SM4 key updates @@ -43,7 +43,7 @@ internal Arm64() { } /// uint32x4_t vsm4ekeyq_u32(uint32x4_t a, uint32x4_t b) /// SM4EKEY Vd.4S,Vn.4S,Vm.4S /// - public static unsafe Vector128 KeyUpdate(Vector128 a, Vector128 b) { throw new PlatformNotSupportedException(); } + public static unsafe Vector128 KeyUpdate(Vector128 value, Vector128 constant) { throw new PlatformNotSupportedException(); } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sm4.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sm4.cs index 16fe6325993a91..b69a44c48dea88 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sm4.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sm4.cs @@ -37,7 +37,7 @@ internal Arm64() { } /// uint32x4_t vsm4eq_u32(uint32x4_t a, uint32x4_t b) /// SM4E Vd.4S,Vn.4S /// - public static unsafe Vector128 Encode(Vector128 a, Vector128 b) => Encode(a, b); + public static unsafe Vector128 Encode(Vector128 value, Vector128 roundKeys) => Encode(a, b); // SM4 key updates @@ -45,7 +45,7 @@ internal Arm64() { } /// uint32x4_t vsm4ekeyq_u32(uint32x4_t a, uint32x4_t b) /// SM4EKEY Vd.4S,Vn.4S,Vm.4S /// - public static unsafe Vector128 KeyUpdate(Vector128 a, Vector128 b) => KeyUpdate(a, b); + public static unsafe Vector128 KeyUpdate(Vector128 value, Vector128 constant) => KeyUpdate(a, b); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/SveSm4.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/SveSm4.PlatformNotSupported.cs index 25d4cd31549c04..79e1a18bf56c73 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/SveSm4.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/SveSm4.PlatformNotSupported.cs @@ -37,7 +37,7 @@ internal Arm64() { } /// svuint32_t svsm4e[_u32](svuint32_t op1, svuint32_t op2) /// SM4E Ztied1.S, Ztied1.S, Zop2.S /// - public static unsafe Vector Encode(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + public static unsafe Vector Encode(Vector value, Vector roundKeys) { throw new PlatformNotSupportedException(); } // SM4 key updates @@ -46,7 +46,7 @@ internal Arm64() { } /// svuint32_t svsm4ekey[_u32](svuint32_t op1, svuint32_t op2) /// SM4EKEY Zresult.S, Zop1.S, Zop2.S /// - public static unsafe Vector KeyUpdate(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + public static unsafe Vector KeyUpdate(Vector value, Vector constant) { throw new PlatformNotSupportedException(); } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/SveSm4.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/SveSm4.cs index 269f9c1eab3c76..d39d83457fe68c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/SveSm4.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/SveSm4.cs @@ -39,7 +39,7 @@ internal Arm64() { } /// svuint32_t svsm4e[_u32](svuint32_t op1, svuint32_t op2) /// SM4E Ztied1.S, Ztied1.S, Zop2.S /// - public static unsafe Vector Encode(Vector left, Vector right) => Encode(left, right); + public static unsafe Vector Encode(Vector value, Vector roundKeys) => Encode(left, right); // SM4 key updates @@ -48,7 +48,7 @@ internal Arm64() { } /// svuint32_t svsm4ekey[_u32](svuint32_t op1, svuint32_t op2) /// SM4EKEY Zresult.S, Zop1.S, Zop2.S /// - public static unsafe Vector KeyUpdate(Vector left, Vector right) => KeyUpdate(left, right); + public static unsafe Vector KeyUpdate(Vector value, Vector constant) => KeyUpdate(left, right); } } From e06595372a6a40528ee25382dff2c9fc1bc62323 Mon Sep 17 00:00:00 2001 From: Alan Hayward Date: Wed, 1 Jul 2026 09:33:33 +0100 Subject: [PATCH 05/11] fix variable names --- .../src/System/Runtime/Intrinsics/Arm/Sm4.cs | 4 ++-- .../src/System/Runtime/Intrinsics/Arm/SveSm4.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sm4.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sm4.cs index b69a44c48dea88..c2ef24e5edc5a1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sm4.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sm4.cs @@ -37,7 +37,7 @@ internal Arm64() { } /// uint32x4_t vsm4eq_u32(uint32x4_t a, uint32x4_t b) /// SM4E Vd.4S,Vn.4S /// - public static unsafe Vector128 Encode(Vector128 value, Vector128 roundKeys) => Encode(a, b); + public static unsafe Vector128 Encode(Vector128 value, Vector128 roundKeys) => Encode(value, roundKeys); // SM4 key updates @@ -45,7 +45,7 @@ internal Arm64() { } /// uint32x4_t vsm4ekeyq_u32(uint32x4_t a, uint32x4_t b) /// SM4EKEY Vd.4S,Vn.4S,Vm.4S /// - public static unsafe Vector128 KeyUpdate(Vector128 value, Vector128 constant) => KeyUpdate(a, b); + public static unsafe Vector128 KeyUpdate(Vector128 value, Vector128 constant) => KeyUpdate(value, constant); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/SveSm4.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/SveSm4.cs index d39d83457fe68c..956c526201a46d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/SveSm4.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/SveSm4.cs @@ -39,7 +39,7 @@ internal Arm64() { } /// svuint32_t svsm4e[_u32](svuint32_t op1, svuint32_t op2) /// SM4E Ztied1.S, Ztied1.S, Zop2.S /// - public static unsafe Vector Encode(Vector value, Vector roundKeys) => Encode(left, right); + public static unsafe Vector Encode(Vector value, Vector roundKeys) => Encode(value, roundKeys); // SM4 key updates @@ -48,7 +48,7 @@ internal Arm64() { } /// svuint32_t svsm4ekey[_u32](svuint32_t op1, svuint32_t op2) /// SM4EKEY Zresult.S, Zop1.S, Zop2.S /// - public static unsafe Vector KeyUpdate(Vector value, Vector constant) => KeyUpdate(left, right); + public static unsafe Vector KeyUpdate(Vector value, Vector constant) => KeyUpdate(value, constant); } } From 69ac7b6a5ef87f2e3a2472e2d744a134e88cf275 Mon Sep 17 00:00:00 2001 From: Alan Hayward Date: Wed, 1 Jul 2026 10:21:11 +0100 Subject: [PATCH 06/11] Do the mov inside emit --- src/coreclr/jit/emitarm64sve.cpp | 3 +++ src/coreclr/jit/hwintrinsiccodegenarm64.cpp | 4 ---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/coreclr/jit/emitarm64sve.cpp b/src/coreclr/jit/emitarm64sve.cpp index a2eab684ee8000..4ba4d0c3181d36 100644 --- a/src/coreclr/jit/emitarm64sve.cpp +++ b/src/coreclr/jit/emitarm64sve.cpp @@ -3016,6 +3016,9 @@ void emitter::emitInsSve_R_R_R(instruction ins, emitInsSve_R_R(ins, attr, reg1, reg3, opt, sopt); return; + case INS_sve_aesd: + case INS_sve_aese: + case INS_sve_sm4e: case INS_sve_sqxtnt: case INS_sve_uqxtnt: case INS_sve_sqxtunt: diff --git a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp index c0a68feed05e1f..98d075b4a2723b 100644 --- a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp +++ b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp @@ -1139,10 +1139,6 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) assert(!isRMW); GetEmitter()->emitIns_R_R(ins, emitSize, targetReg, op1Reg, opt); } - else if (isRMW) - { - GetEmitter()->emitIns_R_R(ins, emitSize, targetReg, op2Reg, opt); - } else { GetEmitter()->emitIns_R_R_R(ins, emitSize, targetReg, op1Reg, op2Reg, opt); From 348c2e958df5e17c774639904f75f6bac888ee86 Mon Sep 17 00:00:00 2001 From: Alan Hayward Date: Wed, 1 Jul 2026 12:26:48 +0100 Subject: [PATCH 07/11] Move helpers into subclass --- .../Arm/AdvSimdTests.cs | 4 +- .../GenerateHWIntrinsicTests/Arm/SveTests.cs | 4 +- .../HardwareIntrinsics/Arm/Shared/Helpers.cs | 173 +++++++++--------- 3 files changed, 92 insertions(+), 89 deletions(-) diff --git a/src/tests/Common/GenerateHWIntrinsicTests/Arm/AdvSimdTests.cs b/src/tests/Common/GenerateHWIntrinsicTests/Arm/AdvSimdTests.cs index f9772f06375f96..fac7fe54585037 100644 --- a/src/tests/Common/GenerateHWIntrinsicTests/Arm/AdvSimdTests.cs +++ b/src/tests/Common/GenerateHWIntrinsicTests/Arm/AdvSimdTests.cs @@ -2766,7 +2766,7 @@ static class AdvSimdTests public static TestGroup Sm4Inputs = new TestGroup(Isa:"Sm4", LoadIsa:"AdvSimd", [ - (Templates.VecBinOpTest, new Dictionary { ["TestName"] = "Sm4_Encode_uint", ["Method"] = "Encode", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["LargestVectorSize"] = "16", ["ValidateIterResult"] = "result[i] != Helpers.Encode(i, left, right)",}), - (Templates.VecBinOpTest, new Dictionary { ["TestName"] = "Sm4_KeyUpdate_uint", ["Method"] = "KeyUpdate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["LargestVectorSize"] = "16", ["ValidateIterResult"] = "result[i] != Helpers.KeyUpdate(i, left, right)",}), + (Templates.VecBinOpTest, new Dictionary { ["TestName"] = "Sm4_Encode_uint", ["Method"] = "Encode", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["LargestVectorSize"] = "16", ["ValidateIterResult"] = "result[i] != Helpers.Sm4.Encode(i, left, right)",}), + (Templates.VecBinOpTest, new Dictionary { ["TestName"] = "Sm4_KeyUpdate_uint", ["Method"] = "KeyUpdate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["LargestVectorSize"] = "16", ["ValidateIterResult"] = "result[i] != Helpers.Sm4.KeyUpdate(i, left, right)",}), ]); } diff --git a/src/tests/Common/GenerateHWIntrinsicTests/Arm/SveTests.cs b/src/tests/Common/GenerateHWIntrinsicTests/Arm/SveTests.cs index cdbd770f5d78b6..c3c7cabb1cb95f 100644 --- a/src/tests/Common/GenerateHWIntrinsicTests/Arm/SveTests.cs +++ b/src/tests/Common/GenerateHWIntrinsicTests/Arm/SveTests.cs @@ -1758,7 +1758,7 @@ static class SveTests public static TestGroup SveSm4Inputs = new TestGroup(Isa:"SveSm4", LoadIsa:"Sve", [ - (Templates.SveVecBinOpTest, new Dictionary { ["TestName"] = "SveSm4_Encode_uint", ["Method"] = "Encode", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result[i] != Helpers.Encode(i, left, right)", ["GetIterResult"] = "Helpers.Encode(i, left, right)"}), - (Templates.SveVecBinOpTest, new Dictionary { ["TestName"] = "SveSm4_KeyUpdate_uint", ["Method"] = "KeyUpdate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result[i] != Helpers.KeyUpdate(i, left, right)", ["GetIterResult"] = "Helpers.KeyUpdate(i, left, right)"}), + (Templates.SveVecBinOpTest, new Dictionary { ["TestName"] = "SveSm4_Encode_uint", ["Method"] = "Encode", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result[i] != Helpers.Sm4.Encode(i, left, right)", ["GetIterResult"] = "Helpers.Sm4.Encode(i, left, right)"}), + (Templates.SveVecBinOpTest, new Dictionary { ["TestName"] = "SveSm4_KeyUpdate_uint", ["Method"] = "KeyUpdate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result[i] != Helpers.Sm4.KeyUpdate(i, left, right)", ["GetIterResult"] = "Helpers.Sm4.KeyUpdate(i, left, right)"}), ]); } diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs index 51640a474d8590..8a57b5428de434 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs @@ -8531,102 +8531,105 @@ public static ulong BitwiseRotateLeftBy1AndXor(ulong op1, ulong op2) public static long BitwiseRotateLeftBy1AndXor(long op1, long op2) => op1 ^ unchecked((long)RotateLeft1((ulong)op2)); - private static readonly byte[] SBox = - { - 0xd6,0x90,0xe9,0xfe,0xcc,0xe1,0x3d,0xb7,0x16,0xb6,0x14,0xc2,0x28,0xfb,0x2c,0x05, - 0x2b,0x67,0x9a,0x76,0x2a,0xbe,0x04,0xc3,0xaa,0x44,0x13,0x26,0x49,0x86,0x06,0x99, - 0x9c,0x42,0x50,0xf4,0x91,0xef,0x98,0x7a,0x33,0x54,0x0b,0x43,0xed,0xcf,0xac,0x62, - 0xe4,0xb3,0x1c,0xa9,0xc9,0x08,0xe8,0x95,0x80,0xdf,0x94,0xfa,0x75,0x8f,0x3f,0xa6, - 0x47,0x07,0xa7,0xfc,0xf3,0x73,0x17,0xba,0x83,0x59,0x3c,0x19,0xe6,0x85,0x4f,0xa8, - 0x68,0x6b,0x81,0xb2,0x71,0x64,0xda,0x8b,0xf8,0xeb,0x0f,0x4b,0x70,0x56,0x9d,0x35, - 0x1e,0x24,0x0e,0x5e,0x63,0x58,0xd1,0xa2,0x25,0x22,0x7c,0x3b,0x01,0x21,0x78,0x87, - 0xd4,0x00,0x46,0x57,0x9f,0xd3,0x27,0x52,0x4c,0x36,0x02,0xe7,0xa0,0xc4,0xc8,0x9e, - 0xea,0xbf,0x8a,0xd2,0x40,0xc7,0x38,0xb5,0xa3,0xf7,0xf2,0xce,0xf9,0x61,0x15,0xa1, - 0xe0,0xae,0x5d,0xa4,0x9b,0x34,0x1a,0x55,0xad,0x93,0x32,0x30,0xf5,0x8c,0xb1,0xe3, - 0x1d,0xf6,0xe2,0x2e,0x82,0x66,0xca,0x60,0xc0,0x29,0x23,0xab,0x0d,0x53,0x4e,0x6f, - 0xd5,0xdb,0x37,0x45,0xde,0xfd,0x8e,0x2f,0x03,0xff,0x6a,0x72,0x6d,0x6c,0x5b,0x51, - 0x8d,0x1b,0xaf,0x92,0xbb,0xdd,0xbc,0x7f,0x11,0xd9,0x5c,0x41,0x1f,0x10,0x5a,0xd8, - 0x0a,0xc1,0x31,0x88,0xa5,0xcd,0x7b,0xbd,0x2d,0x74,0xd0,0x12,0xb8,0xe5,0xb4,0xb0, - 0x89,0x69,0x97,0x4a,0x0c,0x96,0x77,0x7e,0x65,0xb9,0xf1,0x09,0xc5,0x6e,0xc6,0x84, - 0x18,0xf0,0x7d,0xec,0x3a,0xdc,0x4d,0x20,0x79,0xee,0x5f,0x3e,0xd7,0xcb,0x39,0x48 - }; - - private static uint Tau(uint x) - { - return (uint)(SBox[x & 0xff] - | (SBox[(x >> 8) & 0xff] << 8) - | (SBox[(x >> 16) & 0xff] << 16) - | (SBox[(x >> 24) & 0xff] << 24)); - } - - public static uint Encode(int index, uint[] data, uint[] roundKeys) - { - uint[] result = new uint[data.Length]; - - for (int s = 0; s < data.Length; s += 4) - { - uint x0 = data[s + 0]; - uint x1 = data[s + 1]; - uint x2 = data[s + 2]; - uint x3 = data[s + 3]; - - for (int i = 0; i < 4; i++) - { - uint t = x1 ^ x2 ^ x3 ^ roundKeys[s + i]; - t = Tau(t); - t ^= BitOperations.RotateLeft(t, 2) - ^ BitOperations.RotateLeft(t, 10) - ^ BitOperations.RotateLeft(t, 18) - ^ BitOperations.RotateLeft(t, 24); - t ^= x0; - - x0 = x1; - x1 = x2; - x2 = x3; - x3 = t; - } + public static class Sm4 + { + private static readonly byte[] SBox = + { + 0xd6,0x90,0xe9,0xfe,0xcc,0xe1,0x3d,0xb7,0x16,0xb6,0x14,0xc2,0x28,0xfb,0x2c,0x05, + 0x2b,0x67,0x9a,0x76,0x2a,0xbe,0x04,0xc3,0xaa,0x44,0x13,0x26,0x49,0x86,0x06,0x99, + 0x9c,0x42,0x50,0xf4,0x91,0xef,0x98,0x7a,0x33,0x54,0x0b,0x43,0xed,0xcf,0xac,0x62, + 0xe4,0xb3,0x1c,0xa9,0xc9,0x08,0xe8,0x95,0x80,0xdf,0x94,0xfa,0x75,0x8f,0x3f,0xa6, + 0x47,0x07,0xa7,0xfc,0xf3,0x73,0x17,0xba,0x83,0x59,0x3c,0x19,0xe6,0x85,0x4f,0xa8, + 0x68,0x6b,0x81,0xb2,0x71,0x64,0xda,0x8b,0xf8,0xeb,0x0f,0x4b,0x70,0x56,0x9d,0x35, + 0x1e,0x24,0x0e,0x5e,0x63,0x58,0xd1,0xa2,0x25,0x22,0x7c,0x3b,0x01,0x21,0x78,0x87, + 0xd4,0x00,0x46,0x57,0x9f,0xd3,0x27,0x52,0x4c,0x36,0x02,0xe7,0xa0,0xc4,0xc8,0x9e, + 0xea,0xbf,0x8a,0xd2,0x40,0xc7,0x38,0xb5,0xa3,0xf7,0xf2,0xce,0xf9,0x61,0x15,0xa1, + 0xe0,0xae,0x5d,0xa4,0x9b,0x34,0x1a,0x55,0xad,0x93,0x32,0x30,0xf5,0x8c,0xb1,0xe3, + 0x1d,0xf6,0xe2,0x2e,0x82,0x66,0xca,0x60,0xc0,0x29,0x23,0xab,0x0d,0x53,0x4e,0x6f, + 0xd5,0xdb,0x37,0x45,0xde,0xfd,0x8e,0x2f,0x03,0xff,0x6a,0x72,0x6d,0x6c,0x5b,0x51, + 0x8d,0x1b,0xaf,0x92,0xbb,0xdd,0xbc,0x7f,0x11,0xd9,0x5c,0x41,0x1f,0x10,0x5a,0xd8, + 0x0a,0xc1,0x31,0x88,0xa5,0xcd,0x7b,0xbd,0x2d,0x74,0xd0,0x12,0xb8,0xe5,0xb4,0xb0, + 0x89,0x69,0x97,0x4a,0x0c,0x96,0x77,0x7e,0x65,0xb9,0xf1,0x09,0xc5,0x6e,0xc6,0x84, + 0x18,0xf0,0x7d,0xec,0x3a,0xdc,0x4d,0x20,0x79,0xee,0x5f,0x3e,0xd7,0xcb,0x39,0x48 + }; - result[s + 0] = x0; - result[s + 1] = x1; - result[s + 2] = x2; - result[s + 3] = x3; + private static uint Tau(uint x) + { + return (uint)(SBox[x & 0xff] + | (SBox[(x >> 8) & 0xff] << 8) + | (SBox[(x >> 16) & 0xff] << 16) + | (SBox[(x >> 24) & 0xff] << 24)); } - return result[index]; - } + public static uint Encode(int index, uint[] data, uint[] roundKeys) + { + uint[] result = new uint[data.Length]; - public static uint KeyUpdate(int index, uint[] key, uint[] constants) - { - uint[] result = new uint[key.Length]; + for (int s = 0; s < data.Length; s += 4) + { + uint x0 = data[s + 0]; + uint x1 = data[s + 1]; + uint x2 = data[s + 2]; + uint x3 = data[s + 3]; + + for (int i = 0; i < 4; i++) + { + uint t = x1 ^ x2 ^ x3 ^ roundKeys[s + i]; + t = Tau(t); + t ^= BitOperations.RotateLeft(t, 2) + ^ BitOperations.RotateLeft(t, 10) + ^ BitOperations.RotateLeft(t, 18) + ^ BitOperations.RotateLeft(t, 24); + t ^= x0; + + x0 = x1; + x1 = x2; + x2 = x3; + x3 = t; + } + + result[s + 0] = x0; + result[s + 1] = x1; + result[s + 2] = x2; + result[s + 3] = x3; + } + + return result[index]; + } - for (int s = 0; s < key.Length; s += 4) + public static uint KeyUpdate(int index, uint[] key, uint[] constants) { - uint k0 = key[s + 0]; - uint k1 = key[s + 1]; - uint k2 = key[s + 2]; - uint k3 = key[s + 3]; + uint[] result = new uint[key.Length]; - for (int i = 0; i < 4; i++) + for (int s = 0; s < key.Length; s += 4) { - uint t = k1 ^ k2 ^ k3 ^ constants[s + i]; - t = Tau(t); - t ^= BitOperations.RotateLeft(t, 13) - ^ BitOperations.RotateLeft(t, 23); - t ^= k0; - - k0 = k1; - k1 = k2; - k2 = k3; - k3 = t; + uint k0 = key[s + 0]; + uint k1 = key[s + 1]; + uint k2 = key[s + 2]; + uint k3 = key[s + 3]; + + for (int i = 0; i < 4; i++) + { + uint t = k1 ^ k2 ^ k3 ^ constants[s + i]; + t = Tau(t); + t ^= BitOperations.RotateLeft(t, 13) + ^ BitOperations.RotateLeft(t, 23); + t ^= k0; + + k0 = k1; + k1 = k2; + k2 = k3; + k3 = t; + } + + result[s + 0] = k0; + result[s + 1] = k1; + result[s + 2] = k2; + result[s + 3] = k3; } - result[s + 0] = k0; - result[s + 1] = k1; - result[s + 2] = k2; - result[s + 3] = k3; + return result[index]; } - - return result[index]; } } From 3d973e076140170594b7ab7691982bdfa6798285 Mon Sep 17 00:00:00 2001 From: Alan Hayward Date: Wed, 1 Jul 2026 14:37:13 +0100 Subject: [PATCH 08/11] remove bogus assert --- src/coreclr/jit/hwintrinsiccodegenarm64.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp index 98d075b4a2723b..5595530a079572 100644 --- a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp +++ b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp @@ -1136,7 +1136,6 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) if (HWIntrinsicInfo::SupportsContainment(intrin.id) && intrin.op2->isContained() && intrin.op2->IsVectorZero()) { - assert(!isRMW); GetEmitter()->emitIns_R_R(ins, emitSize, targetReg, op1Reg, opt); } else From 64ea15237eee7bb5281e666ebeb138c9a06c1bc9 Mon Sep 17 00:00:00 2001 From: Alan Hayward Date: Mon, 6 Jul 2026 15:30:25 +0100 Subject: [PATCH 09/11] fix hwintrinsic entries --- src/coreclr/jit/hwintrinsiclistarm64.h | 12 ++++++------ src/coreclr/jit/hwintrinsiclistarm64sve.h | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/coreclr/jit/hwintrinsiclistarm64.h b/src/coreclr/jit/hwintrinsiclistarm64.h index 54f0d50e9f6332..ef2dd5590144bb 100644 --- a/src/coreclr/jit/hwintrinsiclistarm64.h +++ b/src/coreclr/jit/hwintrinsiclistarm64.h @@ -612,14 +612,14 @@ HARDWARE_INTRINSIC(Sha3, XorRotateRight, #define LAST_NI_Sha3 NI_Sha3_XorRotateRight // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** -// ISA Function name SIMD size NumArg EncodesExtraTypeArg Instructions Category Flags -// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} +// ISA Function name SIMD size NumArg Instructions IntCost FltCost Category Flags +// TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // Sm4 -#define FIRST_NI_Sm4 NI_Sm4_Encode -HARDWARE_INTRINSIC(Sm4, Encode, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sm4e, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_HasRMWSemantics) -HARDWARE_INTRINSIC(Sm4, KeyUpdate, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sm4ekey, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_NoFlag) -#define LAST_NI_Sm4 NI_Sm4_KeyUpdate +#define FIRST_NI_Sm4 NI_Sm4_Encode +HARDWARE_INTRINSIC(Sm4, Encode, 16, 2, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sm4e, INS_invalid, INS_invalid, INS_invalid, INS_invalid, -1, -1, HW_Category_SIMD, HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sm4, KeyUpdate, 16, 2, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sm4ekey, INS_invalid, INS_invalid, INS_invalid, INS_invalid, -1, -1, HW_Category_SIMD, HW_Flag_NoFlag) +#define LAST_NI_Sm4 NI_Sm4_KeyUpdate #endif // FEATURE_HW_INTRINSIC diff --git a/src/coreclr/jit/hwintrinsiclistarm64sve.h b/src/coreclr/jit/hwintrinsiclistarm64sve.h index dbe065a22ae3bc..773fe23eb501d0 100644 --- a/src/coreclr/jit/hwintrinsiclistarm64sve.h +++ b/src/coreclr/jit/hwintrinsiclistarm64sve.h @@ -543,14 +543,14 @@ HARDWARE_INTRINSIC(SveSha3, BitwiseRotateLeftBy1AndXor, #define LAST_NI_SveSha3 NI_SveSha3_BitwiseRotateLeftBy1AndXor // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** -// ISA Function name SIMD size NumArg Instructions Category Flags -// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} +// ISA Function name SIMD size NumArg Instructions IntCost FltCost Category Flags +// TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // SveSm4 -#define FIRST_NI_SveSm4 NI_SveSm4_Encode -HARDWARE_INTRINSIC(SveSm4, Encode, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_sm4e, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) -HARDWARE_INTRINSIC(SveSm4, KeyUpdate, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_sm4ekey, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable) -#define LAST_NI_SveSm4 NI_SveSm4_KeyUpdate +#define FIRST_NI_SveSm4 NI_SveSm4_Encode +HARDWARE_INTRINSIC(SveSm4, Encode, -1, 2, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_sm4e, INS_invalid, INS_invalid, INS_invalid, INS_invalid, -1, -1, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(SveSm4, KeyUpdate, -1, 2, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_sm4ekey, INS_invalid, INS_invalid, INS_invalid, INS_invalid, -1, -1, HW_Category_SIMD, HW_Flag_Scalable) +#define LAST_NI_SveSm4 NI_SveSm4_KeyUpdate // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // ISA Function name SIMD size NumArg Instructions IntCost FltCost Category Flags From 77006d9c294789353615f96eefa0f28cc267d6e0 Mon Sep 17 00:00:00 2001 From: Alan Hayward Date: Tue, 7 Jul 2026 13:35:06 +0100 Subject: [PATCH 10/11] fix IsSupported --- .../System/Runtime/Intrinsics/Arm/Sm4.PlatformNotSupported.cs | 2 +- .../Runtime/Intrinsics/Arm/SveSm4.PlatformNotSupported.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sm4.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sm4.PlatformNotSupported.cs index 986654cfc37b2f..aa8e2cb6cc0fbd 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sm4.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sm4.PlatformNotSupported.cs @@ -25,7 +25,7 @@ internal Arm64() { } /// Gets a value that indicates whether the APIs in this class are supported. /// if the APIs are supported; otherwise, . /// A value of indicates that the APIs will throw . - public static new bool IsSupported { get => IsSupported; } + public static new bool IsSupported { [Intrinsic] get { return false; } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/SveSm4.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/SveSm4.PlatformNotSupported.cs index 79e1a18bf56c73..32a32d25133e9c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/SveSm4.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/SveSm4.PlatformNotSupported.cs @@ -27,7 +27,7 @@ internal Arm64() { } /// Gets a value that indicates whether the APIs in this class are supported. /// if the APIs are supported; otherwise, . /// A value of indicates that the APIs will throw . - public static new bool IsSupported { get => IsSupported; } + public static new bool IsSupported { [Intrinsic] get { return false; } } } From 2deac956aab8a286bd0baaccd55967ab502ad313 Mon Sep 17 00:00:00 2001 From: Alan Hayward Date: Tue, 7 Jul 2026 13:35:23 +0100 Subject: [PATCH 11/11] remove AES changes --- src/coreclr/jit/emitarm64sve.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/coreclr/jit/emitarm64sve.cpp b/src/coreclr/jit/emitarm64sve.cpp index 4ba4d0c3181d36..fbf84871818903 100644 --- a/src/coreclr/jit/emitarm64sve.cpp +++ b/src/coreclr/jit/emitarm64sve.cpp @@ -3016,8 +3016,6 @@ void emitter::emitInsSve_R_R_R(instruction ins, emitInsSve_R_R(ins, attr, reg1, reg3, opt, sopt); return; - case INS_sve_aesd: - case INS_sve_aese: case INS_sve_sm4e: case INS_sve_sqxtnt: case INS_sve_uqxtnt: