diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp
index e6f381bb015f08..94c1052c055549 100644
--- a/src/coreclr/jit/emitarm64.cpp
+++ b/src/coreclr/jit/emitarm64.cpp
@@ -6100,6 +6100,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/emitarm64sve.cpp b/src/coreclr/jit/emitarm64sve.cpp
index a2eab684ee8000..fbf84871818903 100644
--- a/src/coreclr/jit/emitarm64sve.cpp
+++ b/src/coreclr/jit/emitarm64sve.cpp
@@ -3016,6 +3016,7 @@ void emitter::emitInsSve_R_R_R(instruction ins,
emitInsSve_R_R(ins, attr, reg1, reg3, opt, sopt);
return;
+ case INS_sve_sm4e:
case INS_sve_sqxtnt:
case INS_sve_uqxtnt:
case INS_sve_sqxtunt:
diff --git a/src/coreclr/jit/hwintrinsic.cpp b/src/coreclr/jit/hwintrinsic.cpp
index 5f2b9be56d1264..1624111f413ccc 100644
--- a/src/coreclr/jit/hwintrinsic.cpp
+++ b/src/coreclr/jit/hwintrinsic.cpp
@@ -993,10 +993,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
{ NI_Illegal, NI_Illegal }, // Cssc
{ FIRST_NI_ArmBase_Arm64, LAST_NI_ArmBase_Arm64 }, // ArmBase_Arm64
{ FIRST_NI_AdvSimd_Arm64, LAST_NI_AdvSimd_Arm64 }, // AdvSimd_Arm64
diff --git a/src/coreclr/jit/hwintrinsiclistarm64.h b/src/coreclr/jit/hwintrinsiclistarm64.h
index c04f9bf9a8be30..ef2dd5590144bb 100644
--- a/src/coreclr/jit/hwintrinsiclistarm64.h
+++ b/src/coreclr/jit/hwintrinsiclistarm64.h
@@ -611,6 +611,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, -1, -1, HW_Category_SIMD, HW_Flag_HasImmediateOperand)
#define LAST_NI_Sha3 NI_Sha3_XorRotateRight
+// ***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
+// 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, -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 81ccf47a89f8bf..773fe23eb501d0 100644
--- a/src/coreclr/jit/hwintrinsiclistarm64sve.h
+++ b/src/coreclr/jit/hwintrinsiclistarm64sve.h
@@ -542,6 +542,16 @@ HARDWARE_INTRINSIC(Sve2, XorRotateRight,
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, -1, -1, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen)
#define LAST_NI_SveSha3 NI_SveSha3_BitwiseRotateLeftBy1AndXor
+// ***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
+// 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, -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
// 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 9670007e075ff4..0b64b2d83de1b7 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
@@ -2876,10 +2876,12 @@
+
+
-
+
@@ -2890,10 +2892,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..639105a704eb71
--- /dev/null
+++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sm4.PlatformNotSupported.cs
@@ -0,0 +1,49 @@
+// 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.
+ [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 { [Intrinsic] get => false; }
+
+ /// Provides access to the ARM Sm4 hardware instructions, that are only available to 64-bit processes, via intrinsics.
+ 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 { [Intrinsic] get { return false; } }
+ }
+
+
+ // SM4 encryption and decryption
+
+ ///
+ /// uint32x4_t vsm4eq_u32(uint32x4_t a, uint32x4_t b)
+ /// SM4E Vd.4S,Vn.4S
+ ///
+ public static Vector128 Encode(Vector128 value, Vector128 roundKeys) { 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 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
new file mode 100644
index 00000000000000..77a55f49c755f0
--- /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 Vector128 Encode(Vector128 value, Vector128 roundKeys) => Encode(value, roundKeys);
+
+ // SM4 key updates
+
+ ///
+ /// uint32x4_t vsm4ekeyq_u32(uint32x4_t a, uint32x4_t b)
+ /// SM4EKEY Vd.4S,Vn.4S,Vm.4S
+ ///
+ public static Vector128 KeyUpdate(Vector128 value, Vector128 constant) => KeyUpdate(value, constant);
+
+ }
+}
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..8d4c9f1c4c86db
--- /dev/null
+++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/SveSm4.PlatformNotSupported.cs
@@ -0,0 +1,52 @@
+// 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.
+ [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 { [Intrinsic] get => false; }
+
+ /// Provides access to the ARM SveSm4 hardware instructions, that are only available to 64-bit processes, via intrinsics.
+ 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 { [Intrinsic] get { return false; } }
+ }
+
+
+ // SM4 encryption and decryption
+
+ ///
+ /// svuint32_t svsm4e[_u32](svuint32_t op1, svuint32_t op2)
+ /// SM4E Ztied1.S, Ztied1.S, Zop2.S
+ ///
+ public static Vector Encode(Vector value, Vector roundKeys) { 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 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
new file mode 100644
index 00000000000000..2e62e79f4116b0
--- /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 Vector Encode(Vector value, Vector roundKeys) => Encode(value, roundKeys);
+
+
+ // SM4 key updates
+
+ ///
+ /// svuint32_t svsm4ekey[_u32](svuint32_t op1, svuint32_t op2)
+ /// SM4EKEY Zresult.S, Zop1.S, Zop2.S
+ ///
+ public static Vector KeyUpdate(Vector value, Vector constant) => KeyUpdate(value, constant);
+
+ }
+}
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..0bf5c5e3291547 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 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() { }
+ 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 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() { }
+ 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..fac7fe54585037 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.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 e03cf691540f85..c3c7cabb1cb95f 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.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/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/AdvSimd.Arm64/Program.AdvSimd.Arm64.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/Program.AdvSimd.Arm64.cs
index 717c466e7d3056..4fc532b021369b 100644
--- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/Program.AdvSimd.Arm64.cs
+++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/Program.AdvSimd.Arm64.cs
@@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System;
-using System.Collections.Generic;
namespace JIT.HardwareIntrinsics.Arm._AdvSimd.Arm64
{
diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd.cs b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd.cs
index af869e6e80f7fc..7f7871d518a1bd 100644
--- a/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd.cs
+++ b/src/tests/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd.cs
@@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System;
-using System.Collections.Generic;
namespace JIT.HardwareIntrinsics.Arm._AdvSimd
{
diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Aes/Program.Aes.cs b/src/tests/JIT/HardwareIntrinsics/Arm/Aes/Program.Aes.cs
index 7e9ea28582ae87..eec91b3b441aae 100644
--- a/src/tests/JIT/HardwareIntrinsics/Arm/Aes/Program.Aes.cs
+++ b/src/tests/JIT/HardwareIntrinsics/Arm/Aes/Program.Aes.cs
@@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System;
-using System.Collections.Generic;
namespace JIT.HardwareIntrinsics.Arm._Aes
{
diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/ArmBase.Arm64/Program.ArmBase.Arm64.cs b/src/tests/JIT/HardwareIntrinsics/Arm/ArmBase.Arm64/Program.ArmBase.Arm64.cs
index 9d6d42b6b1c5d9..2505ab8286e9ff 100644
--- a/src/tests/JIT/HardwareIntrinsics/Arm/ArmBase.Arm64/Program.ArmBase.Arm64.cs
+++ b/src/tests/JIT/HardwareIntrinsics/Arm/ArmBase.Arm64/Program.ArmBase.Arm64.cs
@@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System;
-using System.Collections.Generic;
namespace JIT.HardwareIntrinsics.Arm._ArmBase.Arm64
{
diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/ArmBase/Program.ArmBase.cs b/src/tests/JIT/HardwareIntrinsics/Arm/ArmBase/Program.ArmBase.cs
index be2719bf65fd26..934618fe1d6f80 100644
--- a/src/tests/JIT/HardwareIntrinsics/Arm/ArmBase/Program.ArmBase.cs
+++ b/src/tests/JIT/HardwareIntrinsics/Arm/ArmBase/Program.ArmBase.cs
@@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System;
-using System.Collections.Generic;
namespace JIT.HardwareIntrinsics.Arm._ArmBase
{
diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Crc32.Arm64/Program.Crc32.Arm64.cs b/src/tests/JIT/HardwareIntrinsics/Arm/Crc32.Arm64/Program.Crc32.Arm64.cs
index 1b1096f36cd948..8f2da6a69357a0 100644
--- a/src/tests/JIT/HardwareIntrinsics/Arm/Crc32.Arm64/Program.Crc32.Arm64.cs
+++ b/src/tests/JIT/HardwareIntrinsics/Arm/Crc32.Arm64/Program.Crc32.Arm64.cs
@@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System;
-using System.Collections.Generic;
namespace JIT.HardwareIntrinsics.Arm._Crc32.Arm64
{
diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Crc32/Program.Crc32.cs b/src/tests/JIT/HardwareIntrinsics/Arm/Crc32/Program.Crc32.cs
index 354d11efdbf9c6..8ad24f2559d69b 100644
--- a/src/tests/JIT/HardwareIntrinsics/Arm/Crc32/Program.Crc32.cs
+++ b/src/tests/JIT/HardwareIntrinsics/Arm/Crc32/Program.Crc32.cs
@@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System;
-using System.Collections.Generic;
namespace JIT.HardwareIntrinsics.Arm._Crc32
{
diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Dp/Program.Dp.cs b/src/tests/JIT/HardwareIntrinsics/Arm/Dp/Program.Dp.cs
index a0d8abcf65c155..910f04181d06b6 100644
--- a/src/tests/JIT/HardwareIntrinsics/Arm/Dp/Program.Dp.cs
+++ b/src/tests/JIT/HardwareIntrinsics/Arm/Dp/Program.Dp.cs
@@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System;
-using System.Collections.Generic;
namespace JIT.HardwareIntrinsics.Arm._Dp
{
diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Rdm.Arm64/Program.Rdm.Arm64.cs b/src/tests/JIT/HardwareIntrinsics/Arm/Rdm.Arm64/Program.Rdm.Arm64.cs
index a1423adf35ca06..ad94e6cf044172 100644
--- a/src/tests/JIT/HardwareIntrinsics/Arm/Rdm.Arm64/Program.Rdm.Arm64.cs
+++ b/src/tests/JIT/HardwareIntrinsics/Arm/Rdm.Arm64/Program.Rdm.Arm64.cs
@@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System;
-using System.Collections.Generic;
namespace JIT.HardwareIntrinsics.Arm._Rdm.Arm64
{
diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Rdm/Program.Rdm.cs b/src/tests/JIT/HardwareIntrinsics/Arm/Rdm/Program.Rdm.cs
index d266f502be4e5b..b78368f79101bf 100644
--- a/src/tests/JIT/HardwareIntrinsics/Arm/Rdm/Program.Rdm.cs
+++ b/src/tests/JIT/HardwareIntrinsics/Arm/Rdm/Program.Rdm.cs
@@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System;
-using System.Collections.Generic;
namespace JIT.HardwareIntrinsics.Arm._Rdm
{
diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Sha1/Program.Sha1.cs b/src/tests/JIT/HardwareIntrinsics/Arm/Sha1/Program.Sha1.cs
index 1ee49ae24b7d48..6ace98316d39e4 100644
--- a/src/tests/JIT/HardwareIntrinsics/Arm/Sha1/Program.Sha1.cs
+++ b/src/tests/JIT/HardwareIntrinsics/Arm/Sha1/Program.Sha1.cs
@@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System;
-using System.Collections.Generic;
namespace JIT.HardwareIntrinsics.Arm._Sha1
{
diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Sha256/Program.Sha256.cs b/src/tests/JIT/HardwareIntrinsics/Arm/Sha256/Program.Sha256.cs
index d391ef0fc075a7..5dba823121ec76 100644
--- a/src/tests/JIT/HardwareIntrinsics/Arm/Sha256/Program.Sha256.cs
+++ b/src/tests/JIT/HardwareIntrinsics/Arm/Sha256/Program.Sha256.cs
@@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System;
-using System.Collections.Generic;
namespace JIT.HardwareIntrinsics.Arm._Sha256
{
diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs
index 6ee5ba237ff01d..cb7e24fc45dee0 100644
--- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs
+++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs
@@ -8530,5 +8530,114 @@ public static ulong BitwiseRotateLeftBy1AndXor(ulong op1, ulong op2)
public static long BitwiseRotateLeftBy1AndXor(long op1, long op2)
=> op1 ^ unchecked((long)RotateLeft1((ulong)op2));
+
+ // SM4 encoding functions
+ public static class Sm4
+ {
+ // SM4 substitution box used by the non-linear Tau transform.
+ 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)
+ {
+ // Apply the SM4 S-box independently to each byte of the 32-bit word.
+ 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];
+
+ // SM4E processes four 32-bit words at a time and applies four rounds.
+ 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);
+ // Encryption linear transform: L(B) = B ^ rotl(B,2) ^ rotl(B,10) ^ rotl(B,18) ^ rotl(B,24).
+ 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];
+
+ // SM4EKEY uses the same four-word recurrence with the key-schedule linear transform.
+ 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);
+ // Key-schedule linear transform: L'(B) = B ^ rotl(B,13) ^ rotl(B,23).
+ 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..856e72236628e1
--- /dev/null
+++ b/src/tests/JIT/HardwareIntrinsics/Arm/Sm4/Program.Sm4.cs
@@ -0,0 +1,15 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+
+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/Sve/Program.Sve.cs b/src/tests/JIT/HardwareIntrinsics/Arm/Sve/Program.Sve.cs
index 35fb50d5efb903..2f9de0aecd6e97 100644
--- a/src/tests/JIT/HardwareIntrinsics/Arm/Sve/Program.Sve.cs
+++ b/src/tests/JIT/HardwareIntrinsics/Arm/Sve/Program.Sve.cs
@@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System;
-using System.Collections.Generic;
namespace JIT.HardwareIntrinsics.Arm._Sve
{
diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Sve2/Program.Sve2.cs b/src/tests/JIT/HardwareIntrinsics/Arm/Sve2/Program.Sve2.cs
index 4a3dd74fe88d21..741704dc712dd6 100644
--- a/src/tests/JIT/HardwareIntrinsics/Arm/Sve2/Program.Sve2.cs
+++ b/src/tests/JIT/HardwareIntrinsics/Arm/Sve2/Program.Sve2.cs
@@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System;
-using System.Collections.Generic;
namespace JIT.HardwareIntrinsics.Arm._Sve2
{
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..a1cd5de279da86
--- /dev/null
+++ b/src/tests/JIT/HardwareIntrinsics/Arm/SveSm4/Program.SveSm4.cs
@@ -0,0 +1,15 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+
+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
+
+
+
+
+
+
+