diff --git a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp index 7223d7b2203e8..0ea063a0c45d1 100644 --- a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp +++ b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp @@ -571,6 +571,9 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) switch (intrin.numOperands) { + case 0: + GetEmitter()->emitIns_R(ins, emitSize, targetReg, opt); + break; case 1: GetEmitter()->emitIns_R_R(ins, emitSize, targetReg, op1Reg, opt); break; diff --git a/src/coreclr/jit/hwintrinsiclistarm64sve.h b/src/coreclr/jit/hwintrinsiclistarm64sve.h index 2df9c50569558..8b4f6167ff15c 100644 --- a/src/coreclr/jit/hwintrinsiclistarm64sve.h +++ b/src/coreclr/jit/hwintrinsiclistarm64sve.h @@ -29,6 +29,16 @@ HARDWARE_INTRINSIC(Sve, Count16BitElements, HARDWARE_INTRINSIC(Sve, Count32BitElements, 0, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_cntw, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_Scalable|HW_Flag_HasEnumOperand|HW_Flag_SpecialCodeGen|HW_Flag_NoFloatingPointUsed) HARDWARE_INTRINSIC(Sve, Count64BitElements, 0, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_cntd, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_Scalable|HW_Flag_HasEnumOperand|HW_Flag_SpecialCodeGen|HW_Flag_NoFloatingPointUsed) HARDWARE_INTRINSIC(Sve, Count8BitElements, 0, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_cntb, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_Scalable|HW_Flag_HasEnumOperand|HW_Flag_SpecialCodeGen|HW_Flag_NoFloatingPointUsed) +HARDWARE_INTRINSIC(Sve, CreateFalseMaskByte, -1, 0, false, {INS_invalid, INS_sve_pfalse, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_ReturnsPerElementMask) +HARDWARE_INTRINSIC(Sve, CreateFalseMaskDouble, -1, 0, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_pfalse}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_ReturnsPerElementMask) +HARDWARE_INTRINSIC(Sve, CreateFalseMaskInt16, -1, 0, false, {INS_invalid, INS_invalid, INS_sve_pfalse, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_ReturnsPerElementMask) +HARDWARE_INTRINSIC(Sve, CreateFalseMaskInt32, -1, 0, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_pfalse, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_ReturnsPerElementMask) +HARDWARE_INTRINSIC(Sve, CreateFalseMaskInt64, -1, 0, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_pfalse, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_ReturnsPerElementMask) +HARDWARE_INTRINSIC(Sve, CreateFalseMaskSByte, -1, 0, false, {INS_sve_pfalse, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_ReturnsPerElementMask) +HARDWARE_INTRINSIC(Sve, CreateFalseMaskSingle, -1, 0, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_pfalse, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_ReturnsPerElementMask) +HARDWARE_INTRINSIC(Sve, CreateFalseMaskUInt16, -1, 0, false, {INS_invalid, INS_invalid, INS_invalid, INS_sve_pfalse, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_ReturnsPerElementMask) +HARDWARE_INTRINSIC(Sve, CreateFalseMaskUInt32, -1, 0, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_pfalse, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_ReturnsPerElementMask) +HARDWARE_INTRINSIC(Sve, CreateFalseMaskUInt64, -1, 0, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_pfalse, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_ReturnsPerElementMask) HARDWARE_INTRINSIC(Sve, CreateTrueMaskByte, -1, 1, false, {INS_invalid, INS_sve_ptrue, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasEnumOperand|HW_Flag_ReturnsPerElementMask) HARDWARE_INTRINSIC(Sve, CreateTrueMaskDouble, -1, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ptrue}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasEnumOperand|HW_Flag_ReturnsPerElementMask) HARDWARE_INTRINSIC(Sve, CreateTrueMaskInt16, -1, 1, false, {INS_invalid, INS_invalid, INS_sve_ptrue, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasEnumOperand|HW_Flag_ReturnsPerElementMask) 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 e794c1b8f3b4d..3463bdc9cd04d 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 @@ -608,6 +608,96 @@ internal Arm64() { } public static unsafe ulong Count8BitElements([ConstantExpected] SveMaskPattern pattern = SveMaskPattern.All) { throw new PlatformNotSupportedException(); } + /// Set all predicate elements to false + + /// + /// svbool_t svpfalse[_b]() + /// PFALSE Presult.B + /// + public static unsafe Vector CreateFalseMaskByte() { throw new PlatformNotSupportedException(); } + + + /// Set all predicate elements to false + + /// + /// svbool_t svpfalse[_b]() + /// PFALSE Presult.B + /// + public static unsafe Vector CreateFalseMaskDouble() { throw new PlatformNotSupportedException(); } + + + /// Set all predicate elements to false + + /// + /// svbool_t svpfalse[_b]() + /// PFALSE Presult.B + /// + public static unsafe Vector CreateFalseMaskInt16() { throw new PlatformNotSupportedException(); } + + + /// Set all predicate elements to false + + /// + /// svbool_t svpfalse[_b]() + /// PFALSE Presult.B + /// + public static unsafe Vector CreateFalseMaskInt32() { throw new PlatformNotSupportedException(); } + + + /// Set all predicate elements to false + + /// + /// svbool_t svpfalse[_b]() + /// PFALSE Presult.B + /// + public static unsafe Vector CreateFalseMaskInt64() { throw new PlatformNotSupportedException(); } + + + /// Set all predicate elements to false + + /// + /// svbool_t svpfalse[_b]() + /// PFALSE Presult.B + /// + public static unsafe Vector CreateFalseMaskSByte() { throw new PlatformNotSupportedException(); } + + + /// Set all predicate elements to false + + /// + /// svbool_t svpfalse[_b]() + /// PFALSE Presult.B + /// + public static unsafe Vector CreateFalseMaskSingle() { throw new PlatformNotSupportedException(); } + + + /// Set all predicate elements to false + + /// + /// svbool_t svpfalse[_b]() + /// PFALSE Presult.B + /// + public static unsafe Vector CreateFalseMaskUInt16() { throw new PlatformNotSupportedException(); } + + + /// Set all predicate elements to false + + /// + /// svbool_t svpfalse[_b]() + /// PFALSE Presult.B + /// + public static unsafe Vector CreateFalseMaskUInt32() { throw new PlatformNotSupportedException(); } + + + /// Set all predicate elements to false + + /// + /// svbool_t svpfalse[_b]() + /// PFALSE Presult.B + /// + public static unsafe Vector CreateFalseMaskUInt64() { throw new PlatformNotSupportedException(); } + + /// CreateTrueMaskByte : Set predicate elements to true /// 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 64e44b48676ea..2b6be850fc464 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 @@ -665,6 +665,96 @@ internal Arm64() { } public static unsafe ulong Count8BitElements([ConstantExpected] SveMaskPattern pattern = SveMaskPattern.All) => Count8BitElements(pattern); + /// Set all predicate elements to false + + /// + /// svbool_t svpfalse[_b]() + /// PFALSE Presult.B + /// + public static unsafe Vector CreateFalseMaskByte() => CreateFalseMaskByte(); + + + /// Set all predicate elements to false + + /// + /// svbool_t svpfalse[_b]() + /// PFALSE Presult.B + /// + public static unsafe Vector CreateFalseMaskDouble() => CreateFalseMaskDouble(); + + + /// Set all predicate elements to false + + /// + /// svbool_t svpfalse[_b]() + /// PFALSE Presult.B + /// + public static unsafe Vector CreateFalseMaskInt16() => CreateFalseMaskInt16(); + + + /// Set all predicate elements to false + + /// + /// svbool_t svpfalse[_b]() + /// PFALSE Presult.B + /// + public static unsafe Vector CreateFalseMaskInt32() => CreateFalseMaskInt32(); + + + /// Set all predicate elements to false + + /// + /// svbool_t svpfalse[_b]() + /// PFALSE Presult.B + /// + public static unsafe Vector CreateFalseMaskInt64() => CreateFalseMaskInt64(); + + + /// Set all predicate elements to false + + /// + /// svbool_t svpfalse[_b]() + /// PFALSE Presult.B + /// + public static unsafe Vector CreateFalseMaskSByte() => CreateFalseMaskSByte(); + + + /// Set all predicate elements to false + + /// + /// svbool_t svpfalse[_b]() + /// PFALSE Presult.B + /// + public static unsafe Vector CreateFalseMaskSingle() => CreateFalseMaskSingle(); + + + /// Set all predicate elements to false + + /// + /// svbool_t svpfalse[_b]() + /// PFALSE Presult.B + /// + public static unsafe Vector CreateFalseMaskUInt16() => CreateFalseMaskUInt16(); + + + /// Set all predicate elements to false + + /// + /// svbool_t svpfalse[_b]() + /// PFALSE Presult.B + /// + public static unsafe Vector CreateFalseMaskUInt32() => CreateFalseMaskUInt32(); + + + /// Set all predicate elements to false + + /// + /// svbool_t svpfalse[_b]() + /// PFALSE Presult.B + /// + public static unsafe Vector CreateFalseMaskUInt64() => CreateFalseMaskUInt64(); + + /// CreateTrueMaskByte : Set predicate elements to true /// 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 9150de02b8834..67463b3ecaa18 100644 --- a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs +++ b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs @@ -4247,6 +4247,16 @@ internal Arm64() { } public static System.Numerics.Vector ConditionalSelect(System.Numerics.Vector mask, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector ConditionalSelect(System.Numerics.Vector mask, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector ConditionalSelect(System.Numerics.Vector mask, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector CreateFalseMaskByte() { throw null; } + public static System.Numerics.Vector CreateFalseMaskDouble() { throw null; } + public static System.Numerics.Vector CreateFalseMaskInt16() { throw null; } + public static System.Numerics.Vector CreateFalseMaskInt32() { throw null; } + public static System.Numerics.Vector CreateFalseMaskInt64() { throw null; } + public static System.Numerics.Vector CreateFalseMaskSByte() { throw null; } + public static System.Numerics.Vector CreateFalseMaskSingle() { throw null; } + public static System.Numerics.Vector CreateFalseMaskUInt16() { throw null; } + public static System.Numerics.Vector CreateFalseMaskUInt32() { throw null; } + public static System.Numerics.Vector CreateFalseMaskUInt64() { throw null; } public static System.Numerics.Vector CreateTrueMaskByte([ConstantExpected] SveMaskPattern pattern = SveMaskPattern.All) { throw null; } public static System.Numerics.Vector CreateTrueMaskDouble([ConstantExpected] SveMaskPattern pattern = SveMaskPattern.All) { throw null; } public static System.Numerics.Vector CreateTrueMaskInt16([ConstantExpected] SveMaskPattern pattern = SveMaskPattern.All) { throw null; } diff --git a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs index 070afeb2b8c83..35935d05d5785 100644 --- a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs +++ b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs @@ -3009,6 +3009,27 @@ ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Divide_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Divide", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.Divide(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Divide(left[i], right[i])"}), ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Divide_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Divide", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.Divide(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Divide(left[i], right[i])"}), + ("SveSimpleNoOpTest.template", new Dictionary { ["TestName"] = "Sve_CreateFalseMaskByte_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateFalseMaskByte", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["ValidateIterResult"] = "result[i] != 0",}), + ("SveSimpleNoOpTest.template", new Dictionary { ["TestName"] = "Sve_CreateFalseMaskDouble_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateFalseMaskDouble", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["ValidateIterResult"] = "result[i] != 0",}), + ("SveSimpleNoOpTest.template", new Dictionary { ["TestName"] = "Sve_CreateFalseMaskInt16_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateFalseMaskInt16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["ValidateIterResult"] = "result[i] != 0",}), + ("SveSimpleNoOpTest.template", new Dictionary { ["TestName"] = "Sve_CreateFalseMaskInt32_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateFalseMaskInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["ValidateIterResult"] = "result[i] != 0",}), + ("SveSimpleNoOpTest.template", new Dictionary { ["TestName"] = "Sve_CreateFalseMaskInt64_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateFalseMaskInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["ValidateIterResult"] = "result[i] != 0",}), + ("SveSimpleNoOpTest.template", new Dictionary { ["TestName"] = "Sve_CreateFalseMaskSByte_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateFalseMaskSByte", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["ValidateIterResult"] = "result[i] != 0",}), + ("SveSimpleNoOpTest.template", new Dictionary { ["TestName"] = "Sve_CreateFalseMaskSingle_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateFalseMaskSingle", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["ValidateIterResult"] = "result[i] != 0",}), + ("SveSimpleNoOpTest.template", new Dictionary { ["TestName"] = "Sve_CreateFalseMaskUInt16_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateFalseMaskUInt16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["ValidateIterResult"] = "result[i] != 0",}), + ("SveSimpleNoOpTest.template", new Dictionary { ["TestName"] = "Sve_CreateFalseMaskUInt32_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateFalseMaskUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["ValidateIterResult"] = "result[i] != 0",}), + ("SveSimpleNoOpTest.template", new Dictionary { ["TestName"] = "Sve_CreateFalseMaskUInt64_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateFalseMaskUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["ValidateIterResult"] = "result[i] != 0",}), + ("SveCreateTrueMaskTest.template", new Dictionary { ["TestName"] = "Sve_CreateTrueMaskByte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateTrueMaskByte", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1Type"] = "SveMaskPattern"}), + ("SveCreateTrueMaskTest.template", new Dictionary { ["TestName"] = "Sve_CreateTrueMaskDouble", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateTrueMaskDouble", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1Type"] = "SveMaskPattern"}), + ("SveCreateTrueMaskTest.template", new Dictionary { ["TestName"] = "Sve_CreateTrueMaskInt16", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateTrueMaskInt16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1Type"] = "SveMaskPattern"}), + ("SveCreateTrueMaskTest.template", new Dictionary { ["TestName"] = "Sve_CreateTrueMaskInt32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateTrueMaskInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1Type"] = "SveMaskPattern"}), + ("SveCreateTrueMaskTest.template", new Dictionary { ["TestName"] = "Sve_CreateTrueMaskInt64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateTrueMaskInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1Type"] = "SveMaskPattern"}), + ("SveCreateTrueMaskTest.template", new Dictionary { ["TestName"] = "Sve_CreateTrueMaskSByte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateTrueMaskSByte", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1Type"] = "SveMaskPattern"}), + ("SveCreateTrueMaskTest.template", new Dictionary { ["TestName"] = "Sve_CreateTrueMaskSingle", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateTrueMaskSingle", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1Type"] = "SveMaskPattern"}), + ("SveCreateTrueMaskTest.template", new Dictionary { ["TestName"] = "Sve_CreateTrueMaskUInt16", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateTrueMaskUInt16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1Type"] = "SveMaskPattern"}), + ("SveCreateTrueMaskTest.template", new Dictionary { ["TestName"] = "Sve_CreateTrueMaskUInt32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateTrueMaskUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1Type"] = "SveMaskPattern"}), + ("SveCreateTrueMaskTest.template", new Dictionary { ["TestName"] = "Sve_CreateTrueMaskUInt64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateTrueMaskUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1Type"] = "SveMaskPattern"}), + ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVector_float", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVector_double", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVector_sbyte", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveCreateTrueMaskTest.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveCreateTrueMaskTest.template new file mode 100644 index 0000000000000..6c88cd1fb2ec0 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveCreateTrueMaskTest.template @@ -0,0 +1,230 @@ +// 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.Numerics; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.Arm; +using Xunit; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + [Fact] + public static void {TestName}() + { + var test = new CreateTrueMaskTest__{TestName}(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario_CreateTrueMask(); + + // Validates calling via reflection works + test.RunReflectionScenario_CreateTrueMask(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class CreateTrueMaskTest__{TestName} + { + private static int FloorPow2(int x) + { + if (x <= 0) + { + throw new Exception("Expected a positive argument value."); + } + + int result = 1; + + for (x = x / 2; x > 0; x /= 2) + { + result <<= 1; + } + + return result; + } + + // Decode a pattern specifier into a predicate constraint. + + private static int DecodePredCount({Op1Type} bitpattern, int esize) + { + if (bitpattern > {Op1Type}.All) + { + throw new Exception("Bit patterns must be 5 bits long."); + } + + switch (esize) { + case 8: + case 16: + case 32: + case 64: + break; + default: + throw new Exception("Incorrect esize"); + } + + int elements = (int)(Sve.Count8BitElements()) * 8 / esize; + switch (bitpattern) + { + case {Op1Type}.LargestPowerOf2: + return FloorPow2(elements); + case {Op1Type}.VectorCount1: + return elements >= 1 ? 1 : 0; + case {Op1Type}.VectorCount2: + return elements >= 2 ? 2 : 0; + case {Op1Type}.VectorCount3: + return elements >= 3 ? 3 : 0; + case {Op1Type}.VectorCount4: + return elements >= 4 ? 4 : 0; + case {Op1Type}.VectorCount5: + return elements >= 5 ? 5 : 0; + case {Op1Type}.VectorCount6: + return elements >= 6 ? 6 : 0; + case {Op1Type}.VectorCount7: + return elements >= 7 ? 7 : 0; + case {Op1Type}.VectorCount8: + return elements >= 8 ? 8 : 0; + case {Op1Type}.VectorCount16: + return elements >= 16 ? 16 : 0; + case {Op1Type}.VectorCount32: + return elements >= 32 ? 32 : 0; + case {Op1Type}.VectorCount64: + return elements >= 64 ? 64 : 0; + case {Op1Type}.VectorCount128: + return elements >= 128 ? 128 : 0; + case {Op1Type}.VectorCount256: + return elements >= 256 ? 256 : 0; + case {Op1Type}.LargestMultipleOf4: + return elements - (elements % 4); + case {Op1Type}.LargestMultipleOf3: + return elements - (elements % 3); + case {Op1Type}.All: + return elements; + default: + return 0; + } + + throw new Exception("Should be unreachable."); + return 0; + } + + // Calculate the expected result of a PTRUE instruction. + + private static {RetVectorType}<{RetBaseType}> PtrueOp({Op1Type} bitpattern, int esize) + { + int VL = (int)(Sve.Count8BitElements()) * 8; + int PL = VL / 8; + int elements = VL / esize; + int count = DecodePredCount(bitpattern, esize); + // {RetVectorType}<{RetBaseType}> result = {RetVectorType}<{RetBaseType}>.Zero; + int psize = esize / 8; + + {RetBaseType}[] elemArray = new {RetBaseType}[elements]; + for (int e = 0; e < elements; e++) + { + if (typeof({RetBaseType}) == typeof(Single)) + { + elemArray[e] = Unsafe.BitCast(e < count ? 1 : 0); + } + else if (typeof({RetBaseType}) == typeof(Double)) + { + elemArray[e] = Unsafe.BitCast(e < count ? 1 : 0); + } + else + { + elemArray[e] = ({RetBaseType})(e < count ? 1 : 0); + } + } + + return new {RetVectorType}<{RetBaseType}>(elemArray); + } + + public CreateTrueMaskTest__{TestName}() + { + Succeeded = true; + } + + public bool IsSupported => {Isa}.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_CreateTrueMask() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_CreateTrueMask)); + + for ({Op1Type} pattern = {Op1Type}.LargestPowerOf2; pattern <= {Op1Type}.All ; pattern++) + { + var result = {Isa}.{Method}(pattern); + + ValidateResult(pattern, result); + } + } + + public void RunReflectionScenario_CreateTrueMask() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_CreateTrueMask)); + + for ({Op1Type} pattern = {Op1Type}.LargestPowerOf2; pattern <= {Op1Type}.All ; pattern++) + { + var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1Type}) }) + .Invoke(null, new object[] { + pattern + }); + + ValidateResult(pattern, ({RetVectorType}<{RetBaseType}>)(result)); + } + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + Succeeded = false; + + try + { + RunBasicScenario_CreateTrueMask(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult({Op1Type} pattern, {RetVectorType}<{RetBaseType}> result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + {RetVectorType}<{RetBaseType}> expected = PtrueOp(pattern, sizeof({RetBaseType}) * 8); + if (!Vector.EqualsAll(expected, result)) + { + succeeded = false; + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({pattern}): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation($" expected: ({string.Join(", ", expected)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveSimpleNoOpTest.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveSimpleNoOpTest.template new file mode 100644 index 0000000000000..6ad3242c1b768 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveSimpleNoOpTest.template @@ -0,0 +1,114 @@ +// 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.Numerics; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.Arm; +using Xunit; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + [Fact] + public static void {TestName}() + { + var test = new CreateFalseMaskTest__{TestName}(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario_CreateFalseMask(); + + // Validates calling via reflection works + test.RunReflectionScenario_CreateFalseMask(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class CreateFalseMaskTest__{TestName} + { + private static readonly int RetElementCount = Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>() / sizeof({RetBaseType}); + + public CreateFalseMaskTest__{TestName}() + { + Succeeded = true; + } + + public bool IsSupported => {Isa}.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_CreateFalseMask() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_CreateFalseMask)); + + var result = {Isa}.{Method}(); + + ValidateResult(result); + } + + public void RunReflectionScenario_CreateFalseMask() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_CreateFalseMask)); + + var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { }) + .Invoke(null, new object[] {}); + + ValidateResult(({RetVectorType}<{RetBaseType}>)(result)); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + Succeeded = false; + + try + { + RunBasicScenario_CreateFalseMask(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult({RetVectorType}<{RetBaseType}> result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if ({ValidateIterResult}) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>(): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +}