diff --git a/src/coreclr/jit/hwintrinsiclistarm64sve.h b/src/coreclr/jit/hwintrinsiclistarm64sve.h index 4525cc797c20d..ab78d2f0f1af6 100644 --- a/src/coreclr/jit/hwintrinsiclistarm64sve.h +++ b/src/coreclr/jit/hwintrinsiclistarm64sve.h @@ -246,6 +246,8 @@ HARDWARE_INTRINSIC(Sve, TestFirstTrue, HARDWARE_INTRINSIC(Sve, TestLastTrue, -1, 2, true, {INS_sve_ptest, INS_sve_ptest, INS_sve_ptest, INS_sve_ptest, INS_sve_ptest, INS_sve_ptest, INS_sve_ptest, INS_sve_ptest, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Sve, TransposeEven, -1, 2, true, {INS_sve_trn1, INS_sve_trn1, INS_sve_trn1, INS_sve_trn1, INS_sve_trn1, INS_sve_trn1, INS_sve_trn1, INS_sve_trn1, INS_sve_trn1, INS_sve_trn1}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Sve, TransposeOdd, -1, 2, true, {INS_sve_trn2, INS_sve_trn2, INS_sve_trn2, INS_sve_trn2, INS_sve_trn2, INS_sve_trn2, INS_sve_trn2, INS_sve_trn2, INS_sve_trn2, INS_sve_trn2}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(Sve, TrigonometricSelectCoefficient, -1, 2, true, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ftssel, INS_sve_ftssel}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Sve, TrigonometricStartingValue, -1, 2, true, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ftsmul, INS_sve_ftsmul}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Sve, UnzipEven, -1, 2, true, {INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Sve, UnzipOdd, -1, 2, true, {INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Sve, VectorTableLookup, -1, 2, true, {INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl}, HW_Category_SIMD, HW_Flag_Scalable) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs index e89678393d0b1..bfb5314bb97a7 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs @@ -8631,6 +8631,36 @@ internal Arm64() { } public static unsafe Vector TransposeOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + /// Trigonometric select coefficient + + /// + /// svfloat64_t svtssel[_f64](svfloat64_t op1, svuint64_t op2) + /// FTSSEL Zresult.D, Zop1.D, Zop2.D + /// + public static unsafe Vector TrigonometricSelectCoefficient(Vector value, Vector selector) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat32_t svtssel[_f32](svfloat32_t op1, svuint32_t op2) + /// FTSSEL Zresult.S, Zop1.S, Zop2.S + /// + public static unsafe Vector TrigonometricSelectCoefficient(Vector value, Vector selector) { throw new PlatformNotSupportedException(); } + + + /// Trigonometric starting value + + /// + /// svfloat64_t svtsmul[_f64](svfloat64_t op1, svuint64_t op2) + /// FTSMUL Zresult.D, Zop1.D, Zop2.D + /// + public static unsafe Vector TrigonometricStartingValue(Vector value, Vector sign) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat32_t svtsmul[_f32](svfloat32_t op1, svuint32_t op2) + /// FTSMUL Zresult.S, Zop1.S, Zop2.S + /// + public static unsafe Vector TrigonometricStartingValue(Vector value, Vector sign) { throw new PlatformNotSupportedException(); } + + /// UnzipEven : Concatenate even elements from two inputs /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs index acd1f010839be..a0b8086b67992 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs @@ -8676,6 +8676,36 @@ internal Arm64() { } public static unsafe Vector TransposeOdd(Vector left, Vector right) => TransposeOdd(left, right); + /// Trigonometric select coefficient + + /// + /// svfloat64_t svtssel[_f64](svfloat64_t op1, svuint64_t op2) + /// FTSSEL Zresult.D, Zop1.D, Zop2.D + /// + public static unsafe Vector TrigonometricSelectCoefficient(Vector value, Vector selector) => TrigonometricSelectCoefficient(value, selector); + + /// + /// svfloat32_t svtssel[_f32](svfloat32_t op1, svuint32_t op2) + /// FTSSEL Zresult.S, Zop1.S, Zop2.S + /// + public static unsafe Vector TrigonometricSelectCoefficient(Vector value, Vector selector) => TrigonometricSelectCoefficient(value, selector); + + + /// Trigonometric starting value + + /// + /// svfloat64_t svtsmul[_f64](svfloat64_t op1, svuint64_t op2) + /// FTSMUL Zresult.D, Zop1.D, Zop2.D + /// + public static unsafe Vector TrigonometricStartingValue(Vector value, Vector sign) => TrigonometricStartingValue(value, sign); + + /// + /// svfloat32_t svtsmul[_f32](svfloat32_t op1, svuint32_t op2) + /// FTSMUL Zresult.S, Zop1.S, Zop2.S + /// + public static unsafe Vector TrigonometricStartingValue(Vector value, Vector sign) => TrigonometricStartingValue(value, sign); + + /// UnzipEven : Concatenate even elements from two inputs /// 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 e35fa3911744b..1afa8c2c7f750 100644 --- a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs +++ b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs @@ -5603,6 +5603,11 @@ internal Arm64() { } public static System.Numerics.Vector TransposeOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector TransposeOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector TrigonometricSelectCoefficient(System.Numerics.Vector value, System.Numerics.Vector selector) { throw null; } + public static System.Numerics.Vector TrigonometricSelectCoefficient(System.Numerics.Vector value, System.Numerics.Vector selector) { throw null; } + public static System.Numerics.Vector TrigonometricStartingValue(System.Numerics.Vector value, System.Numerics.Vector sign) { throw null; } + public static System.Numerics.Vector TrigonometricStartingValue(System.Numerics.Vector value, System.Numerics.Vector sign) { throw null; } + public static System.Numerics.Vector UnzipEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector UnzipEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector UnzipEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } diff --git a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs index dec13a0d48c36..6e548bd1926db 100644 --- a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs +++ b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs @@ -4156,6 +4156,11 @@ ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_XorAcross_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "XorAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.XorAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_XorAcross_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "XorAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateReduceOpResult"] = "Helpers.XorAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecBinOpDifferentTypesTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricSelectCoefficient_float_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricSelectCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "((left[i] <= (Math.PI / 4)) && (left[i] > (-Math.PI / 4))) && (Helpers.TrigonometricSelectCoefficient(left[i], right[i]) != result[i])", ["GetIterResult"] = "((left[i] <= (Math.PI / 4)) && (left[i] > (-Math.PI / 4))) ? Helpers.TrigonometricSelectCoefficient(left[i], right[i]) : result[i]"}), + ("SveVecBinOpDifferentTypesTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricSelectCoefficient_double_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricSelectCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "((left[i] <= (Math.PI / 4)) && (left[i] > (-Math.PI / 4))) && (Helpers.TrigonometricSelectCoefficient(left[i], right[i]) != result[i])", ["GetIterResult"] = "((left[i] <= (Math.PI / 4)) && (left[i] > (-Math.PI / 4))) ? Helpers.TrigonometricSelectCoefficient(left[i], right[i]) : result[i]"}), + ("SveVecBinOpDifferentTypesTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricStartingValue_float_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricStartingValue", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "((left[i] <= (Math.PI / 4)) && (left[i] > (-Math.PI / 4))) && (Helpers.TrigonometricStartingValue(left[i], right[i]) != result[i])", ["GetIterResult"] = "((left[i] <= (Math.PI / 4)) && (left[i] > (-Math.PI / 4))) ? Helpers.TrigonometricStartingValue(left[i], right[i]) : result[i]"}), + ("SveVecBinOpDifferentTypesTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricStartingValue_double_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricStartingValue", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "((left[i] <= (Math.PI / 4)) && (left[i] > (-Math.PI / 4))) && (Helpers.TrigonometricStartingValue(left[i], right[i]) != result[i])", ["GetIterResult"] = "((left[i] <= (Math.PI / 4)) && (left[i] > (-Math.PI / 4))) ? Helpers.TrigonometricStartingValue(left[i], right[i]) : result[i]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveUnzipEven_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveUnzipEven_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveUnzipEven_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs index 1a1a1192d3763..95619d36dfe3b 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs @@ -5252,6 +5252,36 @@ public static float MultiplyExtended(float op1, float op2) } } + public static float TrigonometricSelectCoefficient(float op1, uint op2) + { + float result = ((op2 % 2) == 0) ? op1 : (float)1.0; + bool isNegative = (op2 & 0b10) == 0b10; + + if (isNegative != (result < 0)) + { + result *= -1; + } + + return result; + } + + public static float TrigonometricStartingValue(float op1, uint op2) + { + float result = op1 * op1; + + if (float.IsNaN(result)) + { + return result; + } + + if ((op2 % 2) == 1) + { + result *= -1; + } + + return result; + } + public static float FPExponentialAccelerator(uint op1) { uint index = op1 & 0b111111; @@ -5372,6 +5402,36 @@ public static double MultiplyExtended(double op1, double op2) } } + public static double TrigonometricSelectCoefficient(double op1, ulong op2) + { + double result = ((op2 % 2) == 0) ? op1 : 1.0; + bool isNegative = (op2 & 0b10) == 0b10; + + if (isNegative != (result < 0)) + { + result *= -1; + } + + return result; + } + + public static double TrigonometricStartingValue(double op1, ulong op2) + { + double result = op1 * op1; + + if (double.IsNaN(result)) + { + return result; + } + + if ((op2 % 2) == 1) + { + result *= -1; + } + + return result; + } + public static double FPExponentialAccelerator(ulong op1) { ulong index = op1 & 0b111111;