From a8e74e34dc796a488a5c9e76f3c4e85133d603ae Mon Sep 17 00:00:00 2001 From: Alan Hayward Date: Thu, 25 Apr 2024 20:05:30 +0100 Subject: [PATCH] JIT ARM64-SVE: Add CreateWhileLessThan* (#100949) * JIT ARM64-SVE: Add CreateWhileLessThan* * Set simdBaseJitType to type of input args * Hardcode opt in codegen * Fix gtNewSimdConvertMaskToVectorNode types * Use HW_Flag_BaseTypeFromFirstArg * Set base type to return type and auxiliary type to input type --- src/coreclr/jit/hwintrinsic.cpp | 11 + src/coreclr/jit/hwintrinsiccodegenarm64.cpp | 34 +++ src/coreclr/jit/hwintrinsiclistarm64sve.h | 10 +- .../Arm/Sve.PlatformNotSupported.cs | 218 ++++++++++++++++++ .../src/System/Runtime/Intrinsics/Arm/Sve.cs | 218 ++++++++++++++++++ .../ref/System.Runtime.Intrinsics.cs | 32 +++ .../GenerateHWIntrinsicTests_Arm.cs | 33 +++ .../HardwareIntrinsics/Arm/Shared/Helpers.cs | 40 ++++ .../Arm/Shared/ScalarBinOpRetVecTest.template | 216 +++++++++++++++++ 9 files changed, 810 insertions(+), 2 deletions(-) create mode 100644 src/tests/JIT/HardwareIntrinsics/Arm/Shared/ScalarBinOpRetVecTest.template diff --git a/src/coreclr/jit/hwintrinsic.cpp b/src/coreclr/jit/hwintrinsic.cpp index 402cae99b3f63..96060b2beacb7 100644 --- a/src/coreclr/jit/hwintrinsic.cpp +++ b/src/coreclr/jit/hwintrinsic.cpp @@ -1539,6 +1539,17 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, } break; + case NI_Sve_CreateWhileLessThanMask8Bit: + case NI_Sve_CreateWhileLessThanOrEqualMask8Bit: + case NI_Sve_CreateWhileLessThanMask16Bit: + case NI_Sve_CreateWhileLessThanOrEqualMask16Bit: + case NI_Sve_CreateWhileLessThanMask32Bit: + case NI_Sve_CreateWhileLessThanOrEqualMask32Bit: + case NI_Sve_CreateWhileLessThanMask64Bit: + case NI_Sve_CreateWhileLessThanOrEqualMask64Bit: + retNode->AsHWIntrinsic()->SetAuxiliaryJitType(sigReader.op1JitType); + break; + default: break; } diff --git a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp index 0355b4285d486..edabd7030359f 100644 --- a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp +++ b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp @@ -1409,6 +1409,40 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) GetEmitter()->emitIns_R_PATTERN(ins, emitSize, targetReg, opt, SVE_PATTERN_ALL); break; + case NI_Sve_CreateWhileLessThanMask8Bit: + case NI_Sve_CreateWhileLessThanMask16Bit: + case NI_Sve_CreateWhileLessThanMask32Bit: + case NI_Sve_CreateWhileLessThanMask64Bit: + { + // Emit size and instruction is based on the scalar operands. + var_types auxType = node->GetAuxiliaryType(); + emitSize = emitActualTypeSize(auxType); + if (varTypeIsUnsigned(auxType)) + { + ins = INS_sve_whilelo; + } + + GetEmitter()->emitIns_R_R_R(ins, emitSize, targetReg, op1Reg, op2Reg, opt); + break; + } + + case NI_Sve_CreateWhileLessThanOrEqualMask8Bit: + case NI_Sve_CreateWhileLessThanOrEqualMask16Bit: + case NI_Sve_CreateWhileLessThanOrEqualMask32Bit: + case NI_Sve_CreateWhileLessThanOrEqualMask64Bit: + { + // Emit size and instruction is based on the scalar operands. + var_types auxType = node->GetAuxiliaryType(); + emitSize = emitActualTypeSize(auxType); + if (varTypeIsUnsigned(auxType)) + { + ins = INS_sve_whilels; + } + + GetEmitter()->emitIns_R_R_R(ins, emitSize, targetReg, op1Reg, op2Reg, opt); + break; + } + default: unreached(); } diff --git a/src/coreclr/jit/hwintrinsiclistarm64sve.h b/src/coreclr/jit/hwintrinsiclistarm64sve.h index 02fd4992204c0..4cc3e86a170ff 100644 --- a/src/coreclr/jit/hwintrinsiclistarm64sve.h +++ b/src/coreclr/jit/hwintrinsiclistarm64sve.h @@ -30,7 +30,14 @@ HARDWARE_INTRINSIC(Sve, CreateTrueMaskSingle, HARDWARE_INTRINSIC(Sve, CreateTrueMaskUInt16, -1, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_sve_ptrue, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_EnumPattern, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_ReturnsPerElementMask) HARDWARE_INTRINSIC(Sve, CreateTrueMaskUInt32, -1, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ptrue, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_EnumPattern, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_ReturnsPerElementMask) HARDWARE_INTRINSIC(Sve, CreateTrueMaskUInt64, -1, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ptrue, INS_invalid, INS_invalid}, HW_Category_EnumPattern, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_ReturnsPerElementMask) - +HARDWARE_INTRINSIC(Sve, CreateWhileLessThanMask16Bit, -1, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_sve_whilelt, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ReturnsPerElementMask) +HARDWARE_INTRINSIC(Sve, CreateWhileLessThanMask32Bit, -1, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_whilelt, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ReturnsPerElementMask) +HARDWARE_INTRINSIC(Sve, CreateWhileLessThanMask64Bit, -1, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_whilelt, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ReturnsPerElementMask) +HARDWARE_INTRINSIC(Sve, CreateWhileLessThanMask8Bit, -1, 2, false, {INS_invalid, INS_sve_whilelt, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ReturnsPerElementMask) +HARDWARE_INTRINSIC(Sve, CreateWhileLessThanOrEqualMask16Bit, -1, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_sve_whilele, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ReturnsPerElementMask) +HARDWARE_INTRINSIC(Sve, CreateWhileLessThanOrEqualMask32Bit, -1, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_whilele, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ReturnsPerElementMask) +HARDWARE_INTRINSIC(Sve, CreateWhileLessThanOrEqualMask64Bit, -1, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_whilele, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ReturnsPerElementMask) +HARDWARE_INTRINSIC(Sve, CreateWhileLessThanOrEqualMask8Bit, -1, 2, false, {INS_invalid, INS_sve_whilele, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ReturnsPerElementMask) HARDWARE_INTRINSIC(Sve, LoadVector, -1, 2, true, {INS_sve_ld1b, INS_sve_ld1b, INS_sve_ld1h, INS_sve_ld1h, INS_sve_ld1w, INS_sve_ld1w, INS_sve_ld1d, INS_sve_ld1d, INS_sve_ld1w, INS_sve_ld1d}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, LoadVectorByteZeroExtendToInt16, -1, 2, false, {INS_invalid, INS_invalid, INS_sve_ld1b, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, LoadVectorByteZeroExtendToInt32, -1, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1b, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) @@ -58,7 +65,6 @@ HARDWARE_INTRINSIC(Sve, LoadVectorUInt32ZeroExtendToInt64, HARDWARE_INTRINSIC(Sve, LoadVectorUInt32ZeroExtendToUInt64, -1, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1w, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) - // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // 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} 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 4b0ccfaecd6de..918b8664739b6 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 @@ -239,6 +239,223 @@ public new abstract class Arm64 : AdvSimd.Arm64 /// public static unsafe Vector CreateTrueMaskUInt64([ConstantExpected] SveMaskPattern pattern = SveMaskPattern.All) { throw new PlatformNotSupportedException(); } + + /// CreateWhileLessThanMask16Bit : While incrementing scalar is less than + + /// + /// svbool_t svwhilelt_b16[_s32](int32_t op1, int32_t op2) + /// WHILELT Presult.H, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanMask16Bit(int left, int right) { throw new PlatformNotSupportedException(); } + + /// + /// svbool_t svwhilelt_b16[_s64](int64_t op1, int64_t op2) + /// WHILELT Presult.H, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanMask16Bit(long left, long right) { throw new PlatformNotSupportedException(); } + + /// + /// svbool_t svwhilelt_b16[_u32](uint32_t op1, uint32_t op2) + /// WHILELO Presult.H, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanMask16Bit(uint left, uint right) { throw new PlatformNotSupportedException(); } + + /// + /// svbool_t svwhilelt_b16[_u64](uint64_t op1, uint64_t op2) + /// WHILELO Presult.H, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanMask16Bit(ulong left, ulong right) { throw new PlatformNotSupportedException(); } + + + /// CreateWhileLessThanMask32Bit : While incrementing scalar is less than + + /// + /// svbool_t svwhilelt_b32[_s32](int32_t op1, int32_t op2) + /// WHILELT Presult.S, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanMask32Bit(int left, int right) { throw new PlatformNotSupportedException(); } + + /// + /// svbool_t svwhilelt_b32[_s64](int64_t op1, int64_t op2) + /// WHILELT Presult.S, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanMask32Bit(long left, long right) { throw new PlatformNotSupportedException(); } + + /// + /// svbool_t svwhilelt_b32[_u32](uint32_t op1, uint32_t op2) + /// WHILELO Presult.S, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanMask32Bit(uint left, uint right) { throw new PlatformNotSupportedException(); } + + /// + /// svbool_t svwhilelt_b32[_u64](uint64_t op1, uint64_t op2) + /// WHILELO Presult.S, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanMask32Bit(ulong left, ulong right) { throw new PlatformNotSupportedException(); } + + + /// CreateWhileLessThanMask64Bit : While incrementing scalar is less than + + /// + /// svbool_t svwhilelt_b64[_s32](int32_t op1, int32_t op2) + /// WHILELT Presult.D, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanMask64Bit(int left, int right) { throw new PlatformNotSupportedException(); } + + /// + /// svbool_t svwhilelt_b64[_s64](int64_t op1, int64_t op2) + /// WHILELT Presult.D, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanMask64Bit(long left, long right) { throw new PlatformNotSupportedException(); } + + /// + /// svbool_t svwhilelt_b64[_u32](uint32_t op1, uint32_t op2) + /// WHILELO Presult.D, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanMask64Bit(uint left, uint right) { throw new PlatformNotSupportedException(); } + + /// + /// svbool_t svwhilelt_b64[_u64](uint64_t op1, uint64_t op2) + /// WHILELO Presult.D, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanMask64Bit(ulong left, ulong right) { throw new PlatformNotSupportedException(); } + + + /// CreateWhileLessThanMask8Bit : While incrementing scalar is less than + + /// + /// svbool_t svwhilelt_b8[_s32](int32_t op1, int32_t op2) + /// WHILELT Presult.B, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanMask8Bit(int left, int right) { throw new PlatformNotSupportedException(); } + + /// + /// svbool_t svwhilelt_b8[_s64](int64_t op1, int64_t op2) + /// WHILELT Presult.B, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanMask8Bit(long left, long right) { throw new PlatformNotSupportedException(); } + + /// + /// svbool_t svwhilelt_b8[_u32](uint32_t op1, uint32_t op2) + /// WHILELO Presult.B, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanMask8Bit(uint left, uint right) { throw new PlatformNotSupportedException(); } + + /// + /// svbool_t svwhilelt_b8[_u64](uint64_t op1, uint64_t op2) + /// WHILELO Presult.B, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanMask8Bit(ulong left, ulong right) { throw new PlatformNotSupportedException(); } + + + /// CreateWhileLessThanOrEqualMask16Bit : While incrementing scalar is less than or equal to + + /// + /// svbool_t svwhilele_b16[_s32](int32_t op1, int32_t op2) + /// WHILELE Presult.H, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask16Bit(int left, int right) { throw new PlatformNotSupportedException(); } + + /// + /// svbool_t svwhilele_b16[_s64](int64_t op1, int64_t op2) + /// WHILELE Presult.H, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask16Bit(long left, long right) { throw new PlatformNotSupportedException(); } + + /// + /// svbool_t svwhilele_b16[_u32](uint32_t op1, uint32_t op2) + /// WHILELS Presult.H, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask16Bit(uint left, uint right) { throw new PlatformNotSupportedException(); } + + /// + /// svbool_t svwhilele_b16[_u64](uint64_t op1, uint64_t op2) + /// WHILELS Presult.H, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask16Bit(ulong left, ulong right) { throw new PlatformNotSupportedException(); } + + + /// CreateWhileLessThanOrEqualMask32Bit : While incrementing scalar is less than or equal to + + /// + /// svbool_t svwhilele_b32[_s32](int32_t op1, int32_t op2) + /// WHILELE Presult.S, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask32Bit(int left, int right) { throw new PlatformNotSupportedException(); } + + /// + /// svbool_t svwhilele_b32[_s64](int64_t op1, int64_t op2) + /// WHILELE Presult.S, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask32Bit(long left, long right) { throw new PlatformNotSupportedException(); } + + /// + /// svbool_t svwhilele_b32[_u32](uint32_t op1, uint32_t op2) + /// WHILELS Presult.S, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask32Bit(uint left, uint right) { throw new PlatformNotSupportedException(); } + + /// + /// svbool_t svwhilele_b32[_u64](uint64_t op1, uint64_t op2) + /// WHILELS Presult.S, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask32Bit(ulong left, ulong right) { throw new PlatformNotSupportedException(); } + + + /// CreateWhileLessThanOrEqualMask64Bit : While incrementing scalar is less than or equal to + + /// + /// svbool_t svwhilele_b64[_s32](int32_t op1, int32_t op2) + /// WHILELE Presult.D, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask64Bit(int left, int right) { throw new PlatformNotSupportedException(); } + + /// + /// svbool_t svwhilele_b64[_s64](int64_t op1, int64_t op2) + /// WHILELE Presult.D, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask64Bit(long left, long right) { throw new PlatformNotSupportedException(); } + + /// + /// svbool_t svwhilele_b64[_u32](uint32_t op1, uint32_t op2) + /// WHILELS Presult.D, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask64Bit(uint left, uint right) { throw new PlatformNotSupportedException(); } + + /// + /// svbool_t svwhilele_b64[_u64](uint64_t op1, uint64_t op2) + /// WHILELS Presult.D, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask64Bit(ulong left, ulong right) { throw new PlatformNotSupportedException(); } + + + /// CreateWhileLessThanOrEqualMask8Bit : While incrementing scalar is less than or equal to + + /// + /// svbool_t svwhilele_b8[_s32](int32_t op1, int32_t op2) + /// WHILELE Presult.B, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask8Bit(int left, int right) { throw new PlatformNotSupportedException(); } + + /// + /// svbool_t svwhilele_b8[_s64](int64_t op1, int64_t op2) + /// WHILELE Presult.B, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask8Bit(long left, long right) { throw new PlatformNotSupportedException(); } + + /// + /// svbool_t svwhilele_b8[_u32](uint32_t op1, uint32_t op2) + /// WHILELS Presult.B, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask8Bit(uint left, uint right) { throw new PlatformNotSupportedException(); } + + /// + /// svbool_t svwhilele_b8[_u64](uint64_t op1, uint64_t op2) + /// WHILELS Presult.B, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask8Bit(ulong left, ulong right) { throw new PlatformNotSupportedException(); } + + /// ConditionalSelect : Conditionally select elements /// @@ -299,6 +516,7 @@ public new abstract class Arm64 : AdvSimd.Arm64 /// public static unsafe Vector ConditionalSelect(Vector mask, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + /// LoadVector : Unextended load /// 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 9f17f6b9008ed..98f1824f5ecfe 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 @@ -266,6 +266,223 @@ public new abstract class Arm64 : AdvSimd.Arm64 /// public static unsafe Vector CreateTrueMaskUInt64([ConstantExpected] SveMaskPattern pattern = SveMaskPattern.All) => CreateTrueMaskUInt64(pattern); + + /// CreateWhileLessThanMask16Bit : While incrementing scalar is less than + + /// + /// svbool_t svwhilelt_b16[_s32](int32_t op1, int32_t op2) + /// WHILELT Presult.H, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanMask16Bit(int left, int right) => CreateWhileLessThanMask16Bit(left, right); + + /// + /// svbool_t svwhilelt_b16[_s64](int64_t op1, int64_t op2) + /// WHILELT Presult.H, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanMask16Bit(long left, long right) => CreateWhileLessThanMask16Bit(left, right); + + /// + /// svbool_t svwhilelt_b16[_u32](uint32_t op1, uint32_t op2) + /// WHILELO Presult.H, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanMask16Bit(uint left, uint right) => CreateWhileLessThanMask16Bit(left, right); + + /// + /// svbool_t svwhilelt_b16[_u64](uint64_t op1, uint64_t op2) + /// WHILELO Presult.H, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanMask16Bit(ulong left, ulong right) => CreateWhileLessThanMask16Bit(left, right); + + + /// CreateWhileLessThanMask32Bit : While incrementing scalar is less than + + /// + /// svbool_t svwhilelt_b32[_s32](int32_t op1, int32_t op2) + /// WHILELT Presult.S, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanMask32Bit(int left, int right) => CreateWhileLessThanMask32Bit(left, right); + + /// + /// svbool_t svwhilelt_b32[_s64](int64_t op1, int64_t op2) + /// WHILELT Presult.S, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanMask32Bit(long left, long right) => CreateWhileLessThanMask32Bit(left, right); + + /// + /// svbool_t svwhilelt_b32[_u32](uint32_t op1, uint32_t op2) + /// WHILELO Presult.S, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanMask32Bit(uint left, uint right) => CreateWhileLessThanMask32Bit(left, right); + + /// + /// svbool_t svwhilelt_b32[_u64](uint64_t op1, uint64_t op2) + /// WHILELO Presult.S, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanMask32Bit(ulong left, ulong right) => CreateWhileLessThanMask32Bit(left, right); + + + /// CreateWhileLessThanMask64Bit : While incrementing scalar is less than + + /// + /// svbool_t svwhilelt_b64[_s32](int32_t op1, int32_t op2) + /// WHILELT Presult.D, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanMask64Bit(int left, int right) => CreateWhileLessThanMask64Bit(left, right); + + /// + /// svbool_t svwhilelt_b64[_s64](int64_t op1, int64_t op2) + /// WHILELT Presult.D, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanMask64Bit(long left, long right) => CreateWhileLessThanMask64Bit(left, right); + + /// + /// svbool_t svwhilelt_b64[_u32](uint32_t op1, uint32_t op2) + /// WHILELO Presult.D, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanMask64Bit(uint left, uint right) => CreateWhileLessThanMask64Bit(left, right); + + /// + /// svbool_t svwhilelt_b64[_u64](uint64_t op1, uint64_t op2) + /// WHILELO Presult.D, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanMask64Bit(ulong left, ulong right) => CreateWhileLessThanMask64Bit(left, right); + + + /// CreateWhileLessThanMask8Bit : While incrementing scalar is less than + + /// + /// svbool_t svwhilelt_b8[_s32](int32_t op1, int32_t op2) + /// WHILELT Presult.B, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanMask8Bit(int left, int right) => CreateWhileLessThanMask8Bit(left, right); + + /// + /// svbool_t svwhilelt_b8[_s64](int64_t op1, int64_t op2) + /// WHILELT Presult.B, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanMask8Bit(long left, long right) => CreateWhileLessThanMask8Bit(left, right); + + /// + /// svbool_t svwhilelt_b8[_u32](uint32_t op1, uint32_t op2) + /// WHILELO Presult.B, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanMask8Bit(uint left, uint right) => CreateWhileLessThanMask8Bit(left, right); + + /// + /// svbool_t svwhilelt_b8[_u64](uint64_t op1, uint64_t op2) + /// WHILELO Presult.B, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanMask8Bit(ulong left, ulong right) => CreateWhileLessThanMask8Bit(left, right); + + + /// CreateWhileLessThanOrEqualMask16Bit : While incrementing scalar is less than or equal to + + /// + /// svbool_t svwhilele_b16[_s32](int32_t op1, int32_t op2) + /// WHILELE Presult.H, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask16Bit(int left, int right) => CreateWhileLessThanOrEqualMask16Bit(left, right); + + /// + /// svbool_t svwhilele_b16[_s64](int64_t op1, int64_t op2) + /// WHILELE Presult.H, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask16Bit(long left, long right) => CreateWhileLessThanOrEqualMask16Bit(left, right); + + /// + /// svbool_t svwhilele_b16[_u32](uint32_t op1, uint32_t op2) + /// WHILELS Presult.H, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask16Bit(uint left, uint right) => CreateWhileLessThanOrEqualMask16Bit(left, right); + + /// + /// svbool_t svwhilele_b16[_u64](uint64_t op1, uint64_t op2) + /// WHILELS Presult.H, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask16Bit(ulong left, ulong right) => CreateWhileLessThanOrEqualMask16Bit(left, right); + + + /// CreateWhileLessThanOrEqualMask32Bit : While incrementing scalar is less than or equal to + + /// + /// svbool_t svwhilele_b32[_s32](int32_t op1, int32_t op2) + /// WHILELE Presult.S, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask32Bit(int left, int right) => CreateWhileLessThanOrEqualMask32Bit(left, right); + + /// + /// svbool_t svwhilele_b32[_s64](int64_t op1, int64_t op2) + /// WHILELE Presult.S, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask32Bit(long left, long right) => CreateWhileLessThanOrEqualMask32Bit(left, right); + + /// + /// svbool_t svwhilele_b32[_u32](uint32_t op1, uint32_t op2) + /// WHILELS Presult.S, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask32Bit(uint left, uint right) => CreateWhileLessThanOrEqualMask32Bit(left, right); + + /// + /// svbool_t svwhilele_b32[_u64](uint64_t op1, uint64_t op2) + /// WHILELS Presult.S, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask32Bit(ulong left, ulong right) => CreateWhileLessThanOrEqualMask32Bit(left, right); + + + /// CreateWhileLessThanOrEqualMask64Bit : While incrementing scalar is less than or equal to + + /// + /// svbool_t svwhilele_b64[_s32](int32_t op1, int32_t op2) + /// WHILELE Presult.D, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask64Bit(int left, int right) => CreateWhileLessThanOrEqualMask64Bit(left, right); + + /// + /// svbool_t svwhilele_b64[_s64](int64_t op1, int64_t op2) + /// WHILELE Presult.D, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask64Bit(long left, long right) => CreateWhileLessThanOrEqualMask64Bit(left, right); + + /// + /// svbool_t svwhilele_b64[_u32](uint32_t op1, uint32_t op2) + /// WHILELS Presult.D, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask64Bit(uint left, uint right) => CreateWhileLessThanOrEqualMask64Bit(left, right); + + /// + /// svbool_t svwhilele_b64[_u64](uint64_t op1, uint64_t op2) + /// WHILELS Presult.D, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask64Bit(ulong left, ulong right) => CreateWhileLessThanOrEqualMask64Bit(left, right); + + + /// CreateWhileLessThanOrEqualMask8Bit : While incrementing scalar is less than or equal to + + /// + /// svbool_t svwhilele_b8[_s32](int32_t op1, int32_t op2) + /// WHILELE Presult.B, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask8Bit(int left, int right) => CreateWhileLessThanOrEqualMask8Bit(left, right); + + /// + /// svbool_t svwhilele_b8[_s64](int64_t op1, int64_t op2) + /// WHILELE Presult.B, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask8Bit(long left, long right) => CreateWhileLessThanOrEqualMask8Bit(left, right); + + /// + /// svbool_t svwhilele_b8[_u32](uint32_t op1, uint32_t op2) + /// WHILELS Presult.B, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask8Bit(uint left, uint right) => CreateWhileLessThanOrEqualMask8Bit(left, right); + + /// + /// svbool_t svwhilele_b8[_u64](uint64_t op1, uint64_t op2) + /// WHILELS Presult.B, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask8Bit(ulong left, ulong right) => CreateWhileLessThanOrEqualMask8Bit(left, right); + + /// ConditionalSelect : Conditionally select elements /// @@ -354,6 +571,7 @@ public new abstract class Arm64 : AdvSimd.Arm64 /// public static unsafe Vector ConditionalSelect(Vector mask, Vector left, Vector right) => ConditionalSelect(mask, left, right); + /// LoadVector : Unextended load /// 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 875d125cb32b5..e2ddb85806910 100644 --- a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs +++ b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs @@ -4197,6 +4197,38 @@ public new abstract partial class Arm64 : System.Runtime.Intrinsics.Arm.AdvSimd. public static System.Numerics.Vector CreateTrueMaskUInt16([ConstantExpected] SveMaskPattern pattern = SveMaskPattern.All) { throw null; } public static System.Numerics.Vector CreateTrueMaskUInt32([ConstantExpected] SveMaskPattern pattern = SveMaskPattern.All) { throw null; } public static System.Numerics.Vector CreateTrueMaskUInt64([ConstantExpected] SveMaskPattern pattern = SveMaskPattern.All) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanMask16Bit(int left, int right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanMask16Bit(long left, long right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanMask16Bit(uint left, uint right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanMask16Bit(ulong left, ulong right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanMask32Bit(int left, int right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanMask32Bit(long left, long right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanMask32Bit(uint left, uint right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanMask32Bit(ulong left, ulong right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanMask64Bit(int left, int right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanMask64Bit(long left, long right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanMask64Bit(uint left, uint right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanMask64Bit(ulong left, ulong right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanMask8Bit(int left, int right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanMask8Bit(long left, long right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanMask8Bit(uint left, uint right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanMask8Bit(ulong left, ulong right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanOrEqualMask16Bit(int left, int right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanOrEqualMask16Bit(long left, long right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanOrEqualMask16Bit(uint left, uint right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanOrEqualMask16Bit(ulong left, ulong right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanOrEqualMask32Bit(int left, int right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanOrEqualMask32Bit(long left, long right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanOrEqualMask32Bit(uint left, uint right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanOrEqualMask32Bit(ulong left, ulong right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanOrEqualMask64Bit(int left, int right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanOrEqualMask64Bit(long left, long right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanOrEqualMask64Bit(uint left, uint right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanOrEqualMask64Bit(ulong left, ulong right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanOrEqualMask8Bit(int left, int right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanOrEqualMask8Bit(long left, long right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanOrEqualMask8Bit(uint left, uint right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanOrEqualMask8Bit(ulong left, ulong 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 ConditionalSelect(System.Numerics.Vector mask, 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 42096d7b697c7..91e67daa18b97 100644 --- a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs +++ b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs @@ -2919,6 +2919,39 @@ ("SveConditionalSelect.template", new Dictionary { ["TestName"] = "Sve_ConditionalSelect_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalSelect", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "(firstOp[i] != 0 ? (result[i] != secondOp[i]) : (result[i] != thirdOp[i]))",}), ("SveConditionalSelect.template", new Dictionary { ["TestName"] = "Sve_ConditionalSelect_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalSelect", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "(firstOp[i] != 0 ? (result[i] != secondOp[i]) : (result[i] != thirdOp[i]))",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask16Bit_Int32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask16Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (Int32)i, right) != (Int32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask16Bit_Int64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask16Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (Int64)i, right) != (Int64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask16Bit_UInt32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask16Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (UInt32)i, right) != (UInt32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask16Bit_UInt64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask16Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (UInt64)i, right) != (UInt64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask32Bit_Int32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask32Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (Int32)i, right) != (Int32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask32Bit_Int64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask32Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (Int64)i, right) != (Int64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask32Bit_UInt32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask32Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (UInt32)i, right) != (UInt32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask32Bit_UInt64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask32Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (UInt64)i, right) != (UInt64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask64Bit_Int32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask64Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (Int32)i, right) != (Int32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask64Bit_Int64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask64Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (Int64)i, right) != (Int64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask64Bit_UInt32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask64Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (UInt32)i, right) != (UInt32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask64Bit_UInt64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask64Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (UInt64)i, right) != (UInt64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask8Bit_Int32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask8Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (Int32)i, right) != (Int32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask8Bit_Int64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask8Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (Int64)i, right) != (Int64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask8Bit_UInt32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask8Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (UInt32)i, right) != (UInt32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask8Bit_UInt64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask8Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (UInt64)i, right) != (UInt64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask16Bit_Int32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask16Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (Int32)i, right) != (Int32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask16Bit_Int64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask16Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (Int64)i, right) != (Int64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask16Bit_UInt32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask16Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (UInt32)i, right) != (UInt32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask16Bit_UInt64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask16Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (UInt64)i, right) != (UInt64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask32Bit_Int32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask32Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (Int32)i, right) != (Int32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask32Bit_Int64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask32Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (Int64)i, right) != (Int64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask32Bit_UInt32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask32Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (UInt32)i, right) != (UInt32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask32Bit_UInt64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask32Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (UInt64)i, right) != (UInt64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask64Bit_Int32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask64Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (Int32)i, right) != (Int32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask64Bit_Int64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask64Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (Int64)i, right) != (Int64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask64Bit_UInt32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask64Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (UInt32)i, right) != (UInt32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask64Bit_UInt64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask64Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (UInt64)i, right) != (UInt64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask8Bit_Int32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask8Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (Int32)i, right) != (Int32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask8Bit_Int64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask8Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (Int64)i, right) != (Int64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask8Bit_UInt32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask8Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (UInt32)i, right) != (UInt32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask8Bit_UInt64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask8Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (UInt64)i, right) != (UInt64)result[i]",}), + ("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/Helpers.cs b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs index 125c187bdd2d4..4b44b29337573 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs @@ -5986,5 +5986,45 @@ public static int DotProduct(int op1, sbyte[] op2, int s, sbyte[] op3, int t) return result; } + + public static int WhileLessThanMask(int op1, int op2) + { + return (op1 < op2) ? 1 : 0; + } + + public static uint WhileLessThanMask(uint op1, uint op2) + { + return (uint)((op1 < op2) ? 1 : 0); + } + + public static long WhileLessThanMask(long op1, long op2) + { + return (op1 < op2) ? 1 : 0; + } + + public static ulong WhileLessThanMask(ulong op1, ulong op2) + { + return (ulong)((op1 < op2) ? 1 : 0); + } + + public static int WhileLessThanOrEqualMask(int op1, int op2) + { + return (op1 <= op2) ? 1 : 0; + } + + public static uint WhileLessThanOrEqualMask(uint op1, uint op2) + { + return (uint)((op1 <= op2) ? 1 : 0); + } + + public static long WhileLessThanOrEqualMask(long op1, long op2) + { + return (op1 <= op2) ? 1 : 0; + } + + public static ulong WhileLessThanOrEqualMask(ulong op1, ulong op2) + { + return (ulong)((op1 <= op2) ? 1 : 0); + } } } diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/ScalarBinOpRetVecTest.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/ScalarBinOpRetVecTest.template new file mode 100644 index 0000000000000..a2434756fae86 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/ScalarBinOpRetVecTest.template @@ -0,0 +1,216 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\Arm\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Numerics; +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 ScalarBinaryOpTest__{TestName}(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.ReadUnaligned + test.RunBasicScenario_UnsafeRead(); + + // Validates calling via reflection works, using Unsafe.ReadUnaligned + test.RunReflectionScenario_UnsafeRead(); + + // Validates passing a local works, using Unsafe.ReadUnaligned + test.RunLclVarScenario_UnsafeRead(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ScalarBinaryOpTest__{TestName} + { + private struct TestStruct + { + public {Op1BaseType} _fld1; + public {Op2BaseType} _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + testStruct._fld1 = {NextValueOp1}; + testStruct._fld2 = {NextValueOp2}; + + return testStruct; + } + + public void RunStructFldScenario(ScalarBinaryOpTest__{TestName} testClass) + { + var result = {Isa}.{Method}(_fld1, _fld2); + testClass.ValidateResult(_fld1, _fld2, result); + } + } + + private static readonly int RetElementCount = Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>() / sizeof({RetBaseType}); + + private static {Op1BaseType} _data1; + private static {Op2BaseType} _data2; + + private {Op1BaseType} _fld1; + private {Op2BaseType} _fld2; + + public ScalarBinaryOpTest__{TestName}() + { + Succeeded = true; + + _fld1 = {NextValueOp1}; + _fld2 = {NextValueOp2}; + + _data1 = {NextValueOp1}; + _data2 = {NextValueOp2}; + } + + public bool IsSupported => {Isa}.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = {Isa}.{Method}( + Unsafe.ReadUnaligned<{Op1BaseType}>(ref Unsafe.As<{Op1BaseType}, byte>(ref _data1)), + Unsafe.ReadUnaligned<{Op2BaseType}>(ref Unsafe.As<{Op2BaseType}, byte>(ref _data2)) + ); + + ValidateResult(_data1, _data2, result); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1BaseType}), typeof({Op2BaseType}) }) + .Invoke(null, new object[] { + Unsafe.ReadUnaligned<{Op1BaseType}>(ref Unsafe.As<{Op1BaseType}, byte>(ref _data1)), + Unsafe.ReadUnaligned<{Op2BaseType}>(ref Unsafe.As<{Op2BaseType}, byte>(ref _data2)) + }); + + ValidateResult(_data1, _data2, ({RetVectorType}<{RetBaseType}>)result); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var data1 = Unsafe.ReadUnaligned<{Op1BaseType}>(ref Unsafe.As<{Op1BaseType}, byte>(ref _data1)); + var data2 = Unsafe.ReadUnaligned<{Op2BaseType}>(ref Unsafe.As<{Op2BaseType}, byte>(ref _data2)); + var result = {Isa}.{Method}(data1, data2); + + ValidateResult(data1, data2, result); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = {Isa}.{Method}(_fld1, _fld2); + ValidateResult(_fld1, _fld2, result); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = {Isa}.{Method}(test._fld1, test._fld2); + + ValidateResult(test._fld1, test._fld2, result); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult({Op1BaseType} left, {Op2BaseType} right, {RetVectorType}<{RetBaseType}> result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (int i = 0; i < RetElementCount; i++) + { + if ({ValidateIterResult}) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetVectorType}<{RetBaseType}>>({Op1BaseType}, {Op2BaseType}): {Method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: {left}"); + TestLibrary.TestFramework.LogInformation($" right: {right}"); + TestLibrary.TestFramework.LogInformation($" result: {result}"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +}