diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 6548dcf30fcf81..0e3986969c161e 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -3377,6 +3377,26 @@ class Compiler CorInfoType simdBaseJitType, unsigned simdSize); + GenTree* gtNewSimdIsEvenIntegerNode(var_types type, + GenTree* op1, + CorInfoType simdBaseJitType, + unsigned simdSize); + + GenTree* gtNewSimdIsFiniteNode(var_types type, + GenTree* op1, + CorInfoType simdBaseJitType, + unsigned simdSize); + + GenTree* gtNewSimdIsInfinityNode(var_types type, + GenTree* op1, + CorInfoType simdBaseJitType, + unsigned simdSize); + + GenTree* gtNewSimdIsIntegerNode(var_types type, + GenTree* op1, + CorInfoType simdBaseJitType, + unsigned simdSize); + GenTree* gtNewSimdIsNaNNode(var_types type, GenTree* op1, CorInfoType simdBaseJitType, @@ -3387,6 +3407,21 @@ class Compiler CorInfoType simdBaseJitType, unsigned simdSize); + GenTree* gtNewSimdIsNegativeInfinityNode(var_types type, + GenTree* op1, + CorInfoType simdBaseJitType, + unsigned simdSize); + + GenTree* gtNewSimdIsNormalNode(var_types type, + GenTree* op1, + CorInfoType simdBaseJitType, + unsigned simdSize); + + GenTree* gtNewSimdIsOddIntegerNode(var_types type, + GenTree* op1, + CorInfoType simdBaseJitType, + unsigned simdSize); + GenTree* gtNewSimdIsPositiveNode(var_types type, GenTree* op1, CorInfoType simdBaseJitType, @@ -3397,6 +3432,11 @@ class Compiler CorInfoType simdBaseJitType, unsigned simdSize); + GenTree* gtNewSimdIsSubnormalNode(var_types type, + GenTree* op1, + CorInfoType simdBaseJitType, + unsigned simdSize); + GenTree* gtNewSimdIsZeroNode(var_types type, GenTree* op1, CorInfoType simdBaseJitType, diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 9154da487bd1fa..ba5407c7d02886 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -23560,6 +23560,166 @@ GenTree* Compiler::gtNewSimdGetUpperNode(var_types type, GenTree* op1, CorInfoTy return gtNewSimdHWIntrinsicNode(type, op1, intrinsicId, simdBaseJitType, simdSize); } +//---------------------------------------------------------------------------------------------- +// Compiler::gtNewSimdIsEvenIntegerNode: Creates a new simd IsEvenInteger node +// +// Arguments: +// type - The return type of SIMD node being created +// op1 - The vector to check for even integers +// simdBaseJitType - The base JIT type of SIMD type of the intrinsic +// simdSize - The size of the SIMD type of the intrinsic +// +// Returns: +// The created IsEvenInteger node +// +GenTree* Compiler::gtNewSimdIsEvenIntegerNode(var_types type, + GenTree* op1, + CorInfoType simdBaseJitType, + unsigned simdSize) +{ + assert(IsBaselineSimdIsaSupportedDebugOnly()); + + assert(varTypeIsSIMD(type)); + assert(getSIMDTypeForSize(simdSize) == type); + + assert(op1 != nullptr); + assert(op1->TypeIs(type)); + + var_types simdBaseType = JitType2PreciseVarType(simdBaseJitType); + assert(varTypeIsIntegral(simdBaseType)); + + op1 = gtNewSimdBinOpNode(GT_AND, type, op1, gtNewOneConNode(type, simdBaseType), simdBaseJitType, simdSize); + return gtNewSimdIsZeroNode(type, op1, simdBaseJitType, simdSize); +} + +//---------------------------------------------------------------------------------------------- +// Compiler::gtNewSimdIsFiniteNode: Creates a new simd IsFinite node +// +// Arguments: +// type - The return type of SIMD node being created +// op1 - The vector to check for finite values +// simdBaseJitType - The base JIT type of SIMD type of the intrinsic +// simdSize - The size of the SIMD type of the intrinsic +// +// Returns: +// The created IsFinite node +// +GenTree* Compiler::gtNewSimdIsFiniteNode(var_types type, GenTree* op1, CorInfoType simdBaseJitType, unsigned simdSize) +{ + assert(IsBaselineSimdIsaSupportedDebugOnly()); + + assert(varTypeIsSIMD(type)); + assert(getSIMDTypeForSize(simdSize) == type); + + assert(op1 != nullptr); + assert(op1->TypeIs(type)); + + var_types simdBaseType = JitType2PreciseVarType(simdBaseJitType); + assert(varTypeIsArithmetic(simdBaseType)); + + if (varTypeIsFloating(simdBaseType)) + { + GenTree* cnsNode; + + if (simdBaseType == TYP_FLOAT) + { + simdBaseType = TYP_INT; + simdBaseJitType = CORINFO_TYPE_UINT; + cnsNode = gtNewIconNode(0x7F800000); + } + else + { + assert(simdBaseType == TYP_DOUBLE); + + simdBaseType = TYP_LONG; + simdBaseJitType = CORINFO_TYPE_ULONG; + cnsNode = gtNewLconNode(0x7FF0000000000000); + } + cnsNode = gtNewSimdCreateBroadcastNode(type, cnsNode, simdBaseJitType, simdSize); + + op1 = gtNewSimdBinOpNode(GT_AND_NOT, type, cnsNode, op1, simdBaseJitType, simdSize); + return gtNewSimdCmpOpNode(GT_NE, type, op1, gtNewZeroConNode(type), simdBaseJitType, simdSize); + } + + assert(varTypeIsIntegral(simdBaseType)); + return gtNewAllBitsSetConNode(type); +} + +//---------------------------------------------------------------------------------------------- +// Compiler::gtNewSimdIsInfinityNode: Creates a new simd IsInfinity node +// +// Arguments: +// type - The return type of SIMD node being created +// op1 - The vector to check for infinities +// simdBaseJitType - The base JIT type of SIMD type of the intrinsic +// simdSize - The size of the SIMD type of the intrinsic +// +// Returns: +// The created IsInfinity node +// +GenTree* Compiler::gtNewSimdIsInfinityNode(var_types type, GenTree* op1, CorInfoType simdBaseJitType, unsigned simdSize) +{ + assert(IsBaselineSimdIsaSupportedDebugOnly()); + + assert(varTypeIsSIMD(type)); + assert(getSIMDTypeForSize(simdSize) == type); + + assert(op1 != nullptr); + assert(op1->TypeIs(type)); + + var_types simdBaseType = JitType2PreciseVarType(simdBaseJitType); + assert(varTypeIsArithmetic(simdBaseType)); + + if (varTypeIsFloating(simdBaseType)) + { + op1 = gtNewSimdAbsNode(type, op1, simdBaseJitType, simdSize); + return gtNewSimdIsPositiveInfinityNode(type, op1, simdBaseJitType, simdSize); + } + return gtNewZeroConNode(type); +} + +//---------------------------------------------------------------------------------------------- +// Compiler::gtNewSimdIsIntegerNode: Creates a new simd IsInteger node +// +// Arguments: +// type - The return type of SIMD node being created +// op1 - The vector to check for integers +// simdBaseJitType - The base JIT type of SIMD type of the intrinsic +// simdSize - The size of the SIMD type of the intrinsic +// +// Returns: +// The created IsInteger node +// +GenTree* Compiler::gtNewSimdIsIntegerNode(var_types type, GenTree* op1, CorInfoType simdBaseJitType, unsigned simdSize) +{ + assert(IsBaselineSimdIsaSupportedDebugOnly()); + + assert(varTypeIsSIMD(type)); + assert(getSIMDTypeForSize(simdSize) == type); + + assert(op1 != nullptr); + assert(op1->TypeIs(type)); + + var_types simdBaseType = JitType2PreciseVarType(simdBaseJitType); + assert(varTypeIsArithmetic(simdBaseType)); + + if (varTypeIsFloating(simdBaseType)) + { + GenTree* op1Dup1 = fgMakeMultiUse(&op1); + GenTree* op1Dup2 = gtCloneExpr(op1Dup1); + + op1 = gtNewSimdIsFiniteNode(type, op1, simdBaseJitType, simdSize); + + op1Dup1 = gtNewSimdTruncNode(type, op1Dup1, simdBaseJitType, simdSize); + GenTree* op2 = gtNewSimdCmpOpNode(GT_EQ, type, op1Dup1, op1Dup2, simdBaseJitType, simdSize); + + return gtNewSimdBinOpNode(GT_AND, type, op1, op2, simdBaseJitType, simdSize); + } + + assert(varTypeIsIntegral(simdBaseType)); + return gtNewAllBitsSetConNode(type); +} + //---------------------------------------------------------------------------------------------- // Compiler::gtNewSimdIsNaNNode: Creates a new simd IsNaN node // @@ -23598,7 +23758,7 @@ GenTree* Compiler::gtNewSimdIsNaNNode(var_types type, GenTree* op1, CorInfoType // // Arguments: // type - The return type of SIMD node being created -// op1 - The vector to check for Negatives +// op1 - The vector to check for negatives // simdBaseJitType - The base JIT type of SIMD type of the intrinsic // simdSize - The size of the SIMD type of the intrinsic // @@ -23634,12 +23794,159 @@ GenTree* Compiler::gtNewSimdIsNegativeNode(var_types type, GenTree* op1, CorInfo return gtNewSimdCmpOpNode(GT_LT, type, op1, gtNewZeroConNode(type), simdBaseJitType, simdSize); } +//---------------------------------------------------------------------------------------------- +// Compiler::gtNewSimdIsNegativeInfinityNode: Creates a new simd IsNegativeInfinity node +// +// Arguments: +// type - The return type of SIMD node being created +// op1 - The vector to check for negative infinities +// simdBaseJitType - The base JIT type of SIMD type of the intrinsic +// simdSize - The size of the SIMD type of the intrinsic +// +// Returns: +// The created IsNegativeInfinity node +// +GenTree* Compiler::gtNewSimdIsNegativeInfinityNode(var_types type, + GenTree* op1, + CorInfoType simdBaseJitType, + unsigned simdSize) +{ + assert(IsBaselineSimdIsaSupportedDebugOnly()); + + assert(varTypeIsSIMD(type)); + assert(getSIMDTypeForSize(simdSize) == type); + + assert(op1 != nullptr); + assert(op1->TypeIs(type)); + + var_types simdBaseType = JitType2PreciseVarType(simdBaseJitType); + assert(varTypeIsArithmetic(simdBaseType)); + + if (varTypeIsFloating(simdBaseType)) + { + GenTree* cnsNode; + + if (simdBaseType == TYP_FLOAT) + { + simdBaseType = TYP_INT; + simdBaseJitType = CORINFO_TYPE_UINT; + cnsNode = gtNewIconNode(0xFF800000); + } + else + { + assert(simdBaseType == TYP_DOUBLE); + + simdBaseType = TYP_LONG; + simdBaseJitType = CORINFO_TYPE_ULONG; + cnsNode = gtNewLconNode(0xFFF0000000000000); + } + cnsNode = gtNewSimdCreateBroadcastNode(type, cnsNode, simdBaseJitType, simdSize); + + return gtNewSimdCmpOpNode(GT_EQ, type, op1, cnsNode, simdBaseJitType, simdSize); + } + return gtNewZeroConNode(type); +} + +//---------------------------------------------------------------------------------------------- +// Compiler::gtNewSimdIsNormalNode: Creates a new simd IsNormal node +// +// Arguments: +// type - The return type of SIMD node being created +// op1 - The vector to check for normal values +// simdBaseJitType - The base JIT type of SIMD type of the intrinsic +// simdSize - The size of the SIMD type of the intrinsic +// +// Returns: +// The created IsNormal node +// +GenTree* Compiler::gtNewSimdIsNormalNode(var_types type, GenTree* op1, CorInfoType simdBaseJitType, unsigned simdSize) +{ + assert(IsBaselineSimdIsaSupportedDebugOnly()); + + assert(varTypeIsSIMD(type)); + assert(getSIMDTypeForSize(simdSize) == type); + + assert(op1 != nullptr); + assert(op1->TypeIs(type)); + + var_types simdBaseType = JitType2PreciseVarType(simdBaseJitType); + assert(varTypeIsArithmetic(simdBaseType)); + + if (varTypeIsFloating(simdBaseType)) + { + op1 = gtNewSimdAbsNode(type, op1, simdBaseJitType, simdSize); + + GenTree* cnsNode1; + GenTree* cnsNode2; + + if (simdBaseType == TYP_FLOAT) + { + simdBaseType = TYP_INT; + simdBaseJitType = CORINFO_TYPE_UINT; + + cnsNode1 = gtNewIconNode(0x00800000); + cnsNode2 = gtNewIconNode(0x7F800000 - 0x00800000); + } + else + { + assert(simdBaseType == TYP_DOUBLE); + + simdBaseType = TYP_LONG; + simdBaseJitType = CORINFO_TYPE_ULONG; + + cnsNode1 = gtNewLconNode(0x0010000000000000); + cnsNode2 = gtNewLconNode(0x7FF0000000000000 - 0x0010000000000000); + } + + cnsNode1 = gtNewSimdCreateBroadcastNode(type, cnsNode1, simdBaseJitType, simdSize); + cnsNode2 = gtNewSimdCreateBroadcastNode(type, cnsNode2, simdBaseJitType, simdSize); + + op1 = gtNewSimdBinOpNode(GT_SUB, type, op1, cnsNode1, simdBaseJitType, simdSize); + return gtNewSimdCmpOpNode(GT_LT, type, op1, cnsNode2, simdBaseJitType, simdSize); + } + + assert(varTypeIsIntegral(simdBaseType)); + return gtNewSimdCmpOpNode(GT_NE, type, op1, gtNewZeroConNode(type), simdBaseJitType, simdSize); +} + +//---------------------------------------------------------------------------------------------- +// Compiler::gtNewSimdIsOddIntegerNode: Creates a new simd IsOddInteger node +// +// Arguments: +// type - The return type of SIMD node being created +// op1 - The vector to check for odd integers +// simdBaseJitType - The base JIT type of SIMD type of the intrinsic +// simdSize - The size of the SIMD type of the intrinsic +// +// Returns: +// The created IsOddInteger node +// +GenTree* Compiler::gtNewSimdIsOddIntegerNode(var_types type, + GenTree* op1, + CorInfoType simdBaseJitType, + unsigned simdSize) +{ + assert(IsBaselineSimdIsaSupportedDebugOnly()); + + assert(varTypeIsSIMD(type)); + assert(getSIMDTypeForSize(simdSize) == type); + + assert(op1 != nullptr); + assert(op1->TypeIs(type)); + + var_types simdBaseType = JitType2PreciseVarType(simdBaseJitType); + assert(varTypeIsIntegral(simdBaseType)); + + op1 = gtNewSimdBinOpNode(GT_AND, type, op1, gtNewOneConNode(type, simdBaseType), simdBaseJitType, simdSize); + return gtNewSimdCmpOpNode(GT_NE, type, op1, gtNewZeroConNode(type), simdBaseJitType, simdSize); +} + //---------------------------------------------------------------------------------------------- // Compiler::gtNewSimdIsPositiveNode: Creates a new simd IsPositive node // // Arguments: // type - The return type of SIMD node being created -// op1 - The vector to check for Positives +// op1 - The vector to check for positives // simdBaseJitType - The base JIT type of SIMD type of the intrinsic // simdSize - The size of the SIMD type of the intrinsic // @@ -23680,7 +23987,7 @@ GenTree* Compiler::gtNewSimdIsPositiveNode(var_types type, GenTree* op1, CorInfo // // Arguments: // type - The return type of SIMD node being created -// op1 - The vector to check for PositiveInfinities +// op1 - The vector to check for positive infinities // simdBaseJitType - The base JIT type of SIMD type of the intrinsic // simdSize - The size of the SIMD type of the intrinsic // @@ -23705,14 +24012,91 @@ GenTree* Compiler::gtNewSimdIsPositiveInfinityNode(var_types type, if (varTypeIsFloating(simdBaseType)) { - double infinity = BitOperations::UInt64BitsToDouble(0x7FF0000000000000); - GenTree* cnsNode = gtNewDconNode(infinity, simdBaseType); - cnsNode = gtNewSimdCreateBroadcastNode(type, cnsNode, simdBaseJitType, simdSize); + GenTree* cnsNode; + + if (simdBaseType == TYP_FLOAT) + { + simdBaseType = TYP_INT; + simdBaseJitType = CORINFO_TYPE_UINT; + cnsNode = gtNewIconNode(0x7F800000); + } + else + { + assert(simdBaseType == TYP_DOUBLE); + + simdBaseType = TYP_LONG; + simdBaseJitType = CORINFO_TYPE_ULONG; + cnsNode = gtNewLconNode(0x7FF0000000000000); + } + cnsNode = gtNewSimdCreateBroadcastNode(type, cnsNode, simdBaseJitType, simdSize); + return gtNewSimdCmpOpNode(GT_EQ, type, op1, cnsNode, simdBaseJitType, simdSize); } return gtNewZeroConNode(type); } +//---------------------------------------------------------------------------------------------- +// Compiler::gtNewSimdIsSubnormalNode: Creates a new simd IsSubnormal node +// +// Arguments: +// type - The return type of SIMD node being created +// op1 - The vector to check for subnormal values +// simdBaseJitType - The base JIT type of SIMD type of the intrinsic +// simdSize - The size of the SIMD type of the intrinsic +// +// Returns: +// The created IsSubnormal node +// +GenTree* Compiler::gtNewSimdIsSubnormalNode(var_types type, + GenTree* op1, + CorInfoType simdBaseJitType, + unsigned simdSize) +{ + assert(IsBaselineSimdIsaSupportedDebugOnly()); + + assert(varTypeIsSIMD(type)); + assert(getSIMDTypeForSize(simdSize) == type); + + assert(op1 != nullptr); + assert(op1->TypeIs(type)); + + var_types simdBaseType = JitType2PreciseVarType(simdBaseJitType); + assert(varTypeIsArithmetic(simdBaseType)); + + if (varTypeIsFloating(simdBaseType)) + { + op1 = gtNewSimdAbsNode(type, op1, simdBaseJitType, simdSize); + + GenTree* cnsNode1; + GenTree* cnsNode2; + + if (simdBaseType == TYP_FLOAT) + { + simdBaseType = TYP_INT; + simdBaseJitType = CORINFO_TYPE_UINT; + + cnsNode2 = gtNewIconNode(0x007FFFFF); + } + else + { + assert(simdBaseType == TYP_DOUBLE); + + simdBaseType = TYP_LONG; + simdBaseJitType = CORINFO_TYPE_ULONG; + + cnsNode2 = gtNewLconNode(0x000FFFFFFFFFFFFF); + } + + cnsNode1 = gtNewOneConNode(type, simdBaseType); + cnsNode2 = gtNewSimdCreateBroadcastNode(type, cnsNode2, simdBaseJitType, simdSize); + + op1 = gtNewSimdBinOpNode(GT_SUB, type, op1, cnsNode1, simdBaseJitType, simdSize); + + return gtNewSimdCmpOpNode(GT_LT, type, op1, cnsNode2, simdBaseJitType, simdSize); + } + return gtNewZeroConNode(type); +} + //---------------------------------------------------------------------------------------------- // Compiler::gtNewSimdIsZeroNode: Creates a new simd IsZero node // diff --git a/src/coreclr/jit/hwintrinsicarm64.cpp b/src/coreclr/jit/hwintrinsicarm64.cpp index fac3e6c6216fe1..be1c577d4bdfaa 100644 --- a/src/coreclr/jit/hwintrinsicarm64.cpp +++ b/src/coreclr/jit/hwintrinsicarm64.cpp @@ -1343,7 +1343,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, case NI_Vector128_op_Equality: { assert(sig->numArgs == 2); - var_types simdType = getSIMDTypeForSize(simdSize); op2 = impSIMDPopStack(); op1 = impSIMDPopStack(); @@ -1356,7 +1355,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, case NI_Vector128_EqualsAny: { assert(sig->numArgs == 2); - var_types simdType = getSIMDTypeForSize(simdSize); op2 = impSIMDPopStack(); op1 = impSIMDPopStack(); @@ -1647,7 +1645,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, case NI_Vector128_GreaterThanAll: { assert(sig->numArgs == 2); - var_types simdType = getSIMDTypeForSize(simdSize); op2 = impSIMDPopStack(); op1 = impSIMDPopStack(); @@ -1660,7 +1657,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, case NI_Vector128_GreaterThanAny: { assert(sig->numArgs == 2); - var_types simdType = getSIMDTypeForSize(simdSize); op2 = impSIMDPopStack(); op1 = impSIMDPopStack(); @@ -1685,7 +1681,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, case NI_Vector128_GreaterThanOrEqualAll: { assert(sig->numArgs == 2); - var_types simdType = getSIMDTypeForSize(simdSize); op2 = impSIMDPopStack(); op1 = impSIMDPopStack(); @@ -1698,7 +1693,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, case NI_Vector128_GreaterThanOrEqualAny: { assert(sig->numArgs == 2); - var_types simdType = getSIMDTypeForSize(simdSize); op2 = impSIMDPopStack(); op1 = impSIMDPopStack(); @@ -1707,12 +1701,54 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, break; } + case NI_Vector64_IsEvenInteger: + case NI_Vector128_IsEvenInteger: + { + assert(sig->numArgs == 1); + + if (varTypeIsFloating(simdBaseType)) + { + // The code for handling floating-point is decently complex but also expected + // to be rare, so we fallback to the managed implementation, which is accelerated + break; + } + + op1 = impSIMDPopStack(); + retNode = gtNewSimdIsEvenIntegerNode(retType, op1, simdBaseJitType, simdSize); + break; + } + + case NI_Vector64_IsFinite: + case NI_Vector128_IsFinite: + { + assert(sig->numArgs == 1); + op1 = impSIMDPopStack(); + retNode = gtNewSimdIsFiniteNode(retType, op1, simdBaseJitType, simdSize); + break; + } + + case NI_Vector64_IsInfinity: + case NI_Vector128_IsInfinity: + { + assert(sig->numArgs == 1); + op1 = impSIMDPopStack(); + retNode = gtNewSimdIsInfinityNode(retType, op1, simdBaseJitType, simdSize); + break; + } + + case NI_Vector64_IsInteger: + case NI_Vector128_IsInteger: + { + assert(sig->numArgs == 1); + op1 = impSIMDPopStack(); + retNode = gtNewSimdIsIntegerNode(retType, op1, simdBaseJitType, simdSize); + break; + } + case NI_Vector64_IsNaN: case NI_Vector128_IsNaN: { assert(sig->numArgs == 1); - var_types simdType = getSIMDTypeForSize(simdSize); - op1 = impSIMDPopStack(); retNode = gtNewSimdIsNaNNode(retType, op1, simdBaseJitType, simdSize); break; @@ -1722,19 +1758,50 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, case NI_Vector128_IsNegative: { assert(sig->numArgs == 1); - var_types simdType = getSIMDTypeForSize(simdSize); - op1 = impSIMDPopStack(); retNode = gtNewSimdIsNegativeNode(retType, op1, simdBaseJitType, simdSize); break; } + case NI_Vector64_IsNegativeInfinity: + case NI_Vector128_IsNegativeInfinity: + { + assert(sig->numArgs == 1); + op1 = impSIMDPopStack(); + retNode = gtNewSimdIsNegativeInfinityNode(retType, op1, simdBaseJitType, simdSize); + break; + } + + case NI_Vector64_IsNormal: + case NI_Vector128_IsNormal: + { + assert(sig->numArgs == 1); + op1 = impSIMDPopStack(); + retNode = gtNewSimdIsNormalNode(retType, op1, simdBaseJitType, simdSize); + break; + } + + case NI_Vector64_IsOddInteger: + case NI_Vector128_IsOddInteger: + { + assert(sig->numArgs == 1); + + if (varTypeIsFloating(simdBaseType)) + { + // The code for handling floating-point is decently complex but also expected + // to be rare, so we fallback to the managed implementation, which is accelerated + break; + } + + op1 = impSIMDPopStack(); + retNode = gtNewSimdIsOddIntegerNode(retType, op1, simdBaseJitType, simdSize); + break; + } + case NI_Vector64_IsPositive: case NI_Vector128_IsPositive: { assert(sig->numArgs == 1); - var_types simdType = getSIMDTypeForSize(simdSize); - op1 = impSIMDPopStack(); retNode = gtNewSimdIsPositiveNode(retType, op1, simdBaseJitType, simdSize); break; @@ -1744,19 +1811,24 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, case NI_Vector128_IsPositiveInfinity: { assert(sig->numArgs == 1); - var_types simdType = getSIMDTypeForSize(simdSize); - op1 = impSIMDPopStack(); retNode = gtNewSimdIsPositiveInfinityNode(retType, op1, simdBaseJitType, simdSize); break; } + case NI_Vector64_IsSubnormal: + case NI_Vector128_IsSubnormal: + { + assert(sig->numArgs == 1); + op1 = impSIMDPopStack(); + retNode = gtNewSimdIsSubnormalNode(retType, op1, simdBaseJitType, simdSize); + break; + } + case NI_Vector64_IsZero: case NI_Vector128_IsZero: { assert(sig->numArgs == 1); - var_types simdType = getSIMDTypeForSize(simdSize); - op1 = impSIMDPopStack(); retNode = gtNewSimdIsZeroNode(retType, op1, simdBaseJitType, simdSize); break; @@ -1778,7 +1850,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, case NI_Vector128_LessThanAll: { assert(sig->numArgs == 2); - var_types simdType = getSIMDTypeForSize(simdSize); op2 = impSIMDPopStack(); op1 = impSIMDPopStack(); @@ -1791,7 +1862,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, case NI_Vector128_LessThanAny: { assert(sig->numArgs == 2); - var_types simdType = getSIMDTypeForSize(simdSize); op2 = impSIMDPopStack(); op1 = impSIMDPopStack(); @@ -1816,7 +1886,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, case NI_Vector128_LessThanOrEqualAll: { assert(sig->numArgs == 2); - var_types simdType = getSIMDTypeForSize(simdSize); op2 = impSIMDPopStack(); op1 = impSIMDPopStack(); @@ -1829,7 +1898,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, case NI_Vector128_LessThanOrEqualAny: { assert(sig->numArgs == 2); - var_types simdType = getSIMDTypeForSize(simdSize); op2 = impSIMDPopStack(); op1 = impSIMDPopStack(); @@ -2068,7 +2136,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, case NI_Vector128_op_Inequality: { assert(sig->numArgs == 2); - var_types simdType = getSIMDTypeForSize(simdSize); op2 = impSIMDPopStack(); op1 = impSIMDPopStack(); @@ -2153,6 +2220,35 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, break; } + case NI_Vector64_ShiftLeft: + case NI_Vector128_ShiftLeft: + { + assert(sig->numArgs == 2); + + if (!varTypeIsSIMD(impStackTop(0).val)) + { + // We just want the inlining profitability boost for the helper intrinsics/ + // that have operator alternatives like `simd << int` + break; + } + + op2 = impSIMDPopStack(); + op1 = impSIMDPopStack(); + + if (simdSize == 8) + { + intrinsic = varTypeIsLong(simdBaseType) ? NI_AdvSimd_ShiftLogicalScalar : NI_AdvSimd_ShiftLogical; + } + else + { + assert(simdSize == 16); + intrinsic = NI_AdvSimd_ShiftLogical; + } + + retNode = gtNewSimdHWIntrinsicNode(retType, op1, op2, intrinsic, simdBaseJitType, simdSize); + break; + } + case NI_Vector64_Shuffle: case NI_Vector128_Shuffle: { @@ -2251,8 +2347,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, simdSize = 16; } - var_types simdType = getSIMDTypeForSize(simdSize); - op1 = impPopStack().val; + op1 = impPopStack().val; if (op1->OperIs(GT_CAST) && op1->gtGetOp1()->TypeIs(TYP_BYREF)) { @@ -2269,7 +2364,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, case NI_Vector128_StoreUnsafe: { assert(retType == TYP_VOID); - var_types simdType = getSIMDTypeForSize(simdSize); if (sig->numArgs == 3) { @@ -2321,8 +2415,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, break; } - var_types simdType = getSIMDTypeForSize(simdSize); - impSpillSideEffect(true, stackState.esStackDepth - 2 DEBUGARG("Spilling op1 side effects for HWIntrinsic")); op2 = impPopStack().val; @@ -2353,8 +2445,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, break; } - var_types simdType = getSIMDTypeForSize(simdSize); - impSpillSideEffect(true, stackState.esStackDepth - 2 DEBUGARG("Spilling op1 side effects for HWIntrinsic")); op2 = impPopStack().val; @@ -2486,8 +2576,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, case NI_Vector128_Sum: { assert(sig->numArgs == 1); - var_types simdType = getSIMDTypeForSize(simdSize); - op1 = impSIMDPopStack(); retNode = gtNewSimdSumNode(retType, op1, simdBaseJitType, simdSize); break; diff --git a/src/coreclr/jit/hwintrinsiclistarm64.h b/src/coreclr/jit/hwintrinsiclistarm64.h index 0481923bf929d0..efad7ee0980253 100644 --- a/src/coreclr/jit/hwintrinsiclistarm64.h +++ b/src/coreclr/jit/hwintrinsiclistarm64.h @@ -60,10 +60,18 @@ HARDWARE_INTRINSIC(Vector64, GreaterThanAny, HARDWARE_INTRINSIC(Vector64, GreaterThanOrEqual, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector64, GreaterThanOrEqualAll, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector64, GreaterThanOrEqualAny, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector64, IsEvenInteger, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(Vector64, IsFinite, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(Vector64, IsInfinity, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(Vector64, IsInteger, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector64, IsNaN, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector64, IsNegative, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(Vector64, IsNegativeInfinity, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(Vector64, IsNormal, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(Vector64, IsOddInteger, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector64, IsPositive, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector64, IsPositiveInfinity, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(Vector64, IsSubnormal, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector64, IsZero, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector64, LessThan, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector64, LessThanAll, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId|HW_Flag_BaseTypeFromFirstArg) @@ -81,6 +89,7 @@ HARDWARE_INTRINSIC(Vector64, MinNative, HARDWARE_INTRINSIC(Vector64, MultiplyAddEstimate, 8, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector64, Narrow, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector64, Round, 8, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(Vector64, ShiftLeft, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector64, Shuffle, 8, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_CanBenefitFromConstantProp) HARDWARE_INTRINSIC(Vector64, Sqrt, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector64, StoreAligned, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId|HW_Flag_BaseTypeFromFirstArg) @@ -173,10 +182,18 @@ HARDWARE_INTRINSIC(Vector128, GreaterThanAny, HARDWARE_INTRINSIC(Vector128, GreaterThanOrEqual, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector128, GreaterThanOrEqualAll, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector128, GreaterThanOrEqualAny, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector128, IsEvenInteger, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(Vector128, IsFinite, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(Vector128, IsInfinity, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(Vector128, IsInteger, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector128, IsNaN, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector128, IsNegative, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(Vector128, IsNegativeInfinity, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(Vector128, IsNormal, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(Vector128, IsOddInteger, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector128, IsPositive, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector128, IsPositiveInfinity, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(Vector128, IsSubnormal, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector128, IsZero, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector128, LessThan, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector128, LessThanAll, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId|HW_Flag_BaseTypeFromFirstArg) @@ -194,6 +211,7 @@ HARDWARE_INTRINSIC(Vector128, MinNative, HARDWARE_INTRINSIC(Vector128, MultiplyAddEstimate, 16, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector128, Narrow, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector128, Round, 16, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(Vector128, ShiftLeft, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector128, Shuffle, 16, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_CanBenefitFromConstantProp) HARDWARE_INTRINSIC(Vector128, Sqrt, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector128, StoreAligned, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId|HW_Flag_BaseTypeFromFirstArg) diff --git a/src/coreclr/jit/hwintrinsiclistxarch.h b/src/coreclr/jit/hwintrinsiclistxarch.h index 970491b52661b4..b76781500c56fa 100644 --- a/src/coreclr/jit/hwintrinsiclistxarch.h +++ b/src/coreclr/jit/hwintrinsiclistxarch.h @@ -78,10 +78,18 @@ HARDWARE_INTRINSIC(Vector128, GreaterThanAny, HARDWARE_INTRINSIC(Vector128, GreaterThanOrEqual, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector128, GreaterThanOrEqualAll, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector128, GreaterThanOrEqualAny, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector128, IsEvenInteger, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(Vector128, IsFinite, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(Vector128, IsInfinity, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(Vector128, IsInteger, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector128, IsNaN, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector128, IsNegative, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(Vector128, IsNegativeInfinity, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(Vector128, IsNormal, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(Vector128, IsOddInteger, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector128, IsPositive, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector128, IsPositiveInfinity, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(Vector128, IsSubnormal, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector128, IsZero, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector128, LessThan, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector128, LessThanAll, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId|HW_Flag_BaseTypeFromFirstArg) @@ -99,6 +107,7 @@ HARDWARE_INTRINSIC(Vector128, MinNative, HARDWARE_INTRINSIC(Vector128, MultiplyAddEstimate, 16, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector128, Narrow, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector128, Round, 16, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(Vector128, ShiftLeft, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector128, Shuffle, 16, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_CanBenefitFromConstantProp) HARDWARE_INTRINSIC(Vector128, Sqrt, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector128, StoreAligned, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId|HW_Flag_BaseTypeFromFirstArg) @@ -188,10 +197,18 @@ HARDWARE_INTRINSIC(Vector256, GreaterThanAny, HARDWARE_INTRINSIC(Vector256, GreaterThanOrEqual, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector256, GreaterThanOrEqualAll, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector256, GreaterThanOrEqualAny, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector256, IsEvenInteger, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(Vector256, IsFinite, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(Vector256, IsInfinity, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(Vector256, IsInteger, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector256, IsNaN, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector256, IsNegative, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(Vector256, IsNegativeInfinity, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(Vector256, IsNormal, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(Vector256, IsOddInteger, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector256, IsPositive, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector256, IsPositiveInfinity, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(Vector256, IsSubnormal, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector256, IsZero, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector256, LessThan, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector256, LessThanAll, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId|HW_Flag_BaseTypeFromFirstArg) @@ -209,6 +226,7 @@ HARDWARE_INTRINSIC(Vector256, MinNative, HARDWARE_INTRINSIC(Vector256, MultiplyAddEstimate, 32, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector256, Narrow, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector256, Round, 32, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(Vector256, ShiftLeft, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector256, Shuffle, 32, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_CanBenefitFromConstantProp) HARDWARE_INTRINSIC(Vector256, Sqrt, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId|HW_Flag_AvxOnlyCompatible) HARDWARE_INTRINSIC(Vector256, StoreAligned, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId|HW_Flag_BaseTypeFromFirstArg|HW_Flag_AvxOnlyCompatible) @@ -299,10 +317,18 @@ HARDWARE_INTRINSIC(Vector512, GreaterThanAny, HARDWARE_INTRINSIC(Vector512, GreaterThanOrEqual, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector512, GreaterThanOrEqualAll, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector512, GreaterThanOrEqualAny, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector512, IsEvenInteger, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(Vector512, IsFinite, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(Vector512, IsInfinity, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(Vector512, IsInteger, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector512, IsNaN, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector512, IsNegative, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(Vector512, IsNegativeInfinity, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(Vector512, IsNormal, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(Vector512, IsOddInteger, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector512, IsPositive, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector512, IsPositiveInfinity, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(Vector512, IsSubnormal, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector512, IsZero, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector512, LessThan, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector512, LessThanAll, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId|HW_Flag_BaseTypeFromFirstArg) @@ -320,6 +346,7 @@ HARDWARE_INTRINSIC(Vector512, MinNative, HARDWARE_INTRINSIC(Vector512, MultiplyAddEstimate, 64, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector512, Narrow, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector512, Round, 64, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(Vector512, ShiftLeft, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector512, Shuffle, 64, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_CanBenefitFromConstantProp) HARDWARE_INTRINSIC(Vector512, Sqrt, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(Vector512, StoreAligned, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_InvalidNodeId|HW_Flag_BaseTypeFromFirstArg) diff --git a/src/coreclr/jit/hwintrinsicxarch.cpp b/src/coreclr/jit/hwintrinsicxarch.cpp index 4d0ebbe19b9f9f..c30bb266edee01 100644 --- a/src/coreclr/jit/hwintrinsicxarch.cpp +++ b/src/coreclr/jit/hwintrinsicxarch.cpp @@ -2800,8 +2800,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, if ((simdSize != 32) || compOpportunisticallyDependsOn(InstructionSet_AVX2)) { - var_types simdType = getSIMDTypeForSize(simdSize); - op2 = impSIMDPopStack(); op1 = impSIMDPopStack(); @@ -2818,8 +2816,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, if ((simdSize != 32) || compOpportunisticallyDependsOn(InstructionSet_AVX2)) { - var_types simdType = getSIMDTypeForSize(simdSize); - op2 = impSIMDPopStack(); op1 = impSIMDPopStack(); @@ -2853,8 +2849,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, if ((simdSize != 32) || compOpportunisticallyDependsOn(InstructionSet_AVX2)) { - var_types simdType = getSIMDTypeForSize(simdSize); - op2 = impSIMDPopStack(); op1 = impSIMDPopStack(); @@ -2871,8 +2865,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, if ((simdSize != 32) || compOpportunisticallyDependsOn(InstructionSet_AVX2)) { - var_types simdType = getSIMDTypeForSize(simdSize); - op2 = impSIMDPopStack(); op1 = impSIMDPopStack(); @@ -2881,13 +2873,71 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, break; } + case NI_Vector128_IsEvenInteger: + case NI_Vector256_IsEvenInteger: + case NI_Vector512_IsEvenInteger: + { + assert(sig->numArgs == 1); + + if (varTypeIsFloating(simdBaseType)) + { + // The code for handling floating-point is decently complex but also expected + // to be rare, so we fallback to the managed implementation, which is accelerated + break; + } + + op1 = impSIMDPopStack(); + retNode = gtNewSimdIsEvenIntegerNode(retType, op1, simdBaseJitType, simdSize); + break; + } + + case NI_Vector128_IsFinite: + case NI_Vector256_IsFinite: + case NI_Vector512_IsFinite: + { + assert(sig->numArgs == 1); + + if ((simdSize != 32) || compOpportunisticallyDependsOn(InstructionSet_AVX2)) + { + op1 = impSIMDPopStack(); + retNode = gtNewSimdIsFiniteNode(retType, op1, simdBaseJitType, simdSize); + } + break; + } + + case NI_Vector128_IsInfinity: + case NI_Vector256_IsInfinity: + case NI_Vector512_IsInfinity: + { + assert(sig->numArgs == 1); + + if ((simdSize != 32) || compOpportunisticallyDependsOn(InstructionSet_AVX2)) + { + op1 = impSIMDPopStack(); + retNode = gtNewSimdIsInfinityNode(retType, op1, simdBaseJitType, simdSize); + } + break; + } + + case NI_Vector128_IsInteger: + case NI_Vector256_IsInteger: + case NI_Vector512_IsInteger: + { + assert(sig->numArgs == 1); + + if ((simdSize != 32) || compOpportunisticallyDependsOn(InstructionSet_AVX2)) + { + op1 = impSIMDPopStack(); + retNode = gtNewSimdIsIntegerNode(retType, op1, simdBaseJitType, simdSize); + } + break; + } + case NI_Vector128_IsNaN: case NI_Vector256_IsNaN: case NI_Vector512_IsNaN: { assert(sig->numArgs == 1); - var_types simdType = getSIMDTypeForSize(simdSize); - op1 = impSIMDPopStack(); retNode = gtNewSimdIsNaNNode(retType, op1, simdBaseJitType, simdSize); break; @@ -2901,13 +2951,58 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, if ((simdSize != 32) || compOpportunisticallyDependsOn(InstructionSet_AVX2)) { - var_types simdType = getSIMDTypeForSize(simdSize); - op1 = impSIMDPopStack(); - retNode = gtNewSimdIsNegativeNode(retType, op1, simdBaseJitType, simdSize); + op1 = impSIMDPopStack(); + retNode = gtNewSimdIsNegativeNode(retType, op1, simdBaseJitType, simdSize); } break; } + case NI_Vector128_IsNegativeInfinity: + case NI_Vector256_IsNegativeInfinity: + case NI_Vector512_IsNegativeInfinity: + { + assert(sig->numArgs == 1); + + if ((simdSize != 32) || compOpportunisticallyDependsOn(InstructionSet_AVX2)) + { + op1 = impSIMDPopStack(); + retNode = gtNewSimdIsNegativeInfinityNode(retType, op1, simdBaseJitType, simdSize); + } + break; + } + + case NI_Vector128_IsNormal: + case NI_Vector256_IsNormal: + case NI_Vector512_IsNormal: + { + assert(sig->numArgs == 1); + + if ((simdSize != 32) || compOpportunisticallyDependsOn(InstructionSet_AVX2)) + { + op1 = impSIMDPopStack(); + retNode = gtNewSimdIsNormalNode(retType, op1, simdBaseJitType, simdSize); + } + break; + } + + case NI_Vector128_IsOddInteger: + case NI_Vector256_IsOddInteger: + case NI_Vector512_IsOddInteger: + { + assert(sig->numArgs == 1); + + if (varTypeIsFloating(simdBaseType)) + { + // The code for handling floating-point is decently complex but also expected + // to be rare, so we fallback to the managed implementation, which is accelerated + break; + } + + op1 = impSIMDPopStack(); + retNode = gtNewSimdIsOddIntegerNode(retType, op1, simdBaseJitType, simdSize); + break; + } + case NI_Vector128_IsPositive: case NI_Vector256_IsPositive: case NI_Vector512_IsPositive: @@ -2916,9 +3011,8 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, if ((simdSize != 32) || compOpportunisticallyDependsOn(InstructionSet_AVX2)) { - var_types simdType = getSIMDTypeForSize(simdSize); - op1 = impSIMDPopStack(); - retNode = gtNewSimdIsPositiveNode(retType, op1, simdBaseJitType, simdSize); + op1 = impSIMDPopStack(); + retNode = gtNewSimdIsPositiveNode(retType, op1, simdBaseJitType, simdSize); } break; } @@ -2928,10 +3022,26 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, case NI_Vector512_IsPositiveInfinity: { assert(sig->numArgs == 1); - var_types simdType = getSIMDTypeForSize(simdSize); - op1 = impSIMDPopStack(); - retNode = gtNewSimdIsPositiveInfinityNode(retType, op1, simdBaseJitType, simdSize); + if ((simdSize != 32) || compOpportunisticallyDependsOn(InstructionSet_AVX2)) + { + op1 = impSIMDPopStack(); + retNode = gtNewSimdIsPositiveInfinityNode(retType, op1, simdBaseJitType, simdSize); + } + break; + } + + case NI_Vector128_IsSubnormal: + case NI_Vector256_IsSubnormal: + case NI_Vector512_IsSubnormal: + { + assert(sig->numArgs == 1); + + if ((simdSize != 32) || compOpportunisticallyDependsOn(InstructionSet_AVX2)) + { + op1 = impSIMDPopStack(); + retNode = gtNewSimdIsSubnormalNode(retType, op1, simdBaseJitType, simdSize); + } break; } @@ -2940,8 +3050,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, case NI_Vector512_IsZero: { assert(sig->numArgs == 1); - var_types simdType = getSIMDTypeForSize(simdSize); - op1 = impSIMDPopStack(); retNode = gtNewSimdIsZeroNode(retType, op1, simdBaseJitType, simdSize); break; @@ -2972,8 +3080,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, if ((simdSize != 32) || compOpportunisticallyDependsOn(InstructionSet_AVX2)) { - var_types simdType = getSIMDTypeForSize(simdSize); - op2 = impSIMDPopStack(); op1 = impSIMDPopStack(); @@ -2990,8 +3096,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, if ((simdSize != 32) || compOpportunisticallyDependsOn(InstructionSet_AVX2)) { - var_types simdType = getSIMDTypeForSize(simdSize); - op2 = impSIMDPopStack(); op1 = impSIMDPopStack(); @@ -3025,8 +3129,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, if ((simdSize != 32) || compOpportunisticallyDependsOn(InstructionSet_AVX2)) { - var_types simdType = getSIMDTypeForSize(simdSize); - op2 = impSIMDPopStack(); op1 = impSIMDPopStack(); @@ -3043,8 +3145,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, if ((simdSize != 32) || compOpportunisticallyDependsOn(InstructionSet_AVX2)) { - var_types simdType = getSIMDTypeForSize(simdSize); - op2 = impSIMDPopStack(); op1 = impSIMDPopStack(); @@ -3368,8 +3468,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, if ((simdSize != 32) || varTypeIsFloating(simdBaseType) || compOpportunisticallyDependsOn(InstructionSet_AVX2)) { - var_types simdType = getSIMDTypeForSize(simdSize); - op2 = impSIMDPopStack(); op1 = impSIMDPopStack(); @@ -3384,8 +3482,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, if (IsBaselineVector512IsaSupportedOpportunistically()) { - var_types simdType = getSIMDTypeForSize(simdSize); - op2 = impSIMDPopStack(); op1 = impSIMDPopStack(); @@ -3509,6 +3605,39 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, break; } + case NI_Vector128_ShiftLeft: + case NI_Vector256_ShiftLeft: + case NI_Vector512_ShiftLeft: + { + assert(sig->numArgs == 2); + + if (!varTypeIsSIMD(impStackTop(0).val)) + { + // We just want the inlining profitability boost for the helper intrinsics/ + // that have operator alternatives like `simd << int` + break; + } + + if ((simdSize != 16) || compOpportunisticallyDependsOn(InstructionSet_AVX2)) + { + op2 = impSIMDPopStack(); + op1 = impSIMDPopStack(); + + if (simdSize == 64) + { + intrinsic = NI_AVX512F_ShiftLeftLogicalVariable; + } + else + { + assert((simdSize == 16) || (simdSize == 32)); + intrinsic = NI_AVX2_ShiftLeftLogicalVariable; + } + + retNode = gtNewSimdHWIntrinsicNode(retType, op1, op2, intrinsic, simdBaseJitType, simdSize); + } + break; + } + case NI_Vector128_Shuffle: case NI_Vector256_Shuffle: case NI_Vector512_Shuffle: @@ -3571,8 +3700,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, assert(retType == TYP_VOID); assert(sig->numArgs == 2); - var_types simdType = getSIMDTypeForSize(simdSize); - op2 = impSIMDPopStack(); op1 = impPopStack().val; @@ -3591,7 +3718,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, case NI_Vector512_StoreUnsafe: { assert(retType == TYP_VOID); - var_types simdType = getSIMDTypeForSize(simdSize); if (sig->numArgs == 3) { @@ -3636,8 +3762,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, assert(sig->numArgs == 2); assert(retType == TYP_VOID); - var_types simdType = getSIMDTypeForSize(simdSize); - impSpillSideEffect(true, stackState.esStackDepth - 2 DEBUGARG("Spilling op1 side effects for HWIntrinsic")); op2 = impPopStack().val; @@ -3661,8 +3785,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, assert(sig->numArgs == 2); assert(retType == TYP_VOID); - var_types simdType = getSIMDTypeForSize(simdSize); - impSpillSideEffect(true, stackState.esStackDepth - 2 DEBUGARG("Spilling op1 side effects for HWIntrinsic")); op2 = impPopStack().val; @@ -3684,7 +3806,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, case NI_Vector512_Sum: { assert(sig->numArgs == 1); - var_types simdType = getSIMDTypeForSize(simdSize); if ((simdSize == 32) && !compOpportunisticallyDependsOn(InstructionSet_AVX2)) { diff --git a/src/libraries/Common/tests/System/GenericMathTestMemberData.cs b/src/libraries/Common/tests/System/GenericMathTestMemberData.cs index 0e19ac826dfdda..0e314aa9e9a27f 100644 --- a/src/libraries/Common/tests/System/GenericMathTestMemberData.cs +++ b/src/libraries/Common/tests/System/GenericMathTestMemberData.cs @@ -676,23 +676,201 @@ public static IEnumerable HypotSingle } } + public static IEnumerable IsTestByte + { + get + { + yield return new object[] { byte.MinValue }; + yield return new object[] { 1.0 }; + yield return new object[] { 2.0 }; + yield return new object[] { 3.0 }; + yield return new object[] { sbyte.MaxValue }; + yield return new object[] { byte.MaxValue }; + } + } + + public static IEnumerable IsTestDouble + { + get + { + yield return new object[] { double.NegativeInfinity }; + yield return new object[] { double.MinValue }; + yield return new object[] { -1.0 }; + yield return new object[] { -MinNormalDouble }; + yield return new object[] { -MaxSubnormalDouble }; + yield return new object[] { -double.Epsilon }; + yield return new object[] { -0.0 }; + yield return new object[] { double.NaN }; + yield return new object[] { 0.0 }; + yield return new object[] { double.Epsilon }; + yield return new object[] { MaxSubnormalDouble }; + yield return new object[] { MinNormalDouble }; + yield return new object[] { 1.0 }; + yield return new object[] { double.MaxValue }; + yield return new object[] { double.PositiveInfinity }; + } + } + + public static IEnumerable IsTestInt16 + { + get + { + yield return new object[] { short.MinValue }; + yield return new object[] { sbyte.MinValue }; + yield return new object[] { -3.0 }; + yield return new object[] { -2.0 }; + yield return new object[] { -1.0 }; + yield return new object[] { 0.0 }; + yield return new object[] { 1.0 }; + yield return new object[] { 2.0 }; + yield return new object[] { 3.0 }; + yield return new object[] { sbyte.MaxValue }; + yield return new object[] { byte.MaxValue }; + yield return new object[] { short.MaxValue }; + } + } + + public static IEnumerable IsTestInt32 + { + get + { + yield return new object[] { int.MinValue }; + yield return new object[] { short.MinValue }; + yield return new object[] { sbyte.MinValue }; + yield return new object[] { -3.0 }; + yield return new object[] { -2.0 }; + yield return new object[] { -1.0 }; + yield return new object[] { 0.0 }; + yield return new object[] { 1.0 }; + yield return new object[] { 2.0 }; + yield return new object[] { 3.0 }; + yield return new object[] { sbyte.MaxValue }; + yield return new object[] { byte.MaxValue }; + yield return new object[] { short.MaxValue }; + yield return new object[] { int.MaxValue }; + } + } + + public static IEnumerable IsTestInt64 + { + get + { + yield return new object[] { long.MinValue }; + yield return new object[] { int.MinValue }; + yield return new object[] { short.MinValue }; + yield return new object[] { sbyte.MinValue }; + yield return new object[] { -3.0 }; + yield return new object[] { -2.0 }; + yield return new object[] { -1.0 }; + yield return new object[] { 0.0 }; + yield return new object[] { 1.0 }; + yield return new object[] { 2.0 }; + yield return new object[] { 3.0 }; + yield return new object[] { sbyte.MaxValue }; + yield return new object[] { byte.MaxValue }; + yield return new object[] { short.MaxValue }; + yield return new object[] { int.MaxValue }; + yield return new object[] { long.MaxValue }; + } + } + + public static IEnumerable IsTestSByte + { + get + { + yield return new object[] { sbyte.MinValue }; + yield return new object[] { -3.0 }; + yield return new object[] { -2.0 }; + yield return new object[] { -1.0 }; + yield return new object[] { 0.0 }; + yield return new object[] { 1.0 }; + yield return new object[] { 2.0 }; + yield return new object[] { 3.0 }; + yield return new object[] { sbyte.MaxValue }; + } + } + + public static IEnumerable IsTestSingle + { + get + { + yield return new object[] { float.NegativeInfinity }; + yield return new object[] { float.MinValue }; + yield return new object[] { -1.0f }; + yield return new object[] { -MinNormalSingle }; + yield return new object[] { -MaxSubnormalSingle }; + yield return new object[] { -float.Epsilon }; + yield return new object[] { -0.0f }; + yield return new object[] { float.NaN }; + yield return new object[] { 0.0f }; + yield return new object[] { float.Epsilon }; + yield return new object[] { MaxSubnormalSingle }; + yield return new object[] { MinNormalSingle }; + yield return new object[] { 1.0f }; + yield return new object[] { float.MaxValue }; + yield return new object[] { float.PositiveInfinity }; + } + } + + public static IEnumerable IsTestUInt16 + { + get + { + yield return new object[] { ushort.MinValue }; + yield return new object[] { 1.0 }; + yield return new object[] { 2.0 }; + yield return new object[] { 3.0 }; + yield return new object[] { sbyte.MaxValue }; + yield return new object[] { byte.MaxValue }; + yield return new object[] { short.MaxValue }; + yield return new object[] { ushort.MaxValue }; + } + } + + public static IEnumerable IsTestUInt32 + { + get + { + yield return new object[] { uint.MinValue }; + yield return new object[] { sbyte.MaxValue }; + yield return new object[] { byte.MaxValue }; + yield return new object[] { short.MaxValue }; + yield return new object[] { int.MaxValue }; + yield return new object[] { uint.MaxValue }; + } + } + + public static IEnumerable IsTestUInt64 + { + get + { + yield return new object[] { ulong.MinValue }; + yield return new object[] { sbyte.MaxValue }; + yield return new object[] { byte.MaxValue }; + yield return new object[] { short.MaxValue }; + yield return new object[] { int.MaxValue }; + yield return new object[] { long.MaxValue }; + yield return new object[] { ulong.MaxValue }; + } + } + public static IEnumerable IsNaNDouble { get { - yield return new object[] { double.NegativeInfinity, false }; - yield return new object[] { double.MinValue, false }; - yield return new object[] { -MinNormalDouble, false }; - yield return new object[] { -MaxSubnormalDouble, false }; - yield return new object[] { -double.Epsilon, false }; - yield return new object[] { -0.0, false }; - yield return new object[] { double.NaN, true }; - yield return new object[] { 0.0, false }; - yield return new object[] { double.Epsilon, false }; - yield return new object[] { MaxSubnormalDouble, false }; - yield return new object[] { MinNormalDouble, false }; - yield return new object[] { double.MaxValue, false }; - yield return new object[] { double.PositiveInfinity, false }; + yield return new object[] { double.NegativeInfinity, false }; + yield return new object[] { double.MinValue, false }; + yield return new object[] { -MinNormalDouble, false }; + yield return new object[] { -MaxSubnormalDouble, false }; + yield return new object[] { -double.Epsilon, false }; + yield return new object[] { -0.0, false }; + yield return new object[] { double.NaN, true }; + yield return new object[] { 0.0, false }; + yield return new object[] { double.Epsilon, false }; + yield return new object[] { MaxSubnormalDouble, false }; + yield return new object[] { MinNormalDouble, false }; + yield return new object[] { double.MaxValue, false }; + yield return new object[] { double.PositiveInfinity, false }; } } @@ -700,19 +878,19 @@ public static IEnumerable IsNaNSingle { get { - yield return new object[] { float.NegativeInfinity, false }; - yield return new object[] { float.MinValue, false }; - yield return new object[] { -MinNormalSingle, false }; - yield return new object[] { -MaxSubnormalSingle, false }; - yield return new object[] { -float.Epsilon, false }; - yield return new object[] { -0.0f, false }; - yield return new object[] { float.NaN, true }; - yield return new object[] { 0.0f, false }; - yield return new object[] { float.Epsilon, false }; - yield return new object[] { MaxSubnormalSingle, false }; - yield return new object[] { MinNormalSingle, false }; - yield return new object[] { float.MaxValue, false }; - yield return new object[] { float.PositiveInfinity, false }; + yield return new object[] { float.NegativeInfinity, false }; + yield return new object[] { float.MinValue, false }; + yield return new object[] { -MinNormalSingle, false }; + yield return new object[] { -MaxSubnormalSingle, false }; + yield return new object[] { -float.Epsilon, false }; + yield return new object[] { -0.0f, false }; + yield return new object[] { float.NaN, true }; + yield return new object[] { 0.0f, false }; + yield return new object[] { float.Epsilon, false }; + yield return new object[] { MaxSubnormalSingle, false }; + yield return new object[] { MinNormalSingle, false }; + yield return new object[] { float.MaxValue, false }; + yield return new object[] { float.PositiveInfinity, false }; } } @@ -720,17 +898,17 @@ public static IEnumerable IsNegativeDouble { get { - yield return new object[] { double.NegativeInfinity, true }; - yield return new object[] { double.MinValue, true }; - yield return new object[] { -MinNormalDouble, true }; - yield return new object[] { -MaxSubnormalDouble, true }; - yield return new object[] { -0.0, true }; - yield return new object[] { double.NaN, true }; - yield return new object[] { 0.0, false }; - yield return new object[] { MaxSubnormalDouble, false }; - yield return new object[] { MinNormalDouble, false }; - yield return new object[] { double.MaxValue, false }; - yield return new object[] { double.PositiveInfinity, false }; + yield return new object[] { double.NegativeInfinity, true }; + yield return new object[] { double.MinValue, true }; + yield return new object[] { -MinNormalDouble, true }; + yield return new object[] { -MaxSubnormalDouble, true }; + yield return new object[] { -0.0, true }; + yield return new object[] { double.NaN, true }; + yield return new object[] { 0.0, false }; + yield return new object[] { MaxSubnormalDouble, false }; + yield return new object[] { MinNormalDouble, false }; + yield return new object[] { double.MaxValue, false }; + yield return new object[] { double.PositiveInfinity, false }; } } @@ -738,17 +916,17 @@ public static IEnumerable IsNegativeSingle { get { - yield return new object[] { float.NegativeInfinity, true }; - yield return new object[] { float.MinValue, true }; - yield return new object[] { -MinNormalSingle, true }; - yield return new object[] { -MaxSubnormalSingle, true }; - yield return new object[] { -0.0f, true }; - yield return new object[] { float.NaN, true }; - yield return new object[] { 0.0f, false }; - yield return new object[] { MaxSubnormalSingle, false }; - yield return new object[] { MinNormalSingle, false }; - yield return new object[] { float.MaxValue, false }; - yield return new object[] { float.PositiveInfinity, false }; + yield return new object[] { float.NegativeInfinity, true }; + yield return new object[] { float.MinValue, true }; + yield return new object[] { -MinNormalSingle, true }; + yield return new object[] { -MaxSubnormalSingle, true }; + yield return new object[] { -0.0f, true }; + yield return new object[] { float.NaN, true }; + yield return new object[] { 0.0f, false }; + yield return new object[] { MaxSubnormalSingle, false }; + yield return new object[] { MinNormalSingle, false }; + yield return new object[] { float.MaxValue, false }; + yield return new object[] { float.PositiveInfinity, false }; } } @@ -756,17 +934,17 @@ public static IEnumerable IsPositiveDouble { get { - yield return new object[] { double.NegativeInfinity, false }; - yield return new object[] { double.MinValue, false }; - yield return new object[] { -MinNormalDouble, false }; - yield return new object[] { -MaxSubnormalDouble, false }; - yield return new object[] { -0.0, false }; - yield return new object[] { double.NaN, false }; - yield return new object[] { 0.0, true }; - yield return new object[] { MaxSubnormalDouble, true }; - yield return new object[] { MinNormalDouble, true }; - yield return new object[] { double.MaxValue, true }; - yield return new object[] { double.PositiveInfinity, true }; + yield return new object[] { double.NegativeInfinity, false }; + yield return new object[] { double.MinValue, false }; + yield return new object[] { -MinNormalDouble, false }; + yield return new object[] { -MaxSubnormalDouble, false }; + yield return new object[] { -0.0, false }; + yield return new object[] { double.NaN, false }; + yield return new object[] { 0.0, true }; + yield return new object[] { MaxSubnormalDouble, true }; + yield return new object[] { MinNormalDouble, true }; + yield return new object[] { double.MaxValue, true }; + yield return new object[] { double.PositiveInfinity, true }; } } @@ -774,17 +952,17 @@ public static IEnumerable IsPositiveSingle { get { - yield return new object[] { float.NegativeInfinity, false }; - yield return new object[] { float.MinValue, false }; - yield return new object[] { -MinNormalSingle, false }; - yield return new object[] { -MaxSubnormalSingle, false }; - yield return new object[] { -0.0f, false }; - yield return new object[] { float.NaN, false }; - yield return new object[] { 0.0f, true }; - yield return new object[] { MaxSubnormalSingle, true }; - yield return new object[] { MinNormalSingle, true }; - yield return new object[] { float.MaxValue, true }; - yield return new object[] { float.PositiveInfinity, true }; + yield return new object[] { float.NegativeInfinity, false }; + yield return new object[] { float.MinValue, false }; + yield return new object[] { -MinNormalSingle, false }; + yield return new object[] { -MaxSubnormalSingle, false }; + yield return new object[] { -0.0f, false }; + yield return new object[] { float.NaN, false }; + yield return new object[] { 0.0f, true }; + yield return new object[] { MaxSubnormalSingle, true }; + yield return new object[] { MinNormalSingle, true }; + yield return new object[] { float.MaxValue, true }; + yield return new object[] { float.PositiveInfinity, true }; } } @@ -792,19 +970,19 @@ public static IEnumerable IsPositiveInfinityDouble { get { - yield return new object[] { double.NegativeInfinity, false }; - yield return new object[] { double.MinValue, false }; - yield return new object[] { -MinNormalDouble, false }; - yield return new object[] { -MaxSubnormalDouble, false }; - yield return new object[] { -double.Epsilon, false }; - yield return new object[] { -0.0, false }; - yield return new object[] { double.NaN, false }; - yield return new object[] { 0.0, false }; - yield return new object[] { double.Epsilon, false }; - yield return new object[] { MaxSubnormalDouble, false }; - yield return new object[] { MinNormalDouble, false }; - yield return new object[] { double.MaxValue, false }; - yield return new object[] { double.PositiveInfinity, true }; + yield return new object[] { double.NegativeInfinity, false }; + yield return new object[] { double.MinValue, false }; + yield return new object[] { -MinNormalDouble, false }; + yield return new object[] { -MaxSubnormalDouble, false }; + yield return new object[] { -double.Epsilon, false }; + yield return new object[] { -0.0, false }; + yield return new object[] { double.NaN, false }; + yield return new object[] { 0.0, false }; + yield return new object[] { double.Epsilon, false }; + yield return new object[] { MaxSubnormalDouble, false }; + yield return new object[] { MinNormalDouble, false }; + yield return new object[] { double.MaxValue, false }; + yield return new object[] { double.PositiveInfinity, true }; } } @@ -812,19 +990,19 @@ public static IEnumerable IsPositiveInfinitySingle { get { - yield return new object[] { float.NegativeInfinity, false }; - yield return new object[] { float.MinValue, false }; - yield return new object[] { -MinNormalSingle, false }; - yield return new object[] { -MaxSubnormalSingle, false }; - yield return new object[] { -float.Epsilon, false }; - yield return new object[] { -0.0f, false }; - yield return new object[] { float.NaN, false }; - yield return new object[] { 0.0f, false }; - yield return new object[] { float.Epsilon, false }; - yield return new object[] { MaxSubnormalSingle, false }; - yield return new object[] { MinNormalSingle, false }; - yield return new object[] { float.MaxValue, false }; - yield return new object[] { float.PositiveInfinity, true }; + yield return new object[] { float.NegativeInfinity, false }; + yield return new object[] { float.MinValue, false }; + yield return new object[] { -MinNormalSingle, false }; + yield return new object[] { -MaxSubnormalSingle, false }; + yield return new object[] { -float.Epsilon, false }; + yield return new object[] { -0.0f, false }; + yield return new object[] { float.NaN, false }; + yield return new object[] { 0.0f, false }; + yield return new object[] { float.Epsilon, false }; + yield return new object[] { MaxSubnormalSingle, false }; + yield return new object[] { MinNormalSingle, false }; + yield return new object[] { float.MaxValue, false }; + yield return new object[] { float.PositiveInfinity, true }; } } @@ -832,19 +1010,19 @@ public static IEnumerable IsZeroDouble { get { - yield return new object[] { double.NegativeInfinity, false }; - yield return new object[] { double.MinValue, false }; - yield return new object[] { -MinNormalDouble, false }; - yield return new object[] { -MaxSubnormalDouble, false }; - yield return new object[] { -double.Epsilon, false }; - yield return new object[] { -0.0, true }; - yield return new object[] { double.NaN, false }; - yield return new object[] { 0.0, true }; - yield return new object[] { double.Epsilon, false }; - yield return new object[] { MaxSubnormalDouble, false }; - yield return new object[] { MinNormalDouble, false }; - yield return new object[] { double.MaxValue, false }; - yield return new object[] { double.PositiveInfinity, false }; + yield return new object[] { double.NegativeInfinity, false }; + yield return new object[] { double.MinValue, false }; + yield return new object[] { -MinNormalDouble, false }; + yield return new object[] { -MaxSubnormalDouble, false }; + yield return new object[] { -double.Epsilon, false }; + yield return new object[] { -0.0, true }; + yield return new object[] { double.NaN, false }; + yield return new object[] { 0.0, true }; + yield return new object[] { double.Epsilon, false }; + yield return new object[] { MaxSubnormalDouble, false }; + yield return new object[] { MinNormalDouble, false }; + yield return new object[] { double.MaxValue, false }; + yield return new object[] { double.PositiveInfinity, false }; } } @@ -852,19 +1030,19 @@ public static IEnumerable IsZeroSingle { get { - yield return new object[] { float.NegativeInfinity, false }; - yield return new object[] { float.MinValue, false }; - yield return new object[] { -MinNormalSingle, false }; - yield return new object[] { -MaxSubnormalSingle, false }; - yield return new object[] { -float.Epsilon, false }; - yield return new object[] { -0.0f, true }; - yield return new object[] { float.NaN, false }; - yield return new object[] { 0.0f, true }; - yield return new object[] { float.Epsilon, false }; - yield return new object[] { MaxSubnormalSingle, false }; - yield return new object[] { MinNormalSingle, false }; - yield return new object[] { float.MaxValue, false }; - yield return new object[] { float.PositiveInfinity, false }; + yield return new object[] { float.NegativeInfinity, false }; + yield return new object[] { float.MinValue, false }; + yield return new object[] { -MinNormalSingle, false }; + yield return new object[] { -MaxSubnormalSingle, false }; + yield return new object[] { -float.Epsilon, false }; + yield return new object[] { -0.0f, true }; + yield return new object[] { float.NaN, false }; + yield return new object[] { 0.0f, true }; + yield return new object[] { float.Epsilon, false }; + yield return new object[] { MaxSubnormalSingle, false }; + yield return new object[] { MinNormalSingle, false }; + yield return new object[] { float.MaxValue, false }; + yield return new object[] { float.PositiveInfinity, false }; } } diff --git a/src/libraries/System.Numerics.Vectors/ref/System.Numerics.Vectors.cs b/src/libraries/System.Numerics.Vectors/ref/System.Numerics.Vectors.cs index fd00fe8c727068..e485b71f87639e 100644 --- a/src/libraries/System.Numerics.Vectors/ref/System.Numerics.Vectors.cs +++ b/src/libraries/System.Numerics.Vectors/ref/System.Numerics.Vectors.cs @@ -205,7 +205,11 @@ public static partial class Vector public static bool IsHardwareAccelerated { get { throw null; } } public static System.Numerics.Vector Abs(System.Numerics.Vector value) { throw null; } public static System.Numerics.Vector Add(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static bool All(System.Numerics.Vector vector, T value) { throw null; } + public static bool AllWhereAllBitsSet(System.Numerics.Vector vector) { throw null; } public static System.Numerics.Vector AndNot(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static bool Any(System.Numerics.Vector vector, T value) { throw null; } + public static bool AnyWhereAllBitsSet(System.Numerics.Vector vector) { throw null; } public static System.Numerics.Vector As(this System.Numerics.Vector vector) { throw null; } public static System.Numerics.Plane AsPlane(this System.Numerics.Vector4 value) { throw null; } public static System.Numerics.Quaternion AsQuaternion(this System.Numerics.Vector4 value) { throw null; } @@ -264,6 +268,8 @@ public static partial class Vector public static System.Numerics.Vector CopySign(System.Numerics.Vector value, System.Numerics.Vector sign) { throw null; } public static System.Numerics.Vector Cos(System.Numerics.Vector vector) { throw null; } public static System.Numerics.Vector Cos(System.Numerics.Vector vector) { throw null; } + public static int Count(System.Numerics.Vector vector, T value) { throw null; } + public static int CountWhereAllBitsSet(System.Numerics.Vector vector) { throw null; } public static System.Numerics.Vector Create(T value) { throw null; } public static System.Numerics.Vector Create(System.ReadOnlySpan values) { throw null; } public static System.Numerics.Vector CreateSequence(T start, T step) { throw null; } @@ -281,11 +287,20 @@ public static partial class Vector public static System.Numerics.Vector Equals(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector Exp(System.Numerics.Vector vector) { throw null; } public static System.Numerics.Vector Exp(System.Numerics.Vector vector) { throw null; } + [CLSCompliant(false)] + public static uint ExtractMostSignificantBits(this System.Numerics.Vector2 vector) { throw null; } + [CLSCompliant(false)] + public static uint ExtractMostSignificantBits(this System.Numerics.Vector3 vector) { throw null; } + [CLSCompliant(false)] + public static uint ExtractMostSignificantBits(this System.Numerics.Vector4 vector) { throw null; } public static System.Numerics.Vector Floor(System.Numerics.Vector value) { throw null; } public static System.Numerics.Vector Floor(System.Numerics.Vector value) { throw null; } public static System.Numerics.Vector FusedMultiplyAdd(System.Numerics.Vector left, System.Numerics.Vector right, System.Numerics.Vector addend) { throw null; } public static System.Numerics.Vector FusedMultiplyAdd(System.Numerics.Vector left, System.Numerics.Vector right, System.Numerics.Vector addend) { throw null; } public static T GetElement(this System.Numerics.Vector vector, int index) { throw null; } + public static float GetElement(this System.Numerics.Vector2 vector, int index) { throw null; } + public static float GetElement(this System.Numerics.Vector3 vector, int index) { throw null; } + public static float GetElement(this System.Numerics.Vector4 vector, int index) { throw null; } public static System.Numerics.Vector GreaterThan(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector GreaterThan(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector GreaterThan(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } @@ -302,11 +317,23 @@ public static partial class Vector public static System.Numerics.Vector GreaterThan(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector Hypot(System.Numerics.Vector x, System.Numerics.Vector y) { throw null; } public static System.Numerics.Vector Hypot(System.Numerics.Vector x, System.Numerics.Vector y) { throw null; } + public static int IndexOf(System.Numerics.Vector vector, T value) { throw null; } + public static int IndexOfWhereAllBitsSet(System.Numerics.Vector vector) { throw null; } + public static System.Numerics.Vector IsEvenInteger(System.Numerics.Vector vector) { throw null; } + public static System.Numerics.Vector IsFinite(System.Numerics.Vector vector) { throw null; } + public static System.Numerics.Vector IsInfinity(System.Numerics.Vector vector) { throw null; } + public static System.Numerics.Vector IsInteger(System.Numerics.Vector vector) { throw null; } public static System.Numerics.Vector IsNaN(System.Numerics.Vector vector) { throw null; } public static System.Numerics.Vector IsNegative(System.Numerics.Vector vector) { throw null; } + public static System.Numerics.Vector IsNegativeInfinity(System.Numerics.Vector vector) { throw null; } + public static System.Numerics.Vector IsNormal(System.Numerics.Vector vector) { throw null; } + public static System.Numerics.Vector IsOddInteger(System.Numerics.Vector vector) { throw null; } public static System.Numerics.Vector IsPositive(System.Numerics.Vector vector) { throw null; } public static System.Numerics.Vector IsPositiveInfinity(System.Numerics.Vector vector) { throw null; } + public static System.Numerics.Vector IsSubnormal(System.Numerics.Vector vector) { throw null; } public static System.Numerics.Vector IsZero(System.Numerics.Vector vector) { throw null; } + public static int LastIndexOf(System.Numerics.Vector vector, T value) { throw null; } + public static int LastIndexOfWhereAllBitsSet(System.Numerics.Vector vector) { throw null; } public static System.Numerics.Vector Lerp(System.Numerics.Vector x, System.Numerics.Vector y, System.Numerics.Vector amount) { throw null; } public static System.Numerics.Vector Lerp(System.Numerics.Vector x, System.Numerics.Vector y, System.Numerics.Vector amount) { throw null; } public static System.Numerics.Vector LessThan(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } @@ -363,6 +390,8 @@ public static partial class Vector [System.CLSCompliantAttribute(false)] public static System.Numerics.Vector Narrow(System.Numerics.Vector low, System.Numerics.Vector high) { throw null; } public static System.Numerics.Vector Negate(System.Numerics.Vector value) { throw null; } + public static bool None(System.Numerics.Vector vector, T value) { throw null; } + public static bool NoneWhereAllBitsSet(System.Numerics.Vector vector) { throw null; } public static System.Numerics.Vector OnesComplement(System.Numerics.Vector value) { throw null; } public static System.Numerics.Vector RadiansToDegrees(System.Numerics.Vector radians) { throw null; } public static System.Numerics.Vector RadiansToDegrees(System.Numerics.Vector radians) { throw null; } @@ -414,15 +443,45 @@ public static partial class Vector [System.CLSCompliantAttribute(false)] public static unsafe void Store(this System.Numerics.Vector source, T* destination) { throw null; } [System.CLSCompliantAttribute(false)] + public static unsafe void Store(this System.Numerics.Vector2 source, float* destination) { throw null; } + [System.CLSCompliantAttribute(false)] + public static unsafe void Store(this System.Numerics.Vector3 source, float* destination) { throw null; } + [System.CLSCompliantAttribute(false)] + public static unsafe void Store(this System.Numerics.Vector4 source, float* destination) { throw null; } + [System.CLSCompliantAttribute(false)] public static unsafe void StoreAligned(this System.Numerics.Vector source, T* destination) { throw null; } [System.CLSCompliantAttribute(false)] + public static unsafe void StoreAligned(this System.Numerics.Vector2 source, float* destination) { throw null; } + [System.CLSCompliantAttribute(false)] + public static unsafe void StoreAligned(this System.Numerics.Vector3 source, float* destination) { throw null; } + [System.CLSCompliantAttribute(false)] + public static unsafe void StoreAligned(this System.Numerics.Vector4 source, float* destination) { throw null; } + [System.CLSCompliantAttribute(false)] public static unsafe void StoreAlignedNonTemporal(this System.Numerics.Vector source, T* destination) { throw null; } + [System.CLSCompliantAttribute(false)] + public static unsafe void StoreAlignedNonTemporal(this System.Numerics.Vector2 source, float* destination) { throw null; } + [System.CLSCompliantAttribute(false)] + public static unsafe void StoreAlignedNonTemporal(this System.Numerics.Vector3 source, float* destination) { throw null; } + [System.CLSCompliantAttribute(false)] + public static unsafe void StoreAlignedNonTemporal(this System.Numerics.Vector4 source, float* destination) { throw null; } public static void StoreUnsafe(this System.Numerics.Vector source, ref T destination) { throw null; } + public static void StoreUnsafe(this System.Numerics.Vector2 source, ref float destination) { throw null; } + public static void StoreUnsafe(this System.Numerics.Vector3 source, ref float destination) { throw null; } + public static void StoreUnsafe(this System.Numerics.Vector4 source, ref float destination) { throw null; } [System.CLSCompliantAttribute(false)] public static void StoreUnsafe(this System.Numerics.Vector source, ref T destination, nuint elementOffset) { throw null; } + [System.CLSCompliantAttribute(false)] + public static void StoreUnsafe(this System.Numerics.Vector2 source, ref float destination, nuint elementOffset) { throw null; } + [System.CLSCompliantAttribute(false)] + public static void StoreUnsafe(this System.Numerics.Vector3 source, ref float destination, nuint elementOffset) { throw null; } + [System.CLSCompliantAttribute(false)] + public static void StoreUnsafe(this System.Numerics.Vector4 source, ref float destination, nuint elementOffset) { throw null; } public static System.Numerics.Vector Subtract(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static T Sum(System.Numerics.Vector value) { throw null; } public static T ToScalar(this System.Numerics.Vector vector) { throw null; } + public static float ToScalar(this System.Numerics.Vector2 vector) { throw null; } + public static float ToScalar(this System.Numerics.Vector3 vector) { throw null; } + public static float ToScalar(this System.Numerics.Vector4 vector) { throw null; } public static System.Numerics.Vector Truncate(System.Numerics.Vector vector) { throw null; } public static System.Numerics.Vector Truncate(System.Numerics.Vector vector) { throw null; } [System.CLSCompliantAttribute(false)] @@ -459,6 +518,9 @@ public static partial class Vector [System.CLSCompliantAttribute(false)] public static System.Numerics.Vector WidenUpper(System.Numerics.Vector source) { throw null; } public static System.Numerics.Vector WithElement(this System.Numerics.Vector vector, int index, T value) { throw null; } + public static System.Numerics.Vector2 WithElement(this System.Numerics.Vector2 vector, int index, float value) { throw null; } + public static System.Numerics.Vector3 WithElement(this System.Numerics.Vector3 vector, int index, float value) { throw null; } + public static System.Numerics.Vector4 WithElement(this System.Numerics.Vector4 vector, int index, float value) { throw null; } public static System.Numerics.Vector Xor(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } } public partial struct Vector2 : System.IEquatable, System.IFormattable @@ -468,6 +530,7 @@ public partial struct Vector2 : System.IEquatable, Syst public Vector2(float value) { throw null; } public Vector2(float x, float y) { throw null; } public Vector2(System.ReadOnlySpan values) { throw null; } + public static System.Numerics.Vector2 AllBitsSet { get { throw null; } } public static System.Numerics.Vector2 E { get { throw null; } } public static System.Numerics.Vector2 Epsilon { get { throw null; } } public static System.Numerics.Vector2 NaN { get { throw null; } } @@ -483,9 +546,19 @@ public partial struct Vector2 : System.IEquatable, Syst public static System.Numerics.Vector2 Zero { get { throw null; } } public static System.Numerics.Vector2 Abs(System.Numerics.Vector2 value) { throw null; } public static System.Numerics.Vector2 Add(System.Numerics.Vector2 left, System.Numerics.Vector2 right) { throw null; } + public static bool All(System.Numerics.Vector2 vector, float value) { throw null; } + public static bool AllWhereAllBitsSet(System.Numerics.Vector2 vector) { throw null; } + public static System.Numerics.Vector2 AndNot(System.Numerics.Vector2 left, System.Numerics.Vector2 right) { throw null; } + public static bool Any(System.Numerics.Vector2 vector, float value) { throw null; } + public static bool AnyWhereAllBitsSet(System.Numerics.Vector2 vector) { throw null; } + public static System.Numerics.Vector2 BitwiseAnd(System.Numerics.Vector2 left, System.Numerics.Vector2 right) { throw null; } + public static System.Numerics.Vector2 BitwiseOr(System.Numerics.Vector2 left, System.Numerics.Vector2 right) { throw null; } public static System.Numerics.Vector2 Clamp(System.Numerics.Vector2 value1, System.Numerics.Vector2 min, System.Numerics.Vector2 max) { throw null; } public static System.Numerics.Vector2 ClampNative(System.Numerics.Vector2 value1, System.Numerics.Vector2 min, System.Numerics.Vector2 max) { throw null; } + public static System.Numerics.Vector2 ConditionalSelect(System.Numerics.Vector2 condition, System.Numerics.Vector2 left, System.Numerics.Vector2 right) { throw null; } public static System.Numerics.Vector2 CopySign(System.Numerics.Vector2 value, System.Numerics.Vector2 sign) { throw null; } + public static int Count(System.Numerics.Vector2 vector, float value) { throw null; } + public static int CountWhereAllBitsSet(System.Numerics.Vector2 vector) { throw null; } public static System.Numerics.Vector2 Create(float value) { throw null; } public static System.Numerics.Vector2 Create(float x, float y) { throw null; } public static System.Numerics.Vector2 Create(System.ReadOnlySpan values) { throw null; } @@ -502,14 +575,55 @@ public readonly void CopyTo(System.Span destination) { } public static float Dot(System.Numerics.Vector2 value1, System.Numerics.Vector2 value2) { throw null; } public readonly bool Equals(System.Numerics.Vector2 other) { throw null; } public override readonly bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } + public static Vector2 Equals(System.Numerics.Vector2 left, System.Numerics.Vector2 right) { throw null; } + public static bool EqualsAll(System.Numerics.Vector2 left, System.Numerics.Vector2 right) { throw null; } + public static bool EqualsAny(System.Numerics.Vector2 left, System.Numerics.Vector2 right) { throw null; } public static System.Numerics.Vector2 Exp(System.Numerics.Vector2 vector) { throw null; } public static System.Numerics.Vector2 FusedMultiplyAdd(System.Numerics.Vector2 left, System.Numerics.Vector2 right, System.Numerics.Vector2 addend) { throw null; } public override readonly int GetHashCode() { throw null; } + public static Vector2 GreaterThan(System.Numerics.Vector2 left, System.Numerics.Vector2 right) { throw null; } + public static bool GreaterThanAll(System.Numerics.Vector2 left, System.Numerics.Vector2 right) { throw null; } + public static bool GreaterThanAny(System.Numerics.Vector2 left, System.Numerics.Vector2 right) { throw null; } + public static Vector2 GreaterThanOrEqual(System.Numerics.Vector2 left, System.Numerics.Vector2 right) { throw null; } + public static bool GreaterThanOrEqualAll(System.Numerics.Vector2 left, System.Numerics.Vector2 right) { throw null; } + public static bool GreaterThanOrEqualAny(System.Numerics.Vector2 left, System.Numerics.Vector2 right) { throw null; } public static System.Numerics.Vector2 Hypot(System.Numerics.Vector2 x, System.Numerics.Vector2 y) { throw null; } + public static int IndexOf(System.Numerics.Vector2 vector, float value) { throw null; } + public static int IndexOfWhereAllBitsSet(System.Numerics.Vector2 vector) { throw null; } + public static System.Numerics.Vector2 IsEvenInteger(System.Numerics.Vector2 vector) { throw null; } + public static System.Numerics.Vector2 IsFinite(System.Numerics.Vector2 vector) { throw null; } + public static System.Numerics.Vector2 IsInfinity(System.Numerics.Vector2 vector) { throw null; } + public static System.Numerics.Vector2 IsInteger(System.Numerics.Vector2 vector) { throw null; } + public static System.Numerics.Vector2 IsNaN(System.Numerics.Vector2 vector) { throw null; } + public static System.Numerics.Vector2 IsNegative(System.Numerics.Vector2 vector) { throw null; } + public static System.Numerics.Vector2 IsNegativeInfinity(System.Numerics.Vector2 vector) { throw null; } + public static System.Numerics.Vector2 IsNormal(System.Numerics.Vector2 vector) { throw null; } + public static System.Numerics.Vector2 IsOddInteger(System.Numerics.Vector2 vector) { throw null; } + public static System.Numerics.Vector2 IsPositive(System.Numerics.Vector2 vector) { throw null; } + public static System.Numerics.Vector2 IsPositiveInfinity(System.Numerics.Vector2 vector) { throw null; } + public static System.Numerics.Vector2 IsSubnormal(System.Numerics.Vector2 vector) { throw null; } + public static System.Numerics.Vector2 IsZero(System.Numerics.Vector2 vector) { throw null; } + public static int LastIndexOf(System.Numerics.Vector2 vector, float value) { throw null; } + public static int LastIndexOfWhereAllBitsSet(System.Numerics.Vector2 vector) { throw null; } public readonly float Length() { throw null; } public readonly float LengthSquared() { throw null; } public static System.Numerics.Vector2 Lerp(System.Numerics.Vector2 value1, System.Numerics.Vector2 value2, float amount) { throw null; } public static System.Numerics.Vector2 Lerp(System.Numerics.Vector2 value1, System.Numerics.Vector2 value2, System.Numerics.Vector2 amount) { throw null; } + public static Vector2 LessThan(System.Numerics.Vector2 left, System.Numerics.Vector2 right) { throw null; } + public static bool LessThanAll(System.Numerics.Vector2 left, System.Numerics.Vector2 right) { throw null; } + public static bool LessThanAny(System.Numerics.Vector2 left, System.Numerics.Vector2 right) { throw null; } + public static Vector2 LessThanOrEqual(System.Numerics.Vector2 left, System.Numerics.Vector2 right) { throw null; } + public static bool LessThanOrEqualAll(System.Numerics.Vector2 left, System.Numerics.Vector2 right) { throw null; } + public static bool LessThanOrEqualAny(System.Numerics.Vector2 left, System.Numerics.Vector2 right) { throw null; } + [CLSCompliant(false)] + public static unsafe System.Numerics.Vector2 Load(float* source) { throw null; } + [CLSCompliant(false)] + public static unsafe System.Numerics.Vector2 LoadAligned(float* source) { throw null; } + [CLSCompliant(false)] + public static unsafe System.Numerics.Vector2 LoadAlignedNonTemporal(float* source) { throw null; } + public static System.Numerics.Vector2 LoadUnsafe(ref readonly float source) { throw null; } + [CLSCompliant(false)] + public static System.Numerics.Vector2 LoadUnsafe(ref readonly float source, nuint elementOffset) { throw null; } public static System.Numerics.Vector2 Log(System.Numerics.Vector2 vector) { throw null; } public static System.Numerics.Vector2 Log2(System.Numerics.Vector2 vector) { throw null; } public static System.Numerics.Vector2 Max(System.Numerics.Vector2 value1, System.Numerics.Vector2 value2) { throw null; } @@ -527,24 +641,37 @@ public readonly void CopyTo(System.Span destination) { } public static System.Numerics.Vector2 Multiply(float left, System.Numerics.Vector2 right) { throw null; } public static System.Numerics.Vector2 MultiplyAddEstimate(System.Numerics.Vector2 left, System.Numerics.Vector2 right, System.Numerics.Vector2 addend) { throw null; } public static System.Numerics.Vector2 Negate(System.Numerics.Vector2 value) { throw null; } + public static bool None(System.Numerics.Vector2 vector, float value) { throw null; } + public static bool NoneWhereAllBitsSet(System.Numerics.Vector2 vector) { throw null; } public static System.Numerics.Vector2 Normalize(System.Numerics.Vector2 value) { throw null; } + public static System.Numerics.Vector2 OnesComplement(System.Numerics.Vector2 value) { throw null; } public static System.Numerics.Vector2 operator +(System.Numerics.Vector2 left, System.Numerics.Vector2 right) { throw null; } + public static System.Numerics.Vector2 operator &(System.Numerics.Vector2 left, System.Numerics.Vector2 right) { throw null; } + public static System.Numerics.Vector2 operator |(System.Numerics.Vector2 left, System.Numerics.Vector2 right) { throw null; } public static System.Numerics.Vector2 operator /(System.Numerics.Vector2 left, System.Numerics.Vector2 right) { throw null; } public static System.Numerics.Vector2 operator /(System.Numerics.Vector2 value1, float value2) { throw null; } + public static System.Numerics.Vector2 operator ^(System.Numerics.Vector2 left, System.Numerics.Vector2 right) { throw null; } public static bool operator ==(System.Numerics.Vector2 left, System.Numerics.Vector2 right) { throw null; } + public static System.Numerics.Vector2 operator <<(System.Numerics.Vector2 value, int shiftAmount) { throw null; } public static bool operator !=(System.Numerics.Vector2 left, System.Numerics.Vector2 right) { throw null; } public static System.Numerics.Vector2 operator *(System.Numerics.Vector2 left, System.Numerics.Vector2 right) { throw null; } public static System.Numerics.Vector2 operator *(System.Numerics.Vector2 left, float right) { throw null; } public static System.Numerics.Vector2 operator *(float left, System.Numerics.Vector2 right) { throw null; } + public static System.Numerics.Vector2 operator ~(System.Numerics.Vector2 value) { throw null; } + public static System.Numerics.Vector2 operator >>(System.Numerics.Vector2 value, int shiftAmount) { throw null; } public static System.Numerics.Vector2 operator -(System.Numerics.Vector2 left, System.Numerics.Vector2 right) { throw null; } public static System.Numerics.Vector2 operator -(System.Numerics.Vector2 value) { throw null; } + public static System.Numerics.Vector2 operator +(System.Numerics.Vector2 value) { throw null; } + public static System.Numerics.Vector2 operator >>>(System.Numerics.Vector2 value, int shiftAmount) { throw null; } public static System.Numerics.Vector2 RadiansToDegrees(System.Numerics.Vector2 radians) { throw null; } public static System.Numerics.Vector2 Round(System.Numerics.Vector2 vector) { throw null; } public static System.Numerics.Vector2 Round(System.Numerics.Vector2 vector, System.MidpointRounding mode) { throw null; } public static System.Numerics.Vector2 Reflect(System.Numerics.Vector2 vector, System.Numerics.Vector2 normal) { throw null; } + public static System.Numerics.Vector2 Shuffle(System.Numerics.Vector2 vector, byte xIndex, byte yIndex) { throw null; } public static System.Numerics.Vector2 Sin(System.Numerics.Vector2 vector) { throw null; } public static (System.Numerics.Vector2 Sin, System.Numerics.Vector2 Cos) SinCos(System.Numerics.Vector2 vector) { throw null; } public static System.Numerics.Vector2 SquareRoot(System.Numerics.Vector2 value) { throw null; } + public static float Sum(System.Numerics.Vector2 value) { throw null; } public static System.Numerics.Vector2 Subtract(System.Numerics.Vector2 left, System.Numerics.Vector2 right) { throw null; } public override readonly string ToString() { throw null; } public readonly string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format) { throw null; } @@ -555,6 +682,7 @@ public readonly void CopyTo(System.Span destination) { } public static System.Numerics.Vector2 TransformNormal(System.Numerics.Vector2 normal, System.Numerics.Matrix3x2 matrix) { throw null; } public static System.Numerics.Vector2 TransformNormal(System.Numerics.Vector2 normal, System.Numerics.Matrix4x4 matrix) { throw null; } public static System.Numerics.Vector2 Truncate(System.Numerics.Vector2 vector) { throw null; } + public static System.Numerics.Vector2 Xor(System.Numerics.Vector2 left, System.Numerics.Vector2 right) { throw null; } } public partial struct Vector3 : System.IEquatable, System.IFormattable { @@ -565,6 +693,7 @@ public partial struct Vector3 : System.IEquatable, Syst public Vector3(float value) { throw null; } public Vector3(float x, float y, float z) { throw null; } public Vector3(System.ReadOnlySpan values) { throw null; } + public static System.Numerics.Vector3 AllBitsSet { get { throw null; } } public static System.Numerics.Vector3 E { get { throw null; } } public static System.Numerics.Vector3 Epsilon { get { throw null; } } public static System.Numerics.Vector3 NaN { get { throw null; } } @@ -581,9 +710,19 @@ public partial struct Vector3 : System.IEquatable, Syst public static System.Numerics.Vector3 Zero { get { throw null; } } public static System.Numerics.Vector3 Abs(System.Numerics.Vector3 value) { throw null; } public static System.Numerics.Vector3 Add(System.Numerics.Vector3 left, System.Numerics.Vector3 right) { throw null; } + public static bool All(System.Numerics.Vector3 vector, float value) { throw null; } + public static bool AllWhereAllBitsSet(System.Numerics.Vector3 vector) { throw null; } + public static System.Numerics.Vector3 AndNot(System.Numerics.Vector3 left, System.Numerics.Vector3 right) { throw null; } + public static bool Any(System.Numerics.Vector3 vector, float value) { throw null; } + public static bool AnyWhereAllBitsSet(System.Numerics.Vector3 vector) { throw null; } + public static System.Numerics.Vector3 BitwiseAnd(System.Numerics.Vector3 left, System.Numerics.Vector3 right) { throw null; } + public static System.Numerics.Vector3 BitwiseOr(System.Numerics.Vector3 left, System.Numerics.Vector3 right) { throw null; } public static System.Numerics.Vector3 Clamp(System.Numerics.Vector3 value1, System.Numerics.Vector3 min, System.Numerics.Vector3 max) { throw null; } public static System.Numerics.Vector3 ClampNative(System.Numerics.Vector3 value1, System.Numerics.Vector3 min, System.Numerics.Vector3 max) { throw null; } + public static System.Numerics.Vector3 ConditionalSelect(System.Numerics.Vector3 condition, System.Numerics.Vector3 left, System.Numerics.Vector3 right) { throw null; } public static System.Numerics.Vector3 CopySign(System.Numerics.Vector3 value, System.Numerics.Vector3 sign) { throw null; } + public static int Count(System.Numerics.Vector3 vector, float value) { throw null; } + public static int CountWhereAllBitsSet(System.Numerics.Vector3 vector) { throw null; } public static System.Numerics.Vector3 Create(float value) { throw null; } public static System.Numerics.Vector3 Create(System.Numerics.Vector2 vector, float z) { throw null; } public static System.Numerics.Vector3 Create(float x, float y, float z) { throw null; } @@ -602,14 +741,55 @@ public readonly void CopyTo(System.Span destination) { } public static float Dot(System.Numerics.Vector3 vector1, System.Numerics.Vector3 vector2) { throw null; } public readonly bool Equals(System.Numerics.Vector3 other) { throw null; } public override readonly bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } + public static Vector3 Equals(System.Numerics.Vector3 left, System.Numerics.Vector3 right) { throw null; } + public static bool EqualsAll(System.Numerics.Vector3 left, System.Numerics.Vector3 right) { throw null; } + public static bool EqualsAny(System.Numerics.Vector3 left, System.Numerics.Vector3 right) { throw null; } public static System.Numerics.Vector3 Exp(System.Numerics.Vector3 vector) { throw null; } public static System.Numerics.Vector3 FusedMultiplyAdd(System.Numerics.Vector3 left, System.Numerics.Vector3 right, System.Numerics.Vector3 addend) { throw null; } public override readonly int GetHashCode() { throw null; } + public static Vector3 GreaterThan(System.Numerics.Vector3 left, System.Numerics.Vector3 right) { throw null; } + public static bool GreaterThanAll(System.Numerics.Vector3 left, System.Numerics.Vector3 right) { throw null; } + public static bool GreaterThanAny(System.Numerics.Vector3 left, System.Numerics.Vector3 right) { throw null; } + public static Vector3 GreaterThanOrEqual(System.Numerics.Vector3 left, System.Numerics.Vector3 right) { throw null; } + public static bool GreaterThanOrEqualAll(System.Numerics.Vector3 left, System.Numerics.Vector3 right) { throw null; } + public static bool GreaterThanOrEqualAny(System.Numerics.Vector3 left, System.Numerics.Vector3 right) { throw null; } + public static System.Numerics.Vector3 Hypot(System.Numerics.Vector3 x, System.Numerics.Vector3 y) { throw null; } + public static int IndexOf(System.Numerics.Vector3 vector, float value) { throw null; } + public static int IndexOfWhereAllBitsSet(System.Numerics.Vector3 vector) { throw null; } + public static System.Numerics.Vector3 IsEvenInteger(System.Numerics.Vector3 vector) { throw null; } + public static System.Numerics.Vector3 IsFinite(System.Numerics.Vector3 vector) { throw null; } + public static System.Numerics.Vector3 IsInfinity(System.Numerics.Vector3 vector) { throw null; } + public static System.Numerics.Vector3 IsInteger(System.Numerics.Vector3 vector) { throw null; } + public static System.Numerics.Vector3 IsNaN(System.Numerics.Vector3 vector) { throw null; } + public static System.Numerics.Vector3 IsNegative(System.Numerics.Vector3 vector) { throw null; } + public static System.Numerics.Vector3 IsNegativeInfinity(System.Numerics.Vector3 vector) { throw null; } + public static System.Numerics.Vector3 IsNormal(System.Numerics.Vector3 vector) { throw null; } + public static System.Numerics.Vector3 IsOddInteger(System.Numerics.Vector3 vector) { throw null; } + public static System.Numerics.Vector3 IsPositive(System.Numerics.Vector3 vector) { throw null; } + public static System.Numerics.Vector3 IsPositiveInfinity(System.Numerics.Vector3 vector) { throw null; } + public static System.Numerics.Vector3 IsSubnormal(System.Numerics.Vector3 vector) { throw null; } + public static System.Numerics.Vector3 IsZero(System.Numerics.Vector3 vector) { throw null; } + public static int LastIndexOf(System.Numerics.Vector3 vector, float value) { throw null; } + public static int LastIndexOfWhereAllBitsSet(System.Numerics.Vector3 vector) { throw null; } public readonly float Length() { throw null; } public readonly float LengthSquared() { throw null; } - public static System.Numerics.Vector3 Hypot(System.Numerics.Vector3 x, System.Numerics.Vector3 y) { throw null; } public static System.Numerics.Vector3 Lerp(System.Numerics.Vector3 value1, System.Numerics.Vector3 value2, float amount) { throw null; } public static System.Numerics.Vector3 Lerp(System.Numerics.Vector3 value1, System.Numerics.Vector3 value2, System.Numerics.Vector3 amount) { throw null; } + public static Vector3 LessThan(System.Numerics.Vector3 left, System.Numerics.Vector3 right) { throw null; } + public static bool LessThanAll(System.Numerics.Vector3 left, System.Numerics.Vector3 right) { throw null; } + public static bool LessThanAny(System.Numerics.Vector3 left, System.Numerics.Vector3 right) { throw null; } + public static Vector3 LessThanOrEqual(System.Numerics.Vector3 left, System.Numerics.Vector3 right) { throw null; } + public static bool LessThanOrEqualAll(System.Numerics.Vector3 left, System.Numerics.Vector3 right) { throw null; } + public static bool LessThanOrEqualAny(System.Numerics.Vector3 left, System.Numerics.Vector3 right) { throw null; } + [CLSCompliant(false)] + public static unsafe System.Numerics.Vector3 Load(float* source) { throw null; } + [CLSCompliant(false)] + public static unsafe System.Numerics.Vector3 LoadAligned(float* source) { throw null; } + [CLSCompliant(false)] + public static unsafe System.Numerics.Vector3 LoadAlignedNonTemporal(float* source) { throw null; } + public static System.Numerics.Vector3 LoadUnsafe(ref readonly float source) { throw null; } + [CLSCompliant(false)] + public static System.Numerics.Vector3 LoadUnsafe(ref readonly float source, nuint elementOffset) { throw null; } public static System.Numerics.Vector3 Log(System.Numerics.Vector3 vector) { throw null; } public static System.Numerics.Vector3 Log2(System.Numerics.Vector3 vector) { throw null; } public static System.Numerics.Vector3 Max(System.Numerics.Vector3 value1, System.Numerics.Vector3 value2) { throw null; } @@ -627,25 +807,38 @@ public readonly void CopyTo(System.Span destination) { } public static System.Numerics.Vector3 Multiply(float left, System.Numerics.Vector3 right) { throw null; } public static System.Numerics.Vector3 MultiplyAddEstimate(System.Numerics.Vector3 left, System.Numerics.Vector3 right, System.Numerics.Vector3 addend) { throw null; } public static System.Numerics.Vector3 Negate(System.Numerics.Vector3 value) { throw null; } + public static bool None(System.Numerics.Vector3 vector, float value) { throw null; } + public static bool NoneWhereAllBitsSet(System.Numerics.Vector3 vector) { throw null; } public static System.Numerics.Vector3 Normalize(System.Numerics.Vector3 value) { throw null; } + public static System.Numerics.Vector3 OnesComplement(System.Numerics.Vector3 value) { throw null; } public static System.Numerics.Vector3 operator +(System.Numerics.Vector3 left, System.Numerics.Vector3 right) { throw null; } + public static System.Numerics.Vector3 operator &(System.Numerics.Vector3 left, System.Numerics.Vector3 right) { throw null; } + public static System.Numerics.Vector3 operator |(System.Numerics.Vector3 left, System.Numerics.Vector3 right) { throw null; } public static System.Numerics.Vector3 operator /(System.Numerics.Vector3 left, System.Numerics.Vector3 right) { throw null; } public static System.Numerics.Vector3 operator /(System.Numerics.Vector3 value1, float value2) { throw null; } + public static System.Numerics.Vector3 operator ^(System.Numerics.Vector3 left, System.Numerics.Vector3 right) { throw null; } public static bool operator ==(System.Numerics.Vector3 left, System.Numerics.Vector3 right) { throw null; } + public static System.Numerics.Vector3 operator <<(System.Numerics.Vector3 value, int shiftAmount) { throw null; } public static bool operator !=(System.Numerics.Vector3 left, System.Numerics.Vector3 right) { throw null; } public static System.Numerics.Vector3 operator *(System.Numerics.Vector3 left, System.Numerics.Vector3 right) { throw null; } public static System.Numerics.Vector3 operator *(System.Numerics.Vector3 left, float right) { throw null; } public static System.Numerics.Vector3 operator *(float left, System.Numerics.Vector3 right) { throw null; } + public static System.Numerics.Vector3 operator ~(System.Numerics.Vector3 value) { throw null; } + public static System.Numerics.Vector3 operator >>(System.Numerics.Vector3 value, int shiftAmount) { throw null; } public static System.Numerics.Vector3 operator -(System.Numerics.Vector3 left, System.Numerics.Vector3 right) { throw null; } public static System.Numerics.Vector3 operator -(System.Numerics.Vector3 value) { throw null; } + public static System.Numerics.Vector3 operator +(System.Numerics.Vector3 value) { throw null; } + public static System.Numerics.Vector3 operator >>>(System.Numerics.Vector3 value, int shiftAmount) { throw null; } public static System.Numerics.Vector3 RadiansToDegrees(System.Numerics.Vector3 radians) { throw null; } public static System.Numerics.Vector3 Reflect(System.Numerics.Vector3 vector, System.Numerics.Vector3 normal) { throw null; } public static System.Numerics.Vector3 Round(System.Numerics.Vector3 vector) { throw null; } public static System.Numerics.Vector3 Round(System.Numerics.Vector3 vector, System.MidpointRounding mode) { throw null; } + public static System.Numerics.Vector3 Shuffle(System.Numerics.Vector3 vector, byte xIndex, byte yIndex, byte zIndex) { throw null; } public static System.Numerics.Vector3 Sin(System.Numerics.Vector3 vector) { throw null; } public static (System.Numerics.Vector3 Sin, System.Numerics.Vector3 Cos) SinCos(System.Numerics.Vector3 vector) { throw null; } public static System.Numerics.Vector3 SquareRoot(System.Numerics.Vector3 value) { throw null; } public static System.Numerics.Vector3 Subtract(System.Numerics.Vector3 left, System.Numerics.Vector3 right) { throw null; } + public static float Sum(System.Numerics.Vector3 value) { throw null; } public override readonly string ToString() { throw null; } public readonly string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format) { throw null; } public readonly string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format, System.IFormatProvider? formatProvider) { throw null; } @@ -653,6 +846,7 @@ public readonly void CopyTo(System.Span destination) { } public static System.Numerics.Vector3 Transform(System.Numerics.Vector3 value, System.Numerics.Quaternion rotation) { throw null; } public static System.Numerics.Vector3 TransformNormal(System.Numerics.Vector3 normal, System.Numerics.Matrix4x4 matrix) { throw null; } public static System.Numerics.Vector3 Truncate(System.Numerics.Vector3 vector) { throw null; } + public static System.Numerics.Vector3 Xor(System.Numerics.Vector3 left, System.Numerics.Vector3 right) { throw null; } } public partial struct Vector4 : System.IEquatable, System.IFormattable { @@ -665,6 +859,7 @@ public partial struct Vector4 : System.IEquatable, Syst public Vector4(float value) { throw null; } public Vector4(float x, float y, float z, float w) { throw null; } public Vector4(System.ReadOnlySpan values) { throw null; } + public static System.Numerics.Vector4 AllBitsSet { get { throw null; } } public static System.Numerics.Vector4 E { get { throw null; } } public static System.Numerics.Vector4 Epsilon { get { throw null; } } public static System.Numerics.Vector4 NaN { get { throw null; } } @@ -682,9 +877,19 @@ public partial struct Vector4 : System.IEquatable, Syst public static System.Numerics.Vector4 Zero { get { throw null; } } public static System.Numerics.Vector4 Abs(System.Numerics.Vector4 value) { throw null; } public static System.Numerics.Vector4 Add(System.Numerics.Vector4 left, System.Numerics.Vector4 right) { throw null; } + public static bool All(System.Numerics.Vector4 vector, float value) { throw null; } + public static bool AllWhereAllBitsSet(System.Numerics.Vector4 vector) { throw null; } + public static System.Numerics.Vector4 AndNot(System.Numerics.Vector4 left, System.Numerics.Vector4 right) { throw null; } + public static bool Any(System.Numerics.Vector4 vector, float value) { throw null; } + public static bool AnyWhereAllBitsSet(System.Numerics.Vector4 vector) { throw null; } + public static System.Numerics.Vector4 BitwiseAnd(System.Numerics.Vector4 left, System.Numerics.Vector4 right) { throw null; } + public static System.Numerics.Vector4 BitwiseOr(System.Numerics.Vector4 left, System.Numerics.Vector4 right) { throw null; } public static System.Numerics.Vector4 Clamp(System.Numerics.Vector4 value1, System.Numerics.Vector4 min, System.Numerics.Vector4 max) { throw null; } public static System.Numerics.Vector4 ClampNative(System.Numerics.Vector4 value1, System.Numerics.Vector4 min, System.Numerics.Vector4 max) { throw null; } + public static System.Numerics.Vector4 ConditionalSelect(System.Numerics.Vector4 condition, System.Numerics.Vector4 left, System.Numerics.Vector4 right) { throw null; } public static System.Numerics.Vector4 CopySign(System.Numerics.Vector4 value, System.Numerics.Vector4 sign) { throw null; } + public static int Count(System.Numerics.Vector4 vector, float value) { throw null; } + public static int CountWhereAllBitsSet(System.Numerics.Vector4 vector) { throw null; } public static System.Numerics.Vector4 Create(float value) { throw null; } public static System.Numerics.Vector4 Create(System.Numerics.Vector2 vector, float z, float w) { throw null; } public static System.Numerics.Vector4 Create(System.Numerics.Vector3 vector, float w) { throw null; } @@ -703,16 +908,57 @@ public readonly void CopyTo(System.Span destination) { } public static float Dot(System.Numerics.Vector4 vector1, System.Numerics.Vector4 vector2) { throw null; } public readonly bool Equals(System.Numerics.Vector4 other) { throw null; } public override readonly bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } + public static Vector4 Equals(System.Numerics.Vector4 left, System.Numerics.Vector4 right) { throw null; } + public static bool EqualsAll(System.Numerics.Vector4 left, System.Numerics.Vector4 right) { throw null; } + public static bool EqualsAny(System.Numerics.Vector4 left, System.Numerics.Vector4 right) { throw null; } public static System.Numerics.Vector4 Exp(System.Numerics.Vector4 vector) { throw null; } public static System.Numerics.Vector4 FusedMultiplyAdd(System.Numerics.Vector4 left, System.Numerics.Vector4 right, System.Numerics.Vector4 addend) { throw null; } public override readonly int GetHashCode() { throw null; } + public static Vector4 GreaterThan(System.Numerics.Vector4 left, System.Numerics.Vector4 right) { throw null; } + public static bool GreaterThanAll(System.Numerics.Vector4 left, System.Numerics.Vector4 right) { throw null; } + public static bool GreaterThanAny(System.Numerics.Vector4 left, System.Numerics.Vector4 right) { throw null; } + public static Vector4 GreaterThanOrEqual(System.Numerics.Vector4 left, System.Numerics.Vector4 right) { throw null; } + public static bool GreaterThanOrEqualAll(System.Numerics.Vector4 left, System.Numerics.Vector4 right) { throw null; } + public static bool GreaterThanOrEqualAny(System.Numerics.Vector4 left, System.Numerics.Vector4 right) { throw null; } + public static System.Numerics.Vector4 Hypot(System.Numerics.Vector4 x, System.Numerics.Vector4 y) { throw null; } + public static int IndexOf(System.Numerics.Vector4 vector, float value) { throw null; } + public static int IndexOfWhereAllBitsSet(System.Numerics.Vector4 vector) { throw null; } + public static System.Numerics.Vector4 IsEvenInteger(System.Numerics.Vector4 vector) { throw null; } + public static System.Numerics.Vector4 IsFinite(System.Numerics.Vector4 vector) { throw null; } + public static System.Numerics.Vector4 IsInfinity(System.Numerics.Vector4 vector) { throw null; } + public static System.Numerics.Vector4 IsInteger(System.Numerics.Vector4 vector) { throw null; } + public static System.Numerics.Vector4 IsNaN(System.Numerics.Vector4 vector) { throw null; } + public static System.Numerics.Vector4 IsNegative(System.Numerics.Vector4 vector) { throw null; } + public static System.Numerics.Vector4 IsNegativeInfinity(System.Numerics.Vector4 vector) { throw null; } + public static System.Numerics.Vector4 IsNormal(System.Numerics.Vector4 vector) { throw null; } + public static System.Numerics.Vector4 IsOddInteger(System.Numerics.Vector4 vector) { throw null; } + public static System.Numerics.Vector4 IsPositive(System.Numerics.Vector4 vector) { throw null; } + public static System.Numerics.Vector4 IsPositiveInfinity(System.Numerics.Vector4 vector) { throw null; } + public static System.Numerics.Vector4 IsSubnormal(System.Numerics.Vector4 vector) { throw null; } + public static System.Numerics.Vector4 IsZero(System.Numerics.Vector4 vector) { throw null; } + public static int LastIndexOf(System.Numerics.Vector4 vector, float value) { throw null; } + public static int LastIndexOfWhereAllBitsSet(System.Numerics.Vector4 vector) { throw null; } public readonly float Length() { throw null; } public readonly float LengthSquared() { throw null; } - public static System.Numerics.Vector4 Hypot(System.Numerics.Vector4 x, System.Numerics.Vector4 y) { throw null; } public static System.Numerics.Vector4 Lerp(System.Numerics.Vector4 value1, System.Numerics.Vector4 value2, float amount) { throw null; } public static System.Numerics.Vector4 Lerp(System.Numerics.Vector4 value1, System.Numerics.Vector4 value2, System.Numerics.Vector4 amount) { throw null; } + public static Vector4 LessThan(System.Numerics.Vector4 left, System.Numerics.Vector4 right) { throw null; } + public static bool LessThanAll(System.Numerics.Vector4 left, System.Numerics.Vector4 right) { throw null; } + public static bool LessThanAny(System.Numerics.Vector4 left, System.Numerics.Vector4 right) { throw null; } + public static Vector4 LessThanOrEqual(System.Numerics.Vector4 left, System.Numerics.Vector4 right) { throw null; } + public static bool LessThanOrEqualAll(System.Numerics.Vector4 left, System.Numerics.Vector4 right) { throw null; } + public static bool LessThanOrEqualAny(System.Numerics.Vector4 left, System.Numerics.Vector4 right) { throw null; } public static System.Numerics.Vector4 Log(System.Numerics.Vector4 vector) { throw null; } public static System.Numerics.Vector4 Log2(System.Numerics.Vector4 vector) { throw null; } + [CLSCompliant(false)] + public static unsafe System.Numerics.Vector4 Load(float* source) { throw null; } + [CLSCompliant(false)] + public static unsafe System.Numerics.Vector4 LoadAligned(float* source) { throw null; } + [CLSCompliant(false)] + public static unsafe System.Numerics.Vector4 LoadAlignedNonTemporal(float* source) { throw null; } + public static System.Numerics.Vector4 LoadUnsafe(ref readonly float source) { throw null; } + [CLSCompliant(false)] + public static System.Numerics.Vector4 LoadUnsafe(ref readonly float source, nuint elementOffset) { throw null; } public static System.Numerics.Vector4 Max(System.Numerics.Vector4 value1, System.Numerics.Vector4 value2) { throw null; } public static System.Numerics.Vector4 MaxMagnitude(System.Numerics.Vector4 value1, System.Numerics.Vector4 value2) { throw null; } public static System.Numerics.Vector4 MaxMagnitudeNumber(System.Numerics.Vector4 value1, System.Numerics.Vector4 value2) { throw null; } @@ -728,24 +974,37 @@ public readonly void CopyTo(System.Span destination) { } public static System.Numerics.Vector4 Multiply(float left, System.Numerics.Vector4 right) { throw null; } public static System.Numerics.Vector4 MultiplyAddEstimate(System.Numerics.Vector4 left, System.Numerics.Vector4 right, System.Numerics.Vector4 addend) { throw null; } public static System.Numerics.Vector4 Negate(System.Numerics.Vector4 value) { throw null; } + public static bool None(System.Numerics.Vector4 vector, float value) { throw null; } + public static bool NoneWhereAllBitsSet(System.Numerics.Vector4 vector) { throw null; } public static System.Numerics.Vector4 Normalize(System.Numerics.Vector4 vector) { throw null; } + public static System.Numerics.Vector4 OnesComplement(System.Numerics.Vector4 value) { throw null; } public static System.Numerics.Vector4 operator +(System.Numerics.Vector4 left, System.Numerics.Vector4 right) { throw null; } + public static System.Numerics.Vector4 operator &(System.Numerics.Vector4 left, System.Numerics.Vector4 right) { throw null; } + public static System.Numerics.Vector4 operator |(System.Numerics.Vector4 left, System.Numerics.Vector4 right) { throw null; } public static System.Numerics.Vector4 operator /(System.Numerics.Vector4 left, System.Numerics.Vector4 right) { throw null; } public static System.Numerics.Vector4 operator /(System.Numerics.Vector4 value1, float value2) { throw null; } + public static System.Numerics.Vector4 operator ^(System.Numerics.Vector4 left, System.Numerics.Vector4 right) { throw null; } public static bool operator ==(System.Numerics.Vector4 left, System.Numerics.Vector4 right) { throw null; } + public static System.Numerics.Vector4 operator <<(System.Numerics.Vector4 value, int shiftAmount) { throw null; } public static bool operator !=(System.Numerics.Vector4 left, System.Numerics.Vector4 right) { throw null; } public static System.Numerics.Vector4 operator *(System.Numerics.Vector4 left, System.Numerics.Vector4 right) { throw null; } public static System.Numerics.Vector4 operator *(System.Numerics.Vector4 left, float right) { throw null; } public static System.Numerics.Vector4 operator *(float left, System.Numerics.Vector4 right) { throw null; } + public static System.Numerics.Vector4 operator ~(System.Numerics.Vector4 value) { throw null; } + public static System.Numerics.Vector4 operator >>(System.Numerics.Vector4 value, int shiftAmount) { throw null; } public static System.Numerics.Vector4 operator -(System.Numerics.Vector4 left, System.Numerics.Vector4 right) { throw null; } public static System.Numerics.Vector4 operator -(System.Numerics.Vector4 value) { throw null; } + public static System.Numerics.Vector4 operator +(System.Numerics.Vector4 value) { throw null; } + public static System.Numerics.Vector4 operator >>>(System.Numerics.Vector4 value, int shiftAmount) { throw null; } public static System.Numerics.Vector4 RadiansToDegrees(System.Numerics.Vector4 radians) { throw null; } public static System.Numerics.Vector4 Round(System.Numerics.Vector4 vector) { throw null; } public static System.Numerics.Vector4 Round(System.Numerics.Vector4 vector, System.MidpointRounding mode) { throw null; } + public static System.Numerics.Vector4 Shuffle(System.Numerics.Vector4 vector, byte xIndex, byte yIndex, byte zIndex, byte wIndex) { throw null; } public static System.Numerics.Vector4 Sin(System.Numerics.Vector4 vector) { throw null; } public static (System.Numerics.Vector4 Sin, System.Numerics.Vector4 Cos) SinCos(System.Numerics.Vector4 vector) { throw null; } public static System.Numerics.Vector4 SquareRoot(System.Numerics.Vector4 value) { throw null; } public static System.Numerics.Vector4 Subtract(System.Numerics.Vector4 left, System.Numerics.Vector4 right) { throw null; } + public static float Sum(System.Numerics.Vector4 value) { throw null; } public override readonly string ToString() { throw null; } public readonly string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format) { throw null; } public readonly string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format, System.IFormatProvider? formatProvider) { throw null; } @@ -756,6 +1015,7 @@ public readonly void CopyTo(System.Span destination) { } public static System.Numerics.Vector4 Transform(System.Numerics.Vector4 vector, System.Numerics.Matrix4x4 matrix) { throw null; } public static System.Numerics.Vector4 Transform(System.Numerics.Vector4 value, System.Numerics.Quaternion rotation) { throw null; } public static System.Numerics.Vector4 Truncate(System.Numerics.Vector4 vector) { throw null; } + public static System.Numerics.Vector4 Xor(System.Numerics.Vector4 left, System.Numerics.Vector4 right) { throw null; } } public readonly partial struct Vector : System.IEquatable>, System.IFormattable { diff --git a/src/libraries/System.Numerics.Vectors/tests/GenericVectorTests.cs b/src/libraries/System.Numerics.Vectors/tests/GenericVectorTests.cs index 28ed4f701d4693..2eb4c0c882437e 100644 --- a/src/libraries/System.Numerics.Vectors/tests/GenericVectorTests.cs +++ b/src/libraries/System.Numerics.Vectors/tests/GenericVectorTests.cs @@ -4652,76 +4652,604 @@ public void HypotSingleTest(float x, float y, float expectedResult, float varian AssertEqual(Vector.Create(expectedResult), Vector.Hypot(Vector.Create(+y), Vector.Create(+x)), Vector.Create(variance)); } + private void IsEvenInteger(T value) + where T : INumber + { + Assert.Equal(T.IsEvenInteger(value) ? Vector.AllBitsSet : Vector.Zero, Vector.IsEvenInteger(Vector.Create(value))); + } + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerByteTest(byte value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerDoubleTest(double value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerInt16Test(short value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerInt32Test(int value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerInt64Test(long value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerSByteTest(sbyte value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerSingleTest(float value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerUInt16Test(ushort value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerUInt32Test(uint value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerUInt64Test(ulong value) => IsEvenInteger(value); + + private void IsFinite(T value) + where T : INumber + { + Assert.Equal(T.IsFinite(value) ? Vector.AllBitsSet : Vector.Zero, Vector.IsFinite(Vector.Create(value))); + } + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteByteTest(byte value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteDoubleTest(double value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteInt16Test(short value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteInt32Test(int value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteInt64Test(long value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteSByteTest(sbyte value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteSingleTest(float value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteUInt16Test(ushort value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteUInt32Test(uint value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteUInt64Test(ulong value) => IsFinite(value); + + private void IsInfinity(T value) + where T : INumber + { + Assert.Equal(T.IsInfinity(value) ? Vector.AllBitsSet : Vector.Zero, Vector.IsInfinity(Vector.Create(value))); + } + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityByteTest(byte value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityDoubleTest(double value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityInt16Test(short value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityInt32Test(int value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityInt64Test(long value) => IsInfinity(value); + [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsNaNDouble), MemberType = typeof(GenericMathTestMemberData))] - public void IsNaNDoubleTest(double value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinitySByteTest(sbyte value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinitySingleTest(float value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityUInt16Test(ushort value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityUInt32Test(uint value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityUInt64Test(ulong value) => IsInfinity(value); + + private void IsInteger(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector.AllBitsSet : Vector.Zero, Vector.IsNaN(Vector.Create(value))); + Assert.Equal(T.IsInteger(value) ? Vector.AllBitsSet : Vector.Zero, Vector.IsInteger(Vector.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsNaNSingle), MemberType = typeof(GenericMathTestMemberData))] - public void IsNaNSingleTest(float value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerByteTest(byte value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerDoubleTest(double value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerInt16Test(short value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerInt32Test(int value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerInt64Test(long value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerSByteTest(sbyte value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerSingleTest(float value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerUInt16Test(ushort value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerUInt32Test(uint value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerUInt64Test(ulong value) => IsInteger(value); + + private void IsNaN(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector.AllBitsSet : Vector.Zero, Vector.IsNaN(Vector.Create(value))); + Assert.Equal(T.IsNaN(value) ? Vector.AllBitsSet : Vector.Zero, Vector.IsNaN(Vector.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsNegativeDouble), MemberType = typeof(GenericMathTestMemberData))] - public void IsNegativeDoubleTest(double value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNByteTest(byte value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNDoubleTest(double value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNInt16Test(short value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNInt32Test(int value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNInt64Test(long value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNSByteTest(sbyte value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNSingleTest(float value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNUInt16Test(ushort value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNUInt32Test(uint value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNUInt64Test(ulong value) => IsNaN(value); + + private void IsNegative(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector.AllBitsSet : Vector.Zero, Vector.IsNegative(Vector.Create(value))); + Assert.Equal(T.IsNegative(value) ? Vector.AllBitsSet : Vector.Zero, Vector.IsNegative(Vector.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsNegativeSingle), MemberType = typeof(GenericMathTestMemberData))] - public void IsNegativeSingleTest(float value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeByteTest(byte value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeDoubleTest(double value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInt16Test(short value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInt32Test(int value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInt64Test(long value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeSByteTest(sbyte value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeSingleTest(float value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeUInt16Test(ushort value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeUInt32Test(uint value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeUInt64Test(ulong value) => IsNegative(value); + + private void IsNegativeInfinity(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector.AllBitsSet : Vector.Zero, Vector.IsNegative(Vector.Create(value))); + Assert.Equal(T.IsNegativeInfinity(value) ? Vector.AllBitsSet : Vector.Zero, Vector.IsNegativeInfinity(Vector.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsPositiveDouble), MemberType = typeof(GenericMathTestMemberData))] - public void IsPositiveDoubleTest(double value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityByteTest(byte value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityDoubleTest(double value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityInt16Test(short value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityInt32Test(int value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityInt64Test(long value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinitySByteTest(sbyte value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinitySingleTest(float value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityUInt16Test(ushort value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityUInt32Test(uint value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityUInt64Test(ulong value) => IsNegativeInfinity(value); + + private void IsNormal(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector.AllBitsSet : Vector.Zero, Vector.IsPositive(Vector.Create(value))); + Assert.Equal(T.IsNormal(value) ? Vector.AllBitsSet : Vector.Zero, Vector.IsNormal(Vector.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsPositiveSingle), MemberType = typeof(GenericMathTestMemberData))] - public void IsPositiveSingleTest(float value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalByteTest(byte value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalDoubleTest(double value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalInt16Test(short value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalInt32Test(int value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalInt64Test(long value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalSByteTest(sbyte value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalSingleTest(float value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalUInt16Test(ushort value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalUInt32Test(uint value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalUInt64Test(ulong value) => IsNormal(value); + + private void IsOddInteger(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector.AllBitsSet : Vector.Zero, Vector.IsPositive(Vector.Create(value))); + Assert.Equal(T.IsOddInteger(value) ? Vector.AllBitsSet : Vector.Zero, Vector.IsOddInteger(Vector.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsPositiveInfinityDouble), MemberType = typeof(GenericMathTestMemberData))] - public void IsPositiveInfinityDoubleTest(double value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerByteTest(byte value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerDoubleTest(double value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerInt16Test(short value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerInt32Test(int value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerInt64Test(long value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerSByteTest(sbyte value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerSingleTest(float value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerUInt16Test(ushort value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerUInt32Test(uint value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerUInt64Test(ulong value) => IsOddInteger(value); + + private void IsPositive(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector.AllBitsSet : Vector.Zero, Vector.IsPositiveInfinity(Vector.Create(value))); + Assert.Equal(T.IsPositive(value) ? Vector.AllBitsSet : Vector.Zero, Vector.IsPositive(Vector.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsPositiveInfinitySingle), MemberType = typeof(GenericMathTestMemberData))] - public void IsPositiveInfinitySingleTest(float value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveByteTest(byte value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveDoubleTest(double value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInt16Test(short value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInt32Test(int value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInt64Test(long value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveSByteTest(sbyte value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveSingleTest(float value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveUInt16Test(ushort value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveUInt32Test(uint value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveUInt64Test(ulong value) => IsPositive(value); + + private void IsPositiveInfinity(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector.AllBitsSet : Vector.Zero, Vector.IsPositiveInfinity(Vector.Create(value))); + Assert.Equal(T.IsPositiveInfinity(value) ? Vector.AllBitsSet : Vector.Zero, Vector.IsPositiveInfinity(Vector.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsZeroDouble), MemberType = typeof(GenericMathTestMemberData))] - public void IsZeroDoubleTest(double value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityByteTest(byte value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityDoubleTest(double value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityInt16Test(short value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityInt32Test(int value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityInt64Test(long value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinitySByteTest(sbyte value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinitySingleTest(float value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityUInt16Test(ushort value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityUInt32Test(uint value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityUInt64Test(ulong value) => IsPositiveInfinity(value); + + private void IsSubnormal(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector.AllBitsSet : Vector.Zero, Vector.IsZero(Vector.Create(value))); + Assert.Equal(T.IsSubnormal(value) ? Vector.AllBitsSet : Vector.Zero, Vector.IsSubnormal(Vector.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsZeroSingle), MemberType = typeof(GenericMathTestMemberData))] - public void IsZeroSingleTest(float value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalByteTest(byte value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalDoubleTest(double value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalInt16Test(short value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalInt32Test(int value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalInt64Test(long value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalSByteTest(sbyte value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalSingleTest(float value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalUInt16Test(ushort value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalUInt32Test(uint value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalUInt64Test(ulong value) => IsSubnormal(value); + + private void IsZero(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector.AllBitsSet : Vector.Zero, Vector.IsZero(Vector.Create(value))); + Assert.Equal(T.IsZero(value) ? Vector.AllBitsSet : Vector.Zero, Vector.IsZero(Vector.Create(value))); } + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroByteTest(byte value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroDoubleTest(double value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroInt16Test(short value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroInt32Test(int value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroInt64Test(long value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroSByteTest(sbyte value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroSingleTest(float value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroUInt16Test(ushort value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroUInt32Test(uint value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroUInt64Test(ulong value) => IsZero(value); + [Theory] [MemberData(nameof(GenericMathTestMemberData.LerpDouble), MemberType = typeof(GenericMathTestMemberData))] public void LerpDoubleTest(double x, double y, double amount, double expectedResult) @@ -4979,5 +5507,275 @@ public void TruncateSingleTest(float value, float expectedResult) Vector actualResult = Vector.Truncate(Vector.Create(value)); AssertEqual(Vector.Create(expectedResult), actualResult, Vector.Zero); } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void AllAnyNoneTest(T value1, T value2) + where T : struct, INumber + { + var input1 = Vector.Create(value1); + var input2 = Vector.Create(value2); + + Assert.True(Vector.All(input1, value1)); + Assert.True(Vector.All(input2, value2)); + Assert.False(Vector.All(input1.WithElement(0, value2), value1)); + Assert.False(Vector.All(input2.WithElement(0, value1), value2)); + Assert.False(Vector.All(input1, value2)); + Assert.False(Vector.All(input2, value1)); + Assert.False(Vector.All(input1.WithElement(0, value2), value2)); + Assert.False(Vector.All(input2.WithElement(0, value1), value1)); + + Assert.True(Vector.Any(input1, value1)); + Assert.True(Vector.Any(input2, value2)); + Assert.True(Vector.Any(input1.WithElement(0, value2), value1)); + Assert.True(Vector.Any(input2.WithElement(0, value1), value2)); + Assert.False(Vector.Any(input1, value2)); + Assert.False(Vector.Any(input2, value1)); + Assert.True(Vector.Any(input1.WithElement(0, value2), value2)); + Assert.True(Vector.Any(input2.WithElement(0, value1), value1)); + + Assert.False(Vector.None(input1, value1)); + Assert.False(Vector.None(input2, value2)); + Assert.False(Vector.None(input1.WithElement(0, value2), value1)); + Assert.False(Vector.None(input2.WithElement(0, value1), value2)); + Assert.True(Vector.None(input1, value2)); + Assert.True(Vector.None(input2, value1)); + Assert.False(Vector.None(input1.WithElement(0, value2), value2)); + Assert.False(Vector.None(input2.WithElement(0, value1), value1)); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void AllAnyNoneTest_IFloatingPointIeee754(T value) + where T : struct, IFloatingPointIeee754 + { + var input = Vector.Create(value); + + Assert.False(Vector.All(input, value)); + Assert.False(Vector.Any(input, value)); + Assert.True(Vector.None(input, value)); + } + + [Fact] + public void AllAnyNoneByteTest() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneDoubleTest() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneDoubleTest_AllBitsSet() => AllAnyNoneTest_IFloatingPointIeee754(BitConverter.Int64BitsToDouble(-1)); + + [Fact] + public void AllAnyNoneInt16Test() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneInt32Test() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneInt64Test() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneSByteTest() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneSingleTest() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneSingleTest_AllBitsSet() => AllAnyNoneTest_IFloatingPointIeee754(BitConverter.Int32BitsToSingle(-1)); + + [Fact] + public void AllAnyNoneUInt16Test() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneUInt32Test() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneUInt64Test() => AllAnyNoneTest(3, 2); + + [MethodImpl(MethodImplOptions.NoInlining)] + private void AllAnyNoneWhereAllBitsSetTest(T allBitsSet, T value2) + where T : struct, INumber + { + var input1 = Vector.Create(allBitsSet); + var input2 = Vector.Create(value2); + + Assert.True(Vector.AllWhereAllBitsSet(input1)); + Assert.False(Vector.AllWhereAllBitsSet(input2)); + Assert.False(Vector.AllWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.False(Vector.AllWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + + Assert.True(Vector.AnyWhereAllBitsSet(input1)); + Assert.False(Vector.AnyWhereAllBitsSet(input2)); + Assert.True(Vector.AnyWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.True(Vector.AnyWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + + Assert.False(Vector.NoneWhereAllBitsSet(input1)); + Assert.True(Vector.NoneWhereAllBitsSet(input2)); + Assert.False(Vector.NoneWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.False(Vector.NoneWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + } + + [Fact] + public void AllAnyNoneWhereAllBitsSetByteTest() => AllAnyNoneWhereAllBitsSetTest(byte.MaxValue, 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetDoubleTest() => AllAnyNoneWhereAllBitsSetTest(BitConverter.Int64BitsToDouble(-1), 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetInt16Test() => AllAnyNoneWhereAllBitsSetTest(-1, 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetInt32Test() => AllAnyNoneWhereAllBitsSetTest(-1, 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetInt64Test() => AllAnyNoneWhereAllBitsSetTest(-1, 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetSByteTest() => AllAnyNoneWhereAllBitsSetTest(-1, 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetSingleTest() => AllAnyNoneWhereAllBitsSetTest(BitConverter.Int32BitsToSingle(-1), 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetUInt16Test() => AllAnyNoneWhereAllBitsSetTest(ushort.MaxValue, 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetUInt32Test() => AllAnyNoneWhereAllBitsSetTest(uint.MaxValue, 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetUInt64Test() => AllAnyNoneWhereAllBitsSetTest(ulong.MaxValue, 2); + + [MethodImpl(MethodImplOptions.NoInlining)] + private void CountIndexOfLastIndexOfTest(T value1, T value2) + where T : struct, INumber + { + var input1 = Vector.Create(value1); + var input2 = Vector.Create(value2); + + Assert.Equal(Vector.Count, Vector.Count(input1, value1)); + Assert.Equal(Vector.Count, Vector.Count(input2, value2)); + Assert.Equal(Vector.Count - 1, Vector.Count(input1.WithElement(0, value2), value1)); + Assert.Equal(Vector.Count - 1, Vector.Count(input2.WithElement(0, value1), value2)); + Assert.Equal(0, Vector.Count(input1, value2)); + Assert.Equal(0, Vector.Count(input2, value1)); + Assert.Equal(1, Vector.Count(input1.WithElement(0, value2), value2)); + Assert.Equal(1, Vector.Count(input2.WithElement(0, value1), value1)); + + Assert.Equal(0, Vector.IndexOf(input1, value1)); + Assert.Equal(0, Vector.IndexOf(input2, value2)); + Assert.Equal(1, Vector.IndexOf(input1.WithElement(0, value2), value1)); + Assert.Equal(1, Vector.IndexOf(input2.WithElement(0, value1), value2)); + Assert.Equal(-1, Vector.IndexOf(input1, value2)); + Assert.Equal(-1, Vector.IndexOf(input2, value1)); + Assert.Equal(0, Vector.IndexOf(input1.WithElement(0, value2), value2)); + Assert.Equal(0, Vector.IndexOf(input2.WithElement(0, value1), value1)); + + Assert.Equal(Vector.Count - 1, Vector.LastIndexOf(input1, value1)); + Assert.Equal(Vector.Count - 1, Vector.LastIndexOf(input2, value2)); + Assert.Equal(Vector.Count - 1, Vector.LastIndexOf(input1.WithElement(0, value2), value1)); + Assert.Equal(Vector.Count - 1, Vector.LastIndexOf(input2.WithElement(0, value1), value2)); + Assert.Equal(-1, Vector.LastIndexOf(input1, value2)); + Assert.Equal(-1, Vector.LastIndexOf(input2, value1)); + Assert.Equal(0, Vector.LastIndexOf(input1.WithElement(0, value2), value2)); + Assert.Equal(0, Vector.LastIndexOf(input2.WithElement(0, value1), value1)); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void CountIndexOfLastIndexOfTest_IFloatingPointIeee754(T value) + where T : struct, IFloatingPointIeee754 + { + var input = Vector.Create(value); + + Assert.Equal(0, Vector.Count(input, value)); + Assert.Equal(-1, Vector.IndexOf(input, value)); + Assert.Equal(-1, Vector.LastIndexOf(input, value)); + } + + [Fact] + public void CountIndexOfLastIndexOfByteTest() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfDoubleTest() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfDoubleTest_AllBitsSet() => CountIndexOfLastIndexOfTest_IFloatingPointIeee754(BitConverter.Int64BitsToDouble(-1)); + + [Fact] + public void CountIndexOfLastIndexOfInt16Test() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfInt32Test() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfInt64Test() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfSByteTest() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfSingleTest() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfSingleTest_AllBitsSet() => CountIndexOfLastIndexOfTest_IFloatingPointIeee754(BitConverter.Int32BitsToSingle(-1)); + + [Fact] + public void CountIndexOfLastIndexOfUInt16Test() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfUInt32Test() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfUInt64Test() => CountIndexOfLastIndexOfTest(3, 2); + + [MethodImpl(MethodImplOptions.NoInlining)] + private void CountIndexOfLastIndexOfWhereAllBitsSetTest(T allBitsSet, T value2) + where T : struct, INumber + { + var input1 = Vector.Create(allBitsSet); + var input2 = Vector.Create(value2); + + Assert.Equal(Vector.Count, Vector.CountWhereAllBitsSet(input1)); + Assert.Equal(0, Vector.CountWhereAllBitsSet(input2)); + Assert.Equal(Vector.Count - 1, Vector.CountWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.Equal(1, Vector.CountWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + + Assert.Equal(0, Vector.IndexOfWhereAllBitsSet(input1)); + Assert.Equal(-1, Vector.IndexOfWhereAllBitsSet(input2)); + Assert.Equal(1, Vector.IndexOfWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.Equal(0, Vector.IndexOfWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + + Assert.Equal(Vector.Count - 1, Vector.LastIndexOfWhereAllBitsSet(input1)); + Assert.Equal(-1, Vector.LastIndexOfWhereAllBitsSet(input2)); + Assert.Equal(Vector.Count - 1, Vector.LastIndexOfWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.Equal(0, Vector.LastIndexOfWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + } + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetByteTest() => CountIndexOfLastIndexOfWhereAllBitsSetTest(byte.MaxValue, 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetDoubleTest() => CountIndexOfLastIndexOfWhereAllBitsSetTest(BitConverter.Int64BitsToDouble(-1), 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetInt16Test() => CountIndexOfLastIndexOfWhereAllBitsSetTest(-1, 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetInt32Test() => CountIndexOfLastIndexOfWhereAllBitsSetTest(-1, 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetInt64Test() => CountIndexOfLastIndexOfWhereAllBitsSetTest(-1, 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetSByteTest() => CountIndexOfLastIndexOfWhereAllBitsSetTest(-1, 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetSingleTest() => CountIndexOfLastIndexOfWhereAllBitsSetTest(BitConverter.Int32BitsToSingle(-1), 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetUInt16Test() => CountIndexOfLastIndexOfWhereAllBitsSetTest(ushort.MaxValue, 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetUInt32Test() => CountIndexOfLastIndexOfWhereAllBitsSetTest(uint.MaxValue, 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetUInt64Test() => CountIndexOfLastIndexOfWhereAllBitsSetTest(ulong.MaxValue, 2); } } diff --git a/src/libraries/System.Numerics.Vectors/tests/Vector2Tests.cs b/src/libraries/System.Numerics.Vectors/tests/Vector2Tests.cs index f2b4a61bbd9bc7..9f6ab423bfab8f 100644 --- a/src/libraries/System.Numerics.Vectors/tests/Vector2Tests.cs +++ b/src/libraries/System.Numerics.Vectors/tests/Vector2Tests.cs @@ -2,7 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Globalization; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; using System.Tests; using Xunit; @@ -10,6 +12,8 @@ namespace System.Numerics.Tests { public sealed class Vector2Tests { + private const int ElementCount = 2; + /// Verifies that two values are equal, within the . /// The expected value /// The value to be compared against @@ -1506,5 +1510,310 @@ public void TruncateSingleTest(float value, float expectedResult) Vector2 actualResult = Vector2.Truncate(Vector2.Create(value)); AssertEqual(Vector2.Create(expectedResult), actualResult, Vector2.Zero); } + + [Fact] + public void AllAnyNoneTest() + { + Test(3, 2); + + [MethodImpl(MethodImplOptions.NoInlining)] + void Test(float value1, float value2) + { + var input1 = Vector2.Create(value1); + var input2 = Vector2.Create(value2); + + Assert.True(Vector2.All(input1, value1)); + Assert.True(Vector2.All(input2, value2)); + Assert.False(Vector2.All(input1.WithElement(0, value2), value1)); + Assert.False(Vector2.All(input2.WithElement(0, value1), value2)); + Assert.False(Vector2.All(input1, value2)); + Assert.False(Vector2.All(input2, value1)); + Assert.False(Vector2.All(input1.WithElement(0, value2), value2)); + Assert.False(Vector2.All(input2.WithElement(0, value1), value1)); + + Assert.True(Vector2.Any(input1, value1)); + Assert.True(Vector2.Any(input2, value2)); + Assert.True(Vector2.Any(input1.WithElement(0, value2), value1)); + Assert.True(Vector2.Any(input2.WithElement(0, value1), value2)); + Assert.False(Vector2.Any(input1, value2)); + Assert.False(Vector2.Any(input2, value1)); + Assert.True(Vector2.Any(input1.WithElement(0, value2), value2)); + Assert.True(Vector2.Any(input2.WithElement(0, value1), value1)); + + Assert.False(Vector2.None(input1, value1)); + Assert.False(Vector2.None(input2, value2)); + Assert.False(Vector2.None(input1.WithElement(0, value2), value1)); + Assert.False(Vector2.None(input2.WithElement(0, value1), value2)); + Assert.True(Vector2.None(input1, value2)); + Assert.True(Vector2.None(input2, value1)); + Assert.False(Vector2.None(input1.WithElement(0, value2), value2)); + Assert.False(Vector2.None(input2.WithElement(0, value1), value1)); + } + } + + [Fact] + public void AllAnyNoneTest_AllBitsSet() + { + Test(BitConverter.Int32BitsToSingle(-1)); + + [MethodImpl(MethodImplOptions.NoInlining)] + void Test(float value) + { + var input = Vector2.Create(value); + + Assert.False(Vector2.All(input, value)); + Assert.False(Vector2.Any(input, value)); + Assert.True(Vector2.None(input, value)); + } + } + + [Fact] + public void AllAnyNoneWhereAllBitsSetTest() + { + Test(BitConverter.Int32BitsToSingle(-1), 2); + + [MethodImpl(MethodImplOptions.NoInlining)] + void Test(float allBitsSet, float value2) + { + var input1 = Vector2.Create(allBitsSet); + var input2 = Vector2.Create(value2); + + Assert.True(Vector2.AllWhereAllBitsSet(input1)); + Assert.False(Vector2.AllWhereAllBitsSet(input2)); + Assert.False(Vector2.AllWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.False(Vector2.AllWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + + Assert.True(Vector2.AnyWhereAllBitsSet(input1)); + Assert.False(Vector2.AnyWhereAllBitsSet(input2)); + Assert.True(Vector2.AnyWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.True(Vector2.AnyWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + + Assert.False(Vector2.NoneWhereAllBitsSet(input1)); + Assert.True(Vector2.NoneWhereAllBitsSet(input2)); + Assert.False(Vector2.NoneWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.False(Vector2.NoneWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + } + } + + [Fact] + public void CountIndexOfLastIndexOfSingleTest() + { + Test(3, 2); + + [MethodImpl(MethodImplOptions.NoInlining)] + void Test(float value1, float value2) + { + var input1 = Vector2.Create(value1); + var input2 = Vector2.Create(value2); + + Assert.Equal(ElementCount, Vector2.Count(input1, value1)); + Assert.Equal(ElementCount, Vector2.Count(input2, value2)); + Assert.Equal(ElementCount - 1, Vector2.Count(input1.WithElement(0, value2), value1)); + Assert.Equal(ElementCount - 1, Vector2.Count(input2.WithElement(0, value1), value2)); + Assert.Equal(0, Vector2.Count(input1, value2)); + Assert.Equal(0, Vector2.Count(input2, value1)); + Assert.Equal(1, Vector2.Count(input1.WithElement(0, value2), value2)); + Assert.Equal(1, Vector2.Count(input2.WithElement(0, value1), value1)); + + Assert.Equal(0, Vector2.IndexOf(input1, value1)); + Assert.Equal(0, Vector2.IndexOf(input2, value2)); + Assert.Equal(1, Vector2.IndexOf(input1.WithElement(0, value2), value1)); + Assert.Equal(1, Vector2.IndexOf(input2.WithElement(0, value1), value2)); + Assert.Equal(-1, Vector2.IndexOf(input1, value2)); + Assert.Equal(-1, Vector2.IndexOf(input2, value1)); + Assert.Equal(0, Vector2.IndexOf(input1.WithElement(0, value2), value2)); + Assert.Equal(0, Vector2.IndexOf(input2.WithElement(0, value1), value1)); + + Assert.Equal(ElementCount - 1, Vector2.LastIndexOf(input1, value1)); + Assert.Equal(ElementCount - 1, Vector2.LastIndexOf(input2, value2)); + Assert.Equal(ElementCount - 1, Vector2.LastIndexOf(input1.WithElement(0, value2), value1)); + Assert.Equal(ElementCount - 1, Vector2.LastIndexOf(input2.WithElement(0, value1), value2)); + Assert.Equal(-1, Vector2.LastIndexOf(input1, value2)); + Assert.Equal(-1, Vector2.LastIndexOf(input2, value1)); + Assert.Equal(0, Vector2.LastIndexOf(input1.WithElement(0, value2), value2)); + Assert.Equal(0, Vector2.LastIndexOf(input2.WithElement(0, value1), value1)); + } + } + + [Fact] + public void CountIndexOfLastIndexOfSingleTest_AllBitsSet() + { + Test(BitConverter.Int32BitsToSingle(-1)); + + [MethodImpl(MethodImplOptions.NoInlining)] + void Test(float value) + { + var input = Vector2.Create(value); + + Assert.Equal(0, Vector2.Count(input, value)); + Assert.Equal(-1, Vector2.IndexOf(input, value)); + Assert.Equal(-1, Vector2.LastIndexOf(input, value)); + } + } + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetSingleTest() + { + Test(BitConverter.Int32BitsToSingle(-1), 2); + + [MethodImpl(MethodImplOptions.NoInlining)] + void Test(float allBitsSet, float value2) + { + var input1 = Vector2.Create(allBitsSet); + var input2 = Vector2.Create(value2); + + Assert.Equal(ElementCount, Vector2.CountWhereAllBitsSet(input1)); + Assert.Equal(0, Vector2.CountWhereAllBitsSet(input2)); + Assert.Equal(ElementCount - 1, Vector2.CountWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.Equal(1, Vector2.CountWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + + Assert.Equal(0, Vector2.IndexOfWhereAllBitsSet(input1)); + Assert.Equal(-1, Vector2.IndexOfWhereAllBitsSet(input2)); + Assert.Equal(1, Vector2.IndexOfWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.Equal(0, Vector2.IndexOfWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + + Assert.Equal(ElementCount - 1, Vector2.LastIndexOfWhereAllBitsSet(input1)); + Assert.Equal(-1, Vector2.LastIndexOfWhereAllBitsSet(input2)); + Assert.Equal(ElementCount - 1, Vector2.LastIndexOfWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.Equal(0, Vector2.LastIndexOfWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + } + } + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerTest(float value) => Assert.Equal(float.IsEvenInteger(value) ? Vector2.AllBitsSet : Vector2.Zero, Vector2.IsEvenInteger(Vector2.Create(value))); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteTest(float value) => Assert.Equal(float.IsFinite(value) ? Vector2.AllBitsSet : Vector2.Zero, Vector2.IsFinite(Vector2.Create(value))); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityTest(float value) => Assert.Equal(float.IsInfinity(value) ? Vector2.AllBitsSet : Vector2.Zero, Vector2.IsInfinity(Vector2.Create(value))); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerTest(float value) => Assert.Equal(float.IsInteger(value) ? Vector2.AllBitsSet : Vector2.Zero, Vector2.IsInteger(Vector2.Create(value))); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNTest(float value) => Assert.Equal(float.IsNaN(value) ? Vector2.AllBitsSet : Vector2.Zero, Vector2.IsNaN(Vector2.Create(value))); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeTest(float value) => Assert.Equal(float.IsNegative(value) ? Vector2.AllBitsSet : Vector2.Zero, Vector2.IsNegative(Vector2.Create(value))); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityTest(float value) => Assert.Equal(float.IsNegativeInfinity(value) ? Vector2.AllBitsSet : Vector2.Zero, Vector2.IsNegativeInfinity(Vector2.Create(value))); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalTest(float value) => Assert.Equal(float.IsNormal(value) ? Vector2.AllBitsSet : Vector2.Zero, Vector2.IsNormal(Vector2.Create(value))); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerTest(float value) => Assert.Equal(float.IsOddInteger(value) ? Vector2.AllBitsSet : Vector2.Zero, Vector2.IsOddInteger(Vector2.Create(value))); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveTest(float value) => Assert.Equal(float.IsPositive(value) ? Vector2.AllBitsSet : Vector2.Zero, Vector2.IsPositive(Vector2.Create(value))); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityTest(float value) => Assert.Equal(float.IsPositiveInfinity(value) ? Vector2.AllBitsSet : Vector2.Zero, Vector2.IsPositiveInfinity(Vector2.Create(value))); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalTest(float value) => Assert.Equal(float.IsSubnormal(value) ? Vector2.AllBitsSet : Vector2.Zero, Vector2.IsSubnormal(Vector2.Create(value))); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroSingleTest(float value) => Assert.Equal((value == 0) ? Vector2.AllBitsSet : Vector2.Zero, Vector2.IsZero(Vector2.Create(value))); + + [Fact] + public void AllBitsSetTest() + { + Assert.Equal(-1, BitConverter.SingleToInt32Bits(Vector2.AllBitsSet.X)); + Assert.Equal(-1, BitConverter.SingleToInt32Bits(Vector2.AllBitsSet.Y)); + } + + [Fact] + public void ConditionalSelectTest() + { + Test(Vector2.Create(1, 2), Vector2.AllBitsSet, Vector2.Create(1, 2), Vector2.Create(5, 6)); + Test(Vector2.Create(5, 6), Vector2.Zero, Vector2.Create(1, 2), Vector2.Create(5, 6)); + Test(Vector2.Create(1, 6), Vector128.Create(-1, 0, -1, 0).AsSingle().AsVector2(), Vector2.Create(1, 2), Vector2.Create(5, 6)); + + [MethodImpl(MethodImplOptions.NoInlining)] + void Test(Vector2 expectedResult, Vector2 condition, Vector2 left, Vector2 right) + { + Assert.Equal(expectedResult, Vector2.ConditionalSelect(condition, left, right)); + } + } + + [Theory] + [InlineData(+0.0f, +0.0f, 0b00)] + [InlineData(-0.0f, +1.0f, 0b01)] + [InlineData(-0.0f, -0.0f, 0b11)] + public void ExtractMostSignificantBitsTest(float x, float y, uint expectedResult) + { + Assert.Equal(expectedResult, Vector2.Create(x, y).ExtractMostSignificantBits()); + } + + [Theory] + [InlineData(1.0f, 2.0f)] + [InlineData(5.0f, 6.0f)] + public void GetElementTest(float x, float y) + { + Assert.Equal(x, Vector2.Create(x, y).GetElement(0)); + Assert.Equal(y, Vector2.Create(x, y).GetElement(1)); + } + + [Theory] + [InlineData(1.0f, 2.0f)] + [InlineData(5.0f, 6.0f)] + public void ShuffleTest(float x, float y) + { + Assert.Equal(Vector2.Create(y, x), Vector2.Shuffle(Vector2.Create(x, y), 1, 0)); + Assert.Equal(Vector2.Create(x, x), Vector2.Shuffle(Vector2.Create(x, y), 0, 0)); + } + + [Theory] + [InlineData(1.0f, 2.0f, 3.0f)] + [InlineData(5.0f, 6.0f, 11.0f)] + public void SumTest(float x, float y, float expectedResult) + { + Assert.Equal(expectedResult, Vector2.Sum(Vector2.Create(x, y))); + } + + [Theory] + [InlineData(1.0f, 2.0f)] + [InlineData(5.0f, 6.0f)] + public void ToScalarTest(float x, float y) + { + Assert.Equal(x, Vector2.Create(x, y).ToScalar()); + } + + [Theory] + [InlineData(1.0f, 2.0f)] + [InlineData(5.0f, 6.0f)] + public void WithElementTest(float x, float y) + { + var vector = Vector2.Create(10); + + Assert.Equal(10, vector.X); + Assert.Equal(10, vector.Y); + + vector = vector.WithElement(0, x); + + Assert.Equal(x, vector.X); + Assert.Equal(10, vector.Y); + + vector = vector.WithElement(1, y); + + Assert.Equal(x, vector.X); + Assert.Equal(y, vector.Y); + } } } diff --git a/src/libraries/System.Numerics.Vectors/tests/Vector3Tests.cs b/src/libraries/System.Numerics.Vectors/tests/Vector3Tests.cs index 210caf826fb10d..880cf4be75e7cb 100644 --- a/src/libraries/System.Numerics.Vectors/tests/Vector3Tests.cs +++ b/src/libraries/System.Numerics.Vectors/tests/Vector3Tests.cs @@ -2,7 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Globalization; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; using System.Tests; using Xunit; @@ -10,6 +12,8 @@ namespace System.Numerics.Tests { public sealed class Vector3Tests { + private const int ElementCount = 3; + /// Verifies that two values are equal, within the . /// The expected value /// The value to be compared against @@ -1556,5 +1560,321 @@ public void TruncateSingleTest(float value, float expectedResult) Vector3 actualResult = Vector3.Truncate(Vector3.Create(value)); AssertEqual(Vector3.Create(expectedResult), actualResult, Vector3.Zero); } + + [Fact] + public void AllAnyNoneTest() + { + Test(3, 2); + + [MethodImpl(MethodImplOptions.NoInlining)] + void Test(float value1, float value2) + { + var input1 = Vector3.Create(value1); + var input2 = Vector3.Create(value2); + + Assert.True(Vector3.All(input1, value1)); + Assert.True(Vector3.All(input2, value2)); + Assert.False(Vector3.All(input1.WithElement(0, value2), value1)); + Assert.False(Vector3.All(input2.WithElement(0, value1), value2)); + Assert.False(Vector3.All(input1, value2)); + Assert.False(Vector3.All(input2, value1)); + Assert.False(Vector3.All(input1.WithElement(0, value2), value2)); + Assert.False(Vector3.All(input2.WithElement(0, value1), value1)); + + Assert.True(Vector3.Any(input1, value1)); + Assert.True(Vector3.Any(input2, value2)); + Assert.True(Vector3.Any(input1.WithElement(0, value2), value1)); + Assert.True(Vector3.Any(input2.WithElement(0, value1), value2)); + Assert.False(Vector3.Any(input1, value2)); + Assert.False(Vector3.Any(input2, value1)); + Assert.True(Vector3.Any(input1.WithElement(0, value2), value2)); + Assert.True(Vector3.Any(input2.WithElement(0, value1), value1)); + + Assert.False(Vector3.None(input1, value1)); + Assert.False(Vector3.None(input2, value2)); + Assert.False(Vector3.None(input1.WithElement(0, value2), value1)); + Assert.False(Vector3.None(input2.WithElement(0, value1), value2)); + Assert.True(Vector3.None(input1, value2)); + Assert.True(Vector3.None(input2, value1)); + Assert.False(Vector3.None(input1.WithElement(0, value2), value2)); + Assert.False(Vector3.None(input2.WithElement(0, value1), value1)); + } + } + + [Fact] + public void AllAnyNoneTest_AllBitsSet() + { + Test(BitConverter.Int32BitsToSingle(-1)); + + [MethodImpl(MethodImplOptions.NoInlining)] + void Test(float value) + { + var input = Vector3.Create(value); + + Assert.False(Vector3.All(input, value)); + Assert.False(Vector3.Any(input, value)); + Assert.True(Vector3.None(input, value)); + } + } + + [Fact] + public void AllAnyNoneWhereAllBitsSetTest() + { + Test(BitConverter.Int32BitsToSingle(-1), 2); + + [MethodImpl(MethodImplOptions.NoInlining)] + void Test(float allBitsSet, float value2) + { + var input1 = Vector3.Create(allBitsSet); + var input2 = Vector3.Create(value2); + + Assert.True(Vector3.AllWhereAllBitsSet(input1)); + Assert.False(Vector3.AllWhereAllBitsSet(input2)); + Assert.False(Vector3.AllWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.False(Vector3.AllWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + + Assert.True(Vector3.AnyWhereAllBitsSet(input1)); + Assert.False(Vector3.AnyWhereAllBitsSet(input2)); + Assert.True(Vector3.AnyWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.True(Vector3.AnyWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + + Assert.False(Vector3.NoneWhereAllBitsSet(input1)); + Assert.True(Vector3.NoneWhereAllBitsSet(input2)); + Assert.False(Vector3.NoneWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.False(Vector3.NoneWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + } + } + + [Fact] + public void CountIndexOfLastIndexOfSingleTest() + { + Test(3, 2); + + [MethodImpl(MethodImplOptions.NoInlining)] + void Test(float value1, float value2) + { + var input1 = Vector3.Create(value1); + var input2 = Vector3.Create(value2); + + Assert.Equal(ElementCount, Vector3.Count(input1, value1)); + Assert.Equal(ElementCount, Vector3.Count(input2, value2)); + Assert.Equal(ElementCount - 1, Vector3.Count(input1.WithElement(0, value2), value1)); + Assert.Equal(ElementCount - 1, Vector3.Count(input2.WithElement(0, value1), value2)); + Assert.Equal(0, Vector3.Count(input1, value2)); + Assert.Equal(0, Vector3.Count(input2, value1)); + Assert.Equal(1, Vector3.Count(input1.WithElement(0, value2), value2)); + Assert.Equal(1, Vector3.Count(input2.WithElement(0, value1), value1)); + + Assert.Equal(0, Vector3.IndexOf(input1, value1)); + Assert.Equal(0, Vector3.IndexOf(input2, value2)); + Assert.Equal(1, Vector3.IndexOf(input1.WithElement(0, value2), value1)); + Assert.Equal(1, Vector3.IndexOf(input2.WithElement(0, value1), value2)); + Assert.Equal(-1, Vector3.IndexOf(input1, value2)); + Assert.Equal(-1, Vector3.IndexOf(input2, value1)); + Assert.Equal(0, Vector3.IndexOf(input1.WithElement(0, value2), value2)); + Assert.Equal(0, Vector3.IndexOf(input2.WithElement(0, value1), value1)); + + Assert.Equal(ElementCount - 1, Vector3.LastIndexOf(input1, value1)); + Assert.Equal(ElementCount - 1, Vector3.LastIndexOf(input2, value2)); + Assert.Equal(ElementCount - 1, Vector3.LastIndexOf(input1.WithElement(0, value2), value1)); + Assert.Equal(ElementCount - 1, Vector3.LastIndexOf(input2.WithElement(0, value1), value2)); + Assert.Equal(-1, Vector3.LastIndexOf(input1, value2)); + Assert.Equal(-1, Vector3.LastIndexOf(input2, value1)); + Assert.Equal(0, Vector3.LastIndexOf(input1.WithElement(0, value2), value2)); + Assert.Equal(0, Vector3.LastIndexOf(input2.WithElement(0, value1), value1)); + } + } + + [Fact] + public void CountIndexOfLastIndexOfSingleTest_AllBitsSet() + { + Test(BitConverter.Int32BitsToSingle(-1)); + + [MethodImpl(MethodImplOptions.NoInlining)] + void Test(float value) + { + var input = Vector3.Create(value); + + Assert.Equal(0, Vector3.Count(input, value)); + Assert.Equal(-1, Vector3.IndexOf(input, value)); + Assert.Equal(-1, Vector3.LastIndexOf(input, value)); + } + } + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetSingleTest() + { + Test(BitConverter.Int32BitsToSingle(-1), 2); + + [MethodImpl(MethodImplOptions.NoInlining)] + void Test(float allBitsSet, float value2) + { + var input1 = Vector3.Create(allBitsSet); + var input2 = Vector3.Create(value2); + + Assert.Equal(ElementCount, Vector3.CountWhereAllBitsSet(input1)); + Assert.Equal(0, Vector3.CountWhereAllBitsSet(input2)); + Assert.Equal(ElementCount - 1, Vector3.CountWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.Equal(1, Vector3.CountWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + + Assert.Equal(0, Vector3.IndexOfWhereAllBitsSet(input1)); + Assert.Equal(-1, Vector3.IndexOfWhereAllBitsSet(input2)); + Assert.Equal(1, Vector3.IndexOfWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.Equal(0, Vector3.IndexOfWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + + Assert.Equal(ElementCount - 1, Vector3.LastIndexOfWhereAllBitsSet(input1)); + Assert.Equal(-1, Vector3.LastIndexOfWhereAllBitsSet(input2)); + Assert.Equal(ElementCount - 1, Vector3.LastIndexOfWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.Equal(0, Vector3.LastIndexOfWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + } + } + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerTest(float value) => Assert.Equal(float.IsEvenInteger(value) ? Vector3.AllBitsSet : Vector3.Zero, Vector3.IsEvenInteger(Vector3.Create(value))); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteTest(float value) => Assert.Equal(float.IsFinite(value) ? Vector3.AllBitsSet : Vector3.Zero, Vector3.IsFinite(Vector3.Create(value))); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityTest(float value) => Assert.Equal(float.IsInfinity(value) ? Vector3.AllBitsSet : Vector3.Zero, Vector3.IsInfinity(Vector3.Create(value))); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerTest(float value) => Assert.Equal(float.IsInteger(value) ? Vector3.AllBitsSet : Vector3.Zero, Vector3.IsInteger(Vector3.Create(value))); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNTest(float value) => Assert.Equal(float.IsNaN(value) ? Vector3.AllBitsSet : Vector3.Zero, Vector3.IsNaN(Vector3.Create(value))); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeTest(float value) => Assert.Equal(float.IsNegative(value) ? Vector3.AllBitsSet : Vector3.Zero, Vector3.IsNegative(Vector3.Create(value))); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityTest(float value) => Assert.Equal(float.IsNegativeInfinity(value) ? Vector3.AllBitsSet : Vector3.Zero, Vector3.IsNegativeInfinity(Vector3.Create(value))); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalTest(float value) => Assert.Equal(float.IsNormal(value) ? Vector3.AllBitsSet : Vector3.Zero, Vector3.IsNormal(Vector3.Create(value))); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerTest(float value) => Assert.Equal(float.IsOddInteger(value) ? Vector3.AllBitsSet : Vector3.Zero, Vector3.IsOddInteger(Vector3.Create(value))); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveTest(float value) => Assert.Equal(float.IsPositive(value) ? Vector3.AllBitsSet : Vector3.Zero, Vector3.IsPositive(Vector3.Create(value))); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityTest(float value) => Assert.Equal(float.IsPositiveInfinity(value) ? Vector3.AllBitsSet : Vector3.Zero, Vector3.IsPositiveInfinity(Vector3.Create(value))); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalTest(float value) => Assert.Equal(float.IsSubnormal(value) ? Vector3.AllBitsSet : Vector3.Zero, Vector3.IsSubnormal(Vector3.Create(value))); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroSingleTest(float value) => Assert.Equal((value == 0) ? Vector3.AllBitsSet : Vector3.Zero, Vector3.IsZero(Vector3.Create(value))); + + [Fact] + public void AllBitsSetTest() + { + Assert.Equal(-1, BitConverter.SingleToInt32Bits(Vector3.AllBitsSet.X)); + Assert.Equal(-1, BitConverter.SingleToInt32Bits(Vector3.AllBitsSet.Y)); + Assert.Equal(-1, BitConverter.SingleToInt32Bits(Vector3.AllBitsSet.Z)); + } + + [Fact] + public void ConditionalSelectTest() + { + Test(Vector3.Create(1, 2, 3), Vector3.AllBitsSet, Vector3.Create(1, 2, 3), Vector3.Create(5, 6, 7)); + Test(Vector3.Create(5, 6, 7), Vector3.Zero, Vector3.Create(1, 2, 3), Vector3.Create(5, 6, 7)); + Test(Vector3.Create(1, 6, 3), Vector128.Create(-1, 0, -1, 0).AsSingle().AsVector3(), Vector3.Create(1, 2, 3), Vector3.Create(5, 6, 7)); + + [MethodImpl(MethodImplOptions.NoInlining)] + void Test(Vector3 expectedResult, Vector3 condition, Vector3 left, Vector3 right) + { + Assert.Equal(expectedResult, Vector3.ConditionalSelect(condition, left, right)); + } + } + + [Theory] + [InlineData(+0.0f, +0.0f, +0.0f, 0b000)] + [InlineData(-0.0f, +1.0f, -0.0f, 0b101)] + [InlineData(-0.0f, -0.0f, -0.0f, 0b111)] + public void ExtractMostSignificantBitsTest(float x, float y, float z, uint expectedResult) + { + Assert.Equal(expectedResult, Vector3.Create(x, y, z).ExtractMostSignificantBits()); + } + + [Theory] + [InlineData(1.0f, 2.0f, 3.0f)] + [InlineData(5.0f, 6.0f, 7.0f)] + public void GetElementTest(float x, float y, float z) + { + Assert.Equal(x, Vector3.Create(x, y, z).GetElement(0)); + Assert.Equal(y, Vector3.Create(x, y, z).GetElement(1)); + Assert.Equal(z, Vector3.Create(x, y, z).GetElement(2)); + } + + [Theory] + [InlineData(1.0f, 2.0f, 3.0f)] + [InlineData(5.0f, 6.0f, 7.0f)] + public void ShuffleTest(float x, float y, float z) + { + Assert.Equal(Vector3.Create(z, y, x), Vector3.Shuffle(Vector3.Create(x, y, z), 2, 1, 0)); + Assert.Equal(Vector3.Create(y, x, z), Vector3.Shuffle(Vector3.Create(x, y, z), 1, 0, 2)); + } + + [Theory] + [InlineData(1.0f, 2.0f, 3.0f, 6.0f)] + [InlineData(5.0f, 6.0f, 7.0f, 18.0f)] + public void SumTest(float x, float y, float z, float expectedResult) + { + Assert.Equal(expectedResult, Vector3.Sum(Vector3.Create(x, y, z))); + } + + [Theory] + [InlineData(1.0f, 2.0f, 3.0f)] + [InlineData(5.0f, 6.0f, 7.0f)] + public void ToScalarTest(float x, float y, float z) + { + Assert.Equal(x, Vector3.Create(x, y, z).ToScalar()); + } + + [Theory] + [InlineData(1.0f, 2.0f, 3.0f)] + [InlineData(5.0f, 6.0f, 7.0f)] + public void WithElementTest(float x, float y, float z) + { + var vector = Vector3.Create(10); + + Assert.Equal(10, vector.X); + Assert.Equal(10, vector.Y); + Assert.Equal(10, vector.Z); + + vector = vector.WithElement(0, x); + + Assert.Equal(x, vector.X); + Assert.Equal(10, vector.Y); + Assert.Equal(10, vector.Z); + + vector = vector.WithElement(1, y); + + Assert.Equal(x, vector.X); + Assert.Equal(y, vector.Y); + Assert.Equal(10, vector.Z); + + vector = vector.WithElement(2, z); + + Assert.Equal(x, vector.X); + Assert.Equal(y, vector.Y); + Assert.Equal(z, vector.Z); + } } } diff --git a/src/libraries/System.Numerics.Vectors/tests/Vector4Tests.cs b/src/libraries/System.Numerics.Vectors/tests/Vector4Tests.cs index 74ffeeba94c564..ee1f85c9ff2fe7 100644 --- a/src/libraries/System.Numerics.Vectors/tests/Vector4Tests.cs +++ b/src/libraries/System.Numerics.Vectors/tests/Vector4Tests.cs @@ -2,7 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Globalization; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; using System.Tests; using Xunit; @@ -10,6 +12,8 @@ namespace System.Numerics.Tests { public sealed class Vector4Tests { + private const int ElementCount = 4; + /// Verifies that two values are equal, within the . /// The expected value /// The value to be compared against @@ -1931,5 +1935,334 @@ public void TruncateSingleTest(float value, float expectedResult) Vector4 actualResult = Vector4.Truncate(Vector4.Create(value)); AssertEqual(Vector4.Create(expectedResult), actualResult, Vector4.Zero); } + + [Fact] + public void AllAnyNoneTest() + { + Test(3, 2); + + [MethodImpl(MethodImplOptions.NoInlining)] + void Test(float value1, float value2) + { + var input1 = Vector4.Create(value1); + var input2 = Vector4.Create(value2); + + Assert.True(Vector4.All(input1, value1)); + Assert.True(Vector4.All(input2, value2)); + Assert.False(Vector4.All(input1.WithElement(0, value2), value1)); + Assert.False(Vector4.All(input2.WithElement(0, value1), value2)); + Assert.False(Vector4.All(input1, value2)); + Assert.False(Vector4.All(input2, value1)); + Assert.False(Vector4.All(input1.WithElement(0, value2), value2)); + Assert.False(Vector4.All(input2.WithElement(0, value1), value1)); + + Assert.True(Vector4.Any(input1, value1)); + Assert.True(Vector4.Any(input2, value2)); + Assert.True(Vector4.Any(input1.WithElement(0, value2), value1)); + Assert.True(Vector4.Any(input2.WithElement(0, value1), value2)); + Assert.False(Vector4.Any(input1, value2)); + Assert.False(Vector4.Any(input2, value1)); + Assert.True(Vector4.Any(input1.WithElement(0, value2), value2)); + Assert.True(Vector4.Any(input2.WithElement(0, value1), value1)); + + Assert.False(Vector4.None(input1, value1)); + Assert.False(Vector4.None(input2, value2)); + Assert.False(Vector4.None(input1.WithElement(0, value2), value1)); + Assert.False(Vector4.None(input2.WithElement(0, value1), value2)); + Assert.True(Vector4.None(input1, value2)); + Assert.True(Vector4.None(input2, value1)); + Assert.False(Vector4.None(input1.WithElement(0, value2), value2)); + Assert.False(Vector4.None(input2.WithElement(0, value1), value1)); + } + } + + [Fact] + public void AllAnyNoneTest_AllBitsSet() + { + Test(BitConverter.Int32BitsToSingle(-1)); + + [MethodImpl(MethodImplOptions.NoInlining)] + void Test(float value) + { + var input = Vector4.Create(value); + + Assert.False(Vector4.All(input, value)); + Assert.False(Vector4.Any(input, value)); + Assert.True(Vector4.None(input, value)); + } + } + + [Fact] + public void AllAnyNoneWhereAllBitsSetTest() + { + Test(BitConverter.Int32BitsToSingle(-1), 2); + + [MethodImpl(MethodImplOptions.NoInlining)] + void Test(float allBitsSet, float value2) + { + var input1 = Vector4.Create(allBitsSet); + var input2 = Vector4.Create(value2); + + Assert.True(Vector4.AllWhereAllBitsSet(input1)); + Assert.False(Vector4.AllWhereAllBitsSet(input2)); + Assert.False(Vector4.AllWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.False(Vector4.AllWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + + Assert.True(Vector4.AnyWhereAllBitsSet(input1)); + Assert.False(Vector4.AnyWhereAllBitsSet(input2)); + Assert.True(Vector4.AnyWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.True(Vector4.AnyWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + + Assert.False(Vector4.NoneWhereAllBitsSet(input1)); + Assert.True(Vector4.NoneWhereAllBitsSet(input2)); + Assert.False(Vector4.NoneWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.False(Vector4.NoneWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + } + } + + [Fact] + public void CountIndexOfLastIndexOfSingleTest() + { + Test(3, 2); + + [MethodImpl(MethodImplOptions.NoInlining)] + void Test(float value1, float value2) + { + var input1 = Vector4.Create(value1); + var input2 = Vector4.Create(value2); + + Assert.Equal(ElementCount, Vector4.Count(input1, value1)); + Assert.Equal(ElementCount, Vector4.Count(input2, value2)); + Assert.Equal(ElementCount - 1, Vector4.Count(input1.WithElement(0, value2), value1)); + Assert.Equal(ElementCount - 1, Vector4.Count(input2.WithElement(0, value1), value2)); + Assert.Equal(0, Vector4.Count(input1, value2)); + Assert.Equal(0, Vector4.Count(input2, value1)); + Assert.Equal(1, Vector4.Count(input1.WithElement(0, value2), value2)); + Assert.Equal(1, Vector4.Count(input2.WithElement(0, value1), value1)); + + Assert.Equal(0, Vector4.IndexOf(input1, value1)); + Assert.Equal(0, Vector4.IndexOf(input2, value2)); + Assert.Equal(1, Vector4.IndexOf(input1.WithElement(0, value2), value1)); + Assert.Equal(1, Vector4.IndexOf(input2.WithElement(0, value1), value2)); + Assert.Equal(-1, Vector4.IndexOf(input1, value2)); + Assert.Equal(-1, Vector4.IndexOf(input2, value1)); + Assert.Equal(0, Vector4.IndexOf(input1.WithElement(0, value2), value2)); + Assert.Equal(0, Vector4.IndexOf(input2.WithElement(0, value1), value1)); + + Assert.Equal(ElementCount - 1, Vector4.LastIndexOf(input1, value1)); + Assert.Equal(ElementCount - 1, Vector4.LastIndexOf(input2, value2)); + Assert.Equal(ElementCount - 1, Vector4.LastIndexOf(input1.WithElement(0, value2), value1)); + Assert.Equal(ElementCount - 1, Vector4.LastIndexOf(input2.WithElement(0, value1), value2)); + Assert.Equal(-1, Vector4.LastIndexOf(input1, value2)); + Assert.Equal(-1, Vector4.LastIndexOf(input2, value1)); + Assert.Equal(0, Vector4.LastIndexOf(input1.WithElement(0, value2), value2)); + Assert.Equal(0, Vector4.LastIndexOf(input2.WithElement(0, value1), value1)); + } + } + + [Fact] + public void CountIndexOfLastIndexOfSingleTest_AllBitsSet() + { + Test(BitConverter.Int32BitsToSingle(-1)); + + [MethodImpl(MethodImplOptions.NoInlining)] + void Test(float value) + { + var input = Vector4.Create(value); + + Assert.Equal(0, Vector4.Count(input, value)); + Assert.Equal(-1, Vector4.IndexOf(input, value)); + Assert.Equal(-1, Vector4.LastIndexOf(input, value)); + } + } + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetSingleTest() + { + Test(BitConverter.Int32BitsToSingle(-1), 2); + + [MethodImpl(MethodImplOptions.NoInlining)] + void Test(float allBitsSet, float value2) + { + var input1 = Vector4.Create(allBitsSet); + var input2 = Vector4.Create(value2); + + Assert.Equal(ElementCount, Vector4.CountWhereAllBitsSet(input1)); + Assert.Equal(0, Vector4.CountWhereAllBitsSet(input2)); + Assert.Equal(ElementCount - 1, Vector4.CountWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.Equal(1, Vector4.CountWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + + Assert.Equal(0, Vector4.IndexOfWhereAllBitsSet(input1)); + Assert.Equal(-1, Vector4.IndexOfWhereAllBitsSet(input2)); + Assert.Equal(1, Vector4.IndexOfWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.Equal(0, Vector4.IndexOfWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + + Assert.Equal(ElementCount - 1, Vector4.LastIndexOfWhereAllBitsSet(input1)); + Assert.Equal(-1, Vector4.LastIndexOfWhereAllBitsSet(input2)); + Assert.Equal(ElementCount - 1, Vector4.LastIndexOfWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.Equal(0, Vector4.LastIndexOfWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + } + } + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerTest(float value) => Assert.Equal(float.IsEvenInteger(value) ? Vector4.AllBitsSet : Vector4.Zero, Vector4.IsEvenInteger(Vector4.Create(value))); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteTest(float value) => Assert.Equal(float.IsFinite(value) ? Vector4.AllBitsSet : Vector4.Zero, Vector4.IsFinite(Vector4.Create(value))); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityTest(float value) => Assert.Equal(float.IsInfinity(value) ? Vector4.AllBitsSet : Vector4.Zero, Vector4.IsInfinity(Vector4.Create(value))); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerTest(float value) => Assert.Equal(float.IsInteger(value) ? Vector4.AllBitsSet : Vector4.Zero, Vector4.IsInteger(Vector4.Create(value))); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNTest(float value) => Assert.Equal(float.IsNaN(value) ? Vector4.AllBitsSet : Vector4.Zero, Vector4.IsNaN(Vector4.Create(value))); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeTest(float value) => Assert.Equal(float.IsNegative(value) ? Vector4.AllBitsSet : Vector4.Zero, Vector4.IsNegative(Vector4.Create(value))); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityTest(float value) => Assert.Equal(float.IsNegativeInfinity(value) ? Vector4.AllBitsSet : Vector4.Zero, Vector4.IsNegativeInfinity(Vector4.Create(value))); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalTest(float value) => Assert.Equal(float.IsNormal(value) ? Vector4.AllBitsSet : Vector4.Zero, Vector4.IsNormal(Vector4.Create(value))); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerTest(float value) => Assert.Equal(float.IsOddInteger(value) ? Vector4.AllBitsSet : Vector4.Zero, Vector4.IsOddInteger(Vector4.Create(value))); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveTest(float value) => Assert.Equal(float.IsPositive(value) ? Vector4.AllBitsSet : Vector4.Zero, Vector4.IsPositive(Vector4.Create(value))); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityTest(float value) => Assert.Equal(float.IsPositiveInfinity(value) ? Vector4.AllBitsSet : Vector4.Zero, Vector4.IsPositiveInfinity(Vector4.Create(value))); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalTest(float value) => Assert.Equal(float.IsSubnormal(value) ? Vector4.AllBitsSet : Vector4.Zero, Vector4.IsSubnormal(Vector4.Create(value))); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroSingleTest(float value) => Assert.Equal((value == 0) ? Vector4.AllBitsSet : Vector4.Zero, Vector4.IsZero(Vector4.Create(value))); + + [Fact] + public void AllBitsSetTest() + { + Assert.Equal(-1, BitConverter.SingleToInt32Bits(Vector4.AllBitsSet.X)); + Assert.Equal(-1, BitConverter.SingleToInt32Bits(Vector4.AllBitsSet.Y)); + Assert.Equal(-1, BitConverter.SingleToInt32Bits(Vector4.AllBitsSet.Z)); + Assert.Equal(-1, BitConverter.SingleToInt32Bits(Vector4.AllBitsSet.W)); + } + + [Fact] + public void ConditionalSelectTest() + { + Test(Vector4.Create(1, 2, 3, 4), Vector4.AllBitsSet, Vector4.Create(1, 2, 3, 4), Vector4.Create(5, 6, 7, 8)); + Test(Vector4.Create(5, 6, 7, 8), Vector4.Zero, Vector4.Create(1, 2, 3, 4), Vector4.Create(5, 6, 7, 8)); + Test(Vector4.Create(1, 6, 3, 8), Vector128.Create(-1, 0, -1, 0).AsSingle().AsVector4(), Vector4.Create(1, 2, 3, 4), Vector4.Create(5, 6, 7, 8)); + + [MethodImpl(MethodImplOptions.NoInlining)] + void Test(Vector4 expectedResult, Vector4 condition, Vector4 left, Vector4 right) + { + Assert.Equal(expectedResult, Vector4.ConditionalSelect(condition, left, right)); + } + } + + [Theory] + [InlineData(+0.0f, +0.0f, +0.0f, +0.0f, 0b0000)] + [InlineData(-0.0f, +1.0f, -0.0f, +0.0f, 0b0101)] + [InlineData(-0.0f, -0.0f, -0.0f, -0.0f, 0b1111)] + public void ExtractMostSignificantBitsTest(float x, float y, float z, float w, uint expectedResult) + { + Assert.Equal(expectedResult, Vector4.Create(x, y, z, w).ExtractMostSignificantBits()); + } + + [Theory] + [InlineData(1.0f, 2.0f, 3.0f, 4.0f)] + [InlineData(5.0f, 6.0f, 7.0f, 8.0f)] + public void GetElementTest(float x, float y, float z, float w) + { + Assert.Equal(x, Vector4.Create(x, y, z, w).GetElement(0)); + Assert.Equal(y, Vector4.Create(x, y, z, w).GetElement(1)); + Assert.Equal(z, Vector4.Create(x, y, z, w).GetElement(2)); + Assert.Equal(w, Vector4.Create(x, y, z, w).GetElement(3)); + } + + [Theory] + [InlineData(1.0f, 2.0f, 3.0f, 4.0f)] + [InlineData(5.0f, 6.0f, 7.0f, 8.0f)] + public void ShuffleTest(float x, float y, float z, float w) + { + Assert.Equal(Vector4.Create(w, z, y, x), Vector4.Shuffle(Vector4.Create(x, y, z, w), 3, 2, 1, 0)); + Assert.Equal(Vector4.Create(y, x, w, z), Vector4.Shuffle(Vector4.Create(x, y, z, w), 1, 0, 3, 2)); + } + + [Theory] + [InlineData(1.0f, 2.0f, 3.0f, 4.0f, 10.0f)] + [InlineData(5.0f, 6.0f, 7.0f, 8.0f, 26.0f)] + public void SumTest(float x, float y, float z, float w, float expectedResult) + { + Assert.Equal(expectedResult, Vector4.Sum(Vector4.Create(x, y, z, w))); + } + + [Theory] + [InlineData(1.0f, 2.0f, 3.0f, 4.0f)] + [InlineData(5.0f, 6.0f, 7.0f, 8.0f)] + public void ToScalarTest(float x, float y, float z, float w) + { + Assert.Equal(x, Vector4.Create(x, y, z, w).ToScalar()); + } + + [Theory] + [InlineData(1.0f, 2.0f, 3.0f, 4.0f)] + [InlineData(5.0f, 6.0f, 7.0f, 8.0f)] + public void WithElementTest(float x, float y, float z, float w) + { + var vector = Vector4.Create(10); + + Assert.Equal(10, vector.X); + Assert.Equal(10, vector.Y); + Assert.Equal(10, vector.Z); + Assert.Equal(10, vector.W); + + vector = vector.WithElement(0, x); + + Assert.Equal(x, vector.X); + Assert.Equal(10, vector.Y); + Assert.Equal(10, vector.Z); + Assert.Equal(10, vector.W); + + vector = vector.WithElement(1, y); + + Assert.Equal(x, vector.X); + Assert.Equal(y, vector.Y); + Assert.Equal(10, vector.Z); + Assert.Equal(10, vector.W); + + vector = vector.WithElement(2, z); + + Assert.Equal(x, vector.X); + Assert.Equal(y, vector.Y); + Assert.Equal(z, vector.Z); + Assert.Equal(10, vector.W); + + vector = vector.WithElement(3, w); + + Assert.Equal(x, vector.X); + Assert.Equal(y, vector.Y); + Assert.Equal(z, vector.Z); + Assert.Equal(w, vector.W); + } } } diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index 2fdf95932689b8..61d304184b2865 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -1043,6 +1043,7 @@ + diff --git a/src/libraries/System.Private.CoreLib/src/System/Double.cs b/src/libraries/System.Private.CoreLib/src/System/Double.cs index 8d24c4024c3000..c4ed8ed65587ad 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Double.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Double.cs @@ -85,7 +85,7 @@ public readonly struct Double internal const ulong BiasedExponentMask = 0x7FF0_0000_0000_0000; internal const int BiasedExponentShift = 52; internal const int BiasedExponentLength = 11; - internal const ushort ShiftedExponentMask = (ushort)(BiasedExponentMask >> BiasedExponentShift); + internal const ushort ShiftedBiasedExponentMask = (ushort)(BiasedExponentMask >> BiasedExponentShift); internal const ulong TrailingSignificandMask = 0x000F_FFFF_FFFF_FFFF; @@ -154,7 +154,7 @@ internal ulong TrailingSignificand internal static ushort ExtractBiasedExponentFromBits(ulong bits) { - return (ushort)((bits >> BiasedExponentShift) & ShiftedExponentMask); + return (ushort)((bits >> BiasedExponentShift) & ShiftedBiasedExponentMask); } internal static ulong ExtractTrailingSignificandFromBits(ulong bits) @@ -177,8 +177,8 @@ public static bool IsFinite(double d) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsInfinity(double d) { - ulong bits = BitConverter.DoubleToUInt64Bits(d); - return (bits & ~SignMask) == PositiveInfinityBits; + ulong bits = BitConverter.DoubleToUInt64Bits(Abs(d)); + return bits == PositiveInfinityBits; } /// Determines whether the specified value is NaN. @@ -224,8 +224,8 @@ public static bool IsNegativeInfinity(double d) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsNormal(double d) { - ulong bits = BitConverter.DoubleToUInt64Bits(d); - return ((bits & ~SignMask) - SmallestNormalBits) < (PositiveInfinityBits - SmallestNormalBits); + ulong bits = BitConverter.DoubleToUInt64Bits(Abs(d)); + return (bits - SmallestNormalBits) < (PositiveInfinityBits - SmallestNormalBits); } /// Determines whether the specified value is positive infinity. @@ -242,8 +242,8 @@ public static bool IsPositiveInfinity(double d) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsSubnormal(double d) { - ulong bits = BitConverter.DoubleToUInt64Bits(d); - return ((bits & ~SignMask) - 1) < MaxTrailingSignificand; + ulong bits = BitConverter.DoubleToUInt64Bits(Abs(d)); + return (bits - 1) < MaxTrailingSignificand; } [NonVersionable] @@ -941,7 +941,24 @@ bool IFloatingPoint.TryWriteSignificandLittleEndian(Span destinati // /// - public static double Clamp(double value, double min, double max) => Math.Clamp(value, min, max); + public static double Clamp(double value, double min, double max) + { + if (min > max) + { + Math.ThrowMinMaxException(min, max); + } + return Min(Max(value, min), max); + } + + /// + public static double ClampNative(double value, double min, double max) + { + if (min > max) + { + Math.ThrowMinMaxException(min, max); + } + return MinNative(MaxNative(value, min), max); + } /// public static double CopySign(double value, double sign) => Math.CopySign(value, sign); @@ -950,6 +967,10 @@ bool IFloatingPoint.TryWriteSignificandLittleEndian(Span destinati [Intrinsic] public static double Max(double x, double y) => Math.Max(x, y); + /// + [Intrinsic] + public static double MaxNative(double x, double y) => (x > y) ? x : y; + /// [Intrinsic] public static double MaxNumber(double x, double y) @@ -977,6 +998,10 @@ public static double MaxNumber(double x, double y) [Intrinsic] public static double Min(double x, double y) => Math.Min(x, y); + /// + [Intrinsic] + public static double MinNative(double x, double y) => (x < y) ? x : y; + /// [Intrinsic] public static double MinNumber(double x, double y) @@ -1489,8 +1514,8 @@ public static double Hypot(double x, double y) ulong xBits = BitConverter.DoubleToUInt64Bits(ax); ulong yBits = BitConverter.DoubleToUInt64Bits(ay); - uint xExp = (uint)((xBits >> BiasedExponentShift) & ShiftedExponentMask); - uint yExp = (uint)((yBits >> BiasedExponentShift) & ShiftedExponentMask); + uint xExp = (uint)((xBits >> BiasedExponentShift) & ShiftedBiasedExponentMask); + uint yExp = (uint)((yBits >> BiasedExponentShift) & ShiftedBiasedExponentMask); int expDiff = (int)(xExp - yExp); double expFix = 1.0; diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/Ordinal.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/Ordinal.cs index 68bcde60f941da..b9ed56a9fb06a4 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/Ordinal.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/Ordinal.cs @@ -81,10 +81,10 @@ internal static int CompareStringIgnoreCaseNonAscii(ref char strA, int lengthA, private static bool EqualsIgnoreCase_Vector(ref char charA, ref char charB, int length) where TVector : struct, ISimdVector { - Debug.Assert(length >= TVector.Count); + Debug.Assert(length >= TVector.ElementCount); nuint lengthU = (nuint)length; - nuint lengthToExamine = lengthU - (nuint)TVector.Count; + nuint lengthToExamine = lengthU - (nuint)TVector.ElementCount; nuint i = 0; TVector vec1; TVector vec2; @@ -113,13 +113,13 @@ private static bool EqualsIgnoreCase_Vector(ref char charA, ref char ch return false; // first input isn't in [A-Za-z], and not exact match of lowered } } - i += (nuint)TVector.Count; + i += (nuint)TVector.ElementCount; } while (i <= lengthToExamine); // Handle trailing elements if (i != lengthU) { - i = lengthU - (nuint)TVector.Count; + i = lengthU - (nuint)TVector.ElementCount; vec1 = TVector.LoadUnsafe(ref Unsafe.As(ref charA), i); vec2 = TVector.LoadUnsafe(ref Unsafe.As(ref charB), i); diff --git a/src/libraries/System.Private.CoreLib/src/System/Half.cs b/src/libraries/System.Private.CoreLib/src/System/Half.cs index dab5e73a278876..80e3f9532248a4 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Half.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Half.cs @@ -1641,7 +1641,17 @@ public static int ILogB(Half x) // /// - public static Half Clamp(Half value, Half min, Half max) => (Half)Math.Clamp((float)value, (float)min, (float)max); + public static Half Clamp(Half value, Half min, Half max) => (Half)float.Clamp((float)value, (float)min, (float)max); + + /// + public static Half ClampNative(Half value, Half min, Half max) + { + if (min > max) + { + Math.ThrowMinMaxException(min, max); + } + return MinNative(MaxNative(value, min), max); + } /// public static Half CopySign(Half value, Half sign) @@ -1657,7 +1667,10 @@ public static Half CopySign(Half value, Half sign) } /// - public static Half Max(Half x, Half y) => (Half)MathF.Max((float)x, (float)y); + public static Half Max(Half x, Half y) => (Half)float.Max((float)x, (float)y); + + /// + public static Half MaxNative(Half x, Half y) => (x > y) ? x : y; /// public static Half MaxNumber(Half x, Half y) @@ -1682,7 +1695,10 @@ public static Half MaxNumber(Half x, Half y) } /// - public static Half Min(Half x, Half y) => (Half)MathF.Min((float)x, (float)y); + public static Half Min(Half x, Half y) => (Half)float.Min((float)x, (float)y); + + /// + public static Half MinNative(Half x, Half y) => (x < y) ? x : y; /// public static Half MinNumber(Half x, Half y) diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/INumber.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/INumber.cs index 59aa0a761efa7e..2e0eb00e22ee14 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/INumber.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/INumber.cs @@ -37,6 +37,27 @@ static virtual TSelf Clamp(TSelf value, TSelf min, TSelf max) return result; } + /// Clamps a value to an inclusive minimum and maximum value using platform-specific behavior for NaN and NegativeZero. + /// The value to clamp. + /// The inclusive minimum to which should clamp. + /// The inclusive maximum to which should clamp. + /// The result of clamping to the inclusive range of and . + /// is greater than . + static virtual TSelf ClampNative(TSelf value, TSelf min, TSelf max) + { + if (min > max) + { + Math.ThrowMinMaxException(min, max); + } + + TSelf result = value; + + result = TSelf.MaxNative(result, min); + result = TSelf.MinNative(result, max); + + return result; + } + /// Copies the sign of a value to the sign of another value. /// The value whose magnitude is used in the result. /// The value whose sign is used in the result. @@ -79,6 +100,15 @@ static virtual TSelf Max(TSelf x, TSelf y) return TSelf.IsNegative(y) ? x : y; } + /// Compares two values to compute which is greater using platform-specific behavior for NaN and NegativeZero. + /// The value to compare with . + /// The value to compare with . + /// if it is greater than ; otherwise, . + static virtual TSelf MaxNative(TSelf x, TSelf y) + { + return (x > y) ? x : y; + } + /// Compares two values to compute which is greater and returning the other value if an input is NaN. /// The value to compare with . /// The value to compare with . @@ -131,6 +161,15 @@ static virtual TSelf Min(TSelf x, TSelf y) return TSelf.IsNegative(x) ? x : y; } + /// Compares two values to compute which is lesser using platform-specific behavior for NaN and NegativeZero. + /// The value to compare with . + /// The value to compare with . + /// if it is lesser than ; otherwise, . + static virtual TSelf MinNative(TSelf x, TSelf y) + { + return (x < y) ? x : y; + } + /// Compares two values to compute which is lesser and returning the other value if an input is NaN. /// The value to compare with . /// The value to compare with . diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector.cs index 355c19d4cfe794..57a71792bc5f0f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector.cs @@ -62,6 +62,30 @@ public static Vector Abs(Vector value) [Intrinsic] public static Vector Add(Vector left, Vector right) => left + right; + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool All(Vector vector, T value) => vector == Create(value); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool AllWhereAllBitsSet(Vector vector) + { + if (typeof(T) == typeof(float)) + { + return All(vector.As(), -1); + } + else if (typeof(T) == typeof(double)) + { + return All(vector.As(), -1); + } + else + { + return All(vector, Scalar.AllBitsSet); + } + } + /// Computes the bitwise-and of a given vector and the ones complement of another vector. /// The vector to bitwise-and with . /// The vector to that is ones-complemented before being bitwise-and with . @@ -70,6 +94,30 @@ public static Vector Abs(Vector value) [Intrinsic] public static Vector AndNot(Vector left, Vector right) => left & ~right; + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool Any(Vector vector, T value) => EqualsAny(vector, Create(value)); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool AnyWhereAllBitsSet(Vector vector) + { + if (typeof(T) == typeof(float)) + { + return Any(vector.As(), -1); + } + else if (typeof(T) == typeof(double)) + { + return Any(vector.As(), -1); + } + else + { + return Any(vector, Scalar.AllBitsSet); + } + } + /// Reinterprets a as a new . /// The type of the input vector. /// The type of the vector should be reinterpreted as. @@ -279,7 +327,7 @@ public static Vector Ceiling(Vector value) return result; } - /// + /// [Intrinsic] public static Vector Clamp(Vector value, Vector min, Vector max) { @@ -287,7 +335,7 @@ public static Vector Clamp(Vector value, Vector min, Vector max) return Min(Max(value, min), max); } - /// + /// [Intrinsic] public static Vector ClampNative(Vector value, Vector min, Vector max) { @@ -328,14 +376,17 @@ public static Vector ClampNative(Vector value, Vector min, Vector [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector ConvertToDouble(Vector value) { - if (Avx2.IsSupported) + if (sizeof(Vector) == sizeof(Vector512)) + { + return Vector512.ConvertToDouble(value.AsVector512()).AsVector(); + } + else if (sizeof(Vector) == sizeof(Vector256)) { - Debug.Assert(Vector.Count == Vector256.Count); return Vector256.ConvertToDouble(value.AsVector256()).AsVector(); } else { - Debug.Assert(Vector.Count == Vector128.Count); + Debug.Assert(sizeof(Vector) == sizeof(Vector128)); return Vector128.ConvertToDouble(value.AsVector128()).AsVector(); } } @@ -348,14 +399,17 @@ public static Vector ConvertToDouble(Vector value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector ConvertToDouble(Vector value) { - if (Avx2.IsSupported) + if (sizeof(Vector) == sizeof(Vector512)) + { + return Vector512.ConvertToDouble(value.AsVector512()).AsVector(); + } + else if (sizeof(Vector) == sizeof(Vector256)) { - Debug.Assert(Vector.Count == Vector256.Count); return Vector256.ConvertToDouble(value.AsVector256()).AsVector(); } else { - Debug.Assert(Vector.Count == Vector128.Count); + Debug.Assert(sizeof(Vector) == sizeof(Vector128)); return Vector128.ConvertToDouble(value.AsVector128()).AsVector(); } } @@ -453,14 +507,17 @@ public static Vector ConvertToSingle(Vector value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector ConvertToSingle(Vector value) { - if (Avx2.IsSupported) + if (sizeof(Vector) == sizeof(Vector512)) + { + return Vector512.ConvertToSingle(value.AsVector512()).AsVector(); + } + else if (sizeof(Vector) == sizeof(Vector256)) { - Debug.Assert(Vector.Count == Vector256.Count); return Vector256.ConvertToSingle(value.AsVector256()).AsVector(); } else { - Debug.Assert(Vector.Count == Vector128.Count); + Debug.Assert(sizeof(Vector) == sizeof(Vector128)); return Vector128.ConvertToSingle(value.AsVector128()).AsVector(); } } @@ -579,7 +636,7 @@ public static Vector Cos(Vector vector) } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector CopySign(Vector value, Vector sign) @@ -610,6 +667,47 @@ public static Vector CopySign(Vector value, Vector sign) } } + + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Count(Vector vector, T value) + { + if (sizeof(Vector) == sizeof(Vector512)) + { + return Vector512.Count(vector.AsVector512(), value); + } + else if (sizeof(Vector) == sizeof(Vector256)) + { + return Vector256.Count(vector.AsVector256(), value); + } + else + { + Debug.Assert(sizeof(Vector) == sizeof(Vector128)); + return Vector128.Count(vector.AsVector128(), value); + } + } + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int CountWhereAllBitsSet(Vector vector) + { + if (typeof(T) == typeof(float)) + { + return Count(vector.As(), -1); + } + else if (typeof(T) == typeof(double)) + { + return Count(vector.As(), -1); + } + else + { + return Count(vector, Scalar.AllBitsSet); + } + } + /// Creates a new instance with all elements initialized to the specified value. /// The type of the elements in the vector. /// The value that all elements will be initialized to. @@ -1228,7 +1326,102 @@ public static Vector Hypot(Vector x, Vector y) } } - /// + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int IndexOf(Vector vector, T value) + { + if (sizeof(Vector) == sizeof(Vector512)) + { + return Vector512.IndexOf(vector.AsVector512(), value); + } + else if (sizeof(Vector) == sizeof(Vector256)) + { + return Vector256.IndexOf(vector.AsVector256(), value); + } + else + { + Debug.Assert(sizeof(Vector) == sizeof(Vector128)); + return Vector128.IndexOf(vector.AsVector128(), value); + } + } + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int IndexOfWhereAllBitsSet(Vector vector) + { + if (typeof(T) == typeof(float)) + { + return IndexOf(vector.As(), -1); + } + else if (typeof(T) == typeof(double)) + { + return IndexOf(vector.As(), -1); + } + else + { + return IndexOf(vector, Scalar.AllBitsSet); + } + } + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector IsEvenInteger(Vector vector) + { + if (typeof(T) == typeof(float)) + { + return VectorMath.IsEvenIntegerSingle, Vector>(vector.As()).As(); + } + else if (typeof(T) == typeof(double)) + { + return VectorMath.IsEvenIntegerDouble, Vector>(vector.As()).As(); + } + return IsZero(vector & Vector.One); + } + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector IsFinite(Vector vector) + { + if (typeof(T) == typeof(float)) + { + return ~IsZero(AndNot(Create(float.PositiveInfinityBits), vector.As())).As(); + } + else if (typeof(T) == typeof(double)) + { + return ~IsZero(AndNot(Create(double.PositiveInfinityBits), vector.As())).As(); + } + return Vector.AllBitsSet; + } + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector IsInfinity(Vector vector) + { + if ((typeof(T) == typeof(float)) || (typeof(T) == typeof(double))) + { + return IsPositiveInfinity(Abs(vector)); + } + return Vector.Zero; + } + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector IsInteger(Vector vector) + { + if ((typeof(T) == typeof(float)) || (typeof(T) == typeof(double))) + { + return IsFinite(vector) & Equals(vector, Truncate(vector)); + } + return Vector.AllBitsSet; + } + + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector IsNaN(Vector vector) @@ -1240,7 +1433,7 @@ public static Vector IsNaN(Vector vector) return Vector.Zero; } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector IsNegative(Vector vector) @@ -1267,7 +1460,55 @@ public static Vector IsNegative(Vector vector) } } - /// + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector IsNegativeInfinity(Vector vector) + { + if (typeof(T) == typeof(float)) + { + return Equals(vector, Create(float.NegativeInfinity).As()); + } + else if (typeof(T) == typeof(double)) + { + return Equals(vector, Create(double.NegativeInfinity).As()); + } + return Vector.Zero; + } + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector IsNormal(Vector vector) + { + if (typeof(T) == typeof(float)) + { + return LessThan(Abs(vector).As() - Create(float.SmallestNormalBits), Create(float.PositiveInfinityBits - float.SmallestNormalBits)).As(); + } + else if (typeof(T) == typeof(double)) + { + return LessThan(Abs(vector).As() - Create(double.SmallestNormalBits), Create(double.PositiveInfinityBits - double.SmallestNormalBits)).As(); + } + return ~IsZero(vector); + } + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector IsOddInteger(Vector vector) + { + if (typeof(T) == typeof(float)) + { + return VectorMath.IsOddIntegerSingle, Vector>(vector.As()).As(); + } + else if (typeof(T) == typeof(double)) + { + return VectorMath.IsOddIntegerDouble, Vector>(vector.As()).As(); + } + return ~IsZero(vector & Vector.One); + } + + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector IsPositive(Vector vector) @@ -1294,7 +1535,7 @@ public static Vector IsPositive(Vector vector) } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector IsPositiveInfinity(Vector vector) @@ -1310,11 +1551,66 @@ public static Vector IsPositiveInfinity(Vector vector) return Vector.Zero; } - /// + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector IsSubnormal(Vector vector) + { + if (typeof(T) == typeof(float)) + { + return LessThan(Abs(vector).As() - Vector.One, Create(float.MaxTrailingSignificand)).As(); + } + else if (typeof(T) == typeof(double)) + { + return LessThan(Abs(vector).As() - Vector.One, Create(double.MaxTrailingSignificand)).As(); + } + return Vector.Zero; + } + + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector IsZero(Vector vector) => Equals(vector, Vector.Zero); + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int LastIndexOf(Vector vector, T value) + { + if (sizeof(Vector) == sizeof(Vector512)) + { + return Vector512.LastIndexOf(vector.AsVector512(), value); + } + else if (sizeof(Vector) == sizeof(Vector256)) + { + return Vector256.LastIndexOf(vector.AsVector256(), value); + } + else + { + Debug.Assert(sizeof(Vector) == sizeof(Vector128)); + return Vector128.LastIndexOf(vector.AsVector128(), value); + } + } + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int LastIndexOfWhereAllBitsSet(Vector vector) + { + if (typeof(T) == typeof(float)) + { + return LastIndexOf(vector.As(), -1); + } + else if (typeof(T) == typeof(double)) + { + return LastIndexOf(vector.As(), -1); + } + else + { + return LastIndexOf(vector, Scalar.AllBitsSet); + } + } + internal static Vector Lerp(Vector x, Vector y, Vector amount) where T : IFloatingPointIeee754 { @@ -1696,7 +1992,7 @@ public static Vector Log2(Vector vector) } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector Max(Vector left, Vector right) @@ -1719,7 +2015,7 @@ public static Vector Max(Vector left, Vector right) } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector MaxMagnitude(Vector left, Vector right) @@ -1742,7 +2038,7 @@ public static Vector MaxMagnitude(Vector left, Vector right) } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector MaxMagnitudeNumber(Vector left, Vector right) @@ -1765,7 +2061,7 @@ public static Vector MaxMagnitudeNumber(Vector left, Vector right) } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector MaxNative(Vector left, Vector right) @@ -1788,7 +2084,7 @@ public static Vector MaxNative(Vector left, Vector right) } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector MaxNumber(Vector left, Vector right) @@ -1811,7 +2107,7 @@ public static Vector MaxNumber(Vector left, Vector right) } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector Min(Vector left, Vector right) @@ -1834,7 +2130,7 @@ public static Vector Min(Vector left, Vector right) } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector MinMagnitude(Vector left, Vector right) @@ -1857,7 +2153,7 @@ public static Vector MinMagnitude(Vector left, Vector right) } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector MinMagnitudeNumber(Vector left, Vector right) @@ -1880,7 +2176,7 @@ public static Vector MinMagnitudeNumber(Vector left, Vector right) } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector MinNative(Vector left, Vector right) @@ -1903,7 +2199,7 @@ public static Vector MinNative(Vector left, Vector right) } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector MinNumber(Vector left, Vector right) @@ -2183,6 +2479,30 @@ public static Vector Narrow(Vector low, Vector high) [Intrinsic] public static Vector Negate(Vector value) => -value; + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool None(Vector vector, T value) => !EqualsAny(vector, Create(value)); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool NoneWhereAllBitsSet(Vector vector) + { + if (typeof(T) == typeof(float)) + { + return None(vector.As(), -1); + } + else if (typeof(T) == typeof(double)) + { + return None(vector.As(), -1); + } + else + { + return None(vector, Scalar.AllBitsSet); + } + } + /// Computes the ones-complement of a vector. /// The vector whose ones-complement is to be computed. /// The type of the elements in the vector. @@ -2346,6 +2666,24 @@ internal static Vector Round(Vector vector) [CLSCompliant(false)] public static Vector ShiftLeft(Vector value, int shiftCount) => value << shiftCount; + [Intrinsic] + internal static Vector ShiftLeft(Vector vector, Vector shiftCount) + { + if (sizeof(Vector) == sizeof(Vector512)) + { + return Vector512.ShiftLeft(vector.AsVector512(), shiftCount.AsVector512()).AsVector(); + } + else if (sizeof(Vector) == sizeof(Vector256)) + { + return Vector256.ShiftLeft(vector.AsVector256(), shiftCount.AsVector256()).AsVector(); + } + else + { + Debug.Assert(sizeof(Vector) == sizeof(Vector128)); + return Vector128.ShiftLeft(vector.AsVector128(), shiftCount.AsVector128()).AsVector(); + } + } + /// Shifts each element of a vector left by the specified amount. /// The vector whose elements are to be shifted. /// The number of bits by which to shift each element. @@ -2354,6 +2692,24 @@ internal static Vector Round(Vector vector) [CLSCompliant(false)] public static Vector ShiftLeft(Vector value, int shiftCount) => value << shiftCount; + [Intrinsic] + internal static Vector ShiftLeft(Vector vector, Vector shiftCount) + { + if (sizeof(Vector) == sizeof(Vector512)) + { + return Vector512.ShiftLeft(vector.AsVector512(), shiftCount.AsVector512()).AsVector(); + } + else if (sizeof(Vector) == sizeof(Vector256)) + { + return Vector256.ShiftLeft(vector.AsVector256(), shiftCount.AsVector256()).AsVector(); + } + else + { + Debug.Assert(sizeof(Vector) == sizeof(Vector128)); + return Vector128.ShiftLeft(vector.AsVector128(), shiftCount.AsVector128()).AsVector(); + } + } + /// Shifts (signed) each element of a vector right by the specified amount. /// The vector whose elements are to be shifted. /// The number of bits by which to shift each element. diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector2.Extensions.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector2.Extensions.cs index 21e3defd777a4e..3c38c3852bdd9c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector2.Extensions.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector2.Extensions.cs @@ -12,13 +12,94 @@ public static unsafe partial class Vector /// Reinterprets a to a new with the new elements zeroed. /// The vector to reinterpret. /// reinterpreted to a new with the new elements zeroed. - [Intrinsic] public static Vector4 AsVector4(this Vector2 value) => value.AsVector128().AsVector4(); /// Reinterprets a to a new with the new elements undefined. /// The vector to reinterpret. /// reinterpreted to a new with the new elements undefined. - [Intrinsic] public static Vector4 AsVector4Unsafe(this Vector2 value) => value.AsVector128Unsafe().AsVector4(); + + /// + [CLSCompliant(false)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint ExtractMostSignificantBits(this Vector2 vector) => vector.AsVector128().ExtractMostSignificantBits(); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float GetElement(this Vector2 vector, int index) + { + if ((uint)index >= Vector2.ElementCount) + { + ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index); + } + return vector.AsVector128Unsafe().GetElement(index); + } + + /// Stores a vector at the given destination. + /// The vector that will be stored. + /// The destination at which will be stored. + [CLSCompliant(false)] + public static void Store(this Vector2 source, float* destination) => source.StoreUnsafe(ref *destination); + + /// Stores a vector at the given 8-byte aligned destination. + /// The vector that will be stored. + /// The aligned destination at which will be stored. + /// is not 8-byte aligned. + [CLSCompliant(false)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void StoreAligned(this Vector2 source, float* destination) + { + if (((nuint)destination % (uint)(Vector2.Alignment)) != 0) + { + ThrowHelper.ThrowAccessViolationException(); + } + + *(Vector2*)destination = source; + } + + /// Stores a vector at the given 8-byte aligned destination. + /// The vector that will be stored. + /// The aligned destination at which will be stored. + /// is not 8-byte aligned. + /// This method may bypass the cache on certain platforms. + [CLSCompliant(false)] + public static void StoreAlignedNonTemporal(this Vector2 source, float* destination) => source.StoreAligned(destination); + + /// Stores a vector at the given destination. + /// The vector that will be stored. + /// The destination at which will be stored. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void StoreUnsafe(this Vector2 source, ref float destination) + { + ref byte address = ref Unsafe.As(ref destination); + Unsafe.WriteUnaligned(ref address, source); + } + + /// Stores a vector at the given destination. + /// The vector that will be stored. + /// The destination to which will be added before the vector will be stored. + /// The element offset from from which the vector will be stored. + [CLSCompliant(false)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void StoreUnsafe(this Vector2 source, ref float destination, nuint elementOffset) + { + destination = ref Unsafe.Add(ref destination, (nint)elementOffset); + Unsafe.WriteUnaligned(ref Unsafe.As(ref destination), source); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float ToScalar(this Vector2 vector) => vector.AsVector128Unsafe().ToScalar(); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 WithElement(this Vector2 vector, int index, float value) + { + if ((uint)index >= Vector2.ElementCount) + { + ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index); + } + return vector.AsVector128Unsafe().WithElement(index, value).AsVector2(); + } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector2.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector2.cs index 5619dcfede46b0..351986ea4ac578 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector2.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector2.cs @@ -17,13 +17,31 @@ namespace System.Numerics [Intrinsic] public partial struct Vector2 : IEquatable, IFormattable { + /// Specifies the alignment of the vector as used by the and APIs. + /// + /// + /// Different environments all have their own concepts of alignment/packing. + /// For example, a Vector3 in .NET is 4-byte aligned and 12-bytes in size, + /// in GLSL a vec3 is 16-byte aligned and 16-byte sized, while in HLSL a + /// float3 is functionally 8-byte aligned and 12-byte sized. These differences + /// make it impossible to define a "correct" alignment; additionally, the nuance + /// in environments like HLSL where size is not a multiple of alignment introduce complications. + /// + /// + /// For the purposes of the LoadAligned and StoreAligned APIs we + /// therefore pick a value that allows for a broad range of compatibility while + /// also allowing more optimal codegen for various target platforms. + /// + /// + internal const int Alignment = 8; + /// The X component of the vector. public float X; /// The Y component of the vector. public float Y; - internal const int Count = 2; + internal const int ElementCount = 2; /// Creates a new object whose two elements have the same value. /// The value to assign to both elements. @@ -50,6 +68,13 @@ public Vector2(ReadOnlySpan values) this = Create(values); } + /// + public static Vector2 AllBitsSet + { + [Intrinsic] + get => Vector128.AllBitsSet.AsVector2(); + } + /// public static Vector2 E { @@ -143,25 +168,12 @@ public static Vector2 Zero public float this[int index] { [Intrinsic] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - readonly get - { - if ((uint)index >= Count) - { - ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index); - } - return this.AsVector128Unsafe().GetElement(index); - } + readonly get => this.GetElement(index); [Intrinsic] - [MethodImpl(MethodImplOptions.AggressiveInlining)] set { - if ((uint)index >= Count) - { - ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index); - } - this = this.AsVector128Unsafe().WithElement(index, value).AsVector2(); + this = this.WithElement(index, value); } } @@ -251,6 +263,46 @@ readonly get [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 operator -(Vector2 value) => (-value.AsVector128Unsafe()).AsVector2(); + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 operator &(Vector2 left, Vector2 right) => (left.AsVector128Unsafe() & right.AsVector128Unsafe()).AsVector2(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 operator |(Vector2 left, Vector2 right) => (left.AsVector128Unsafe() | right.AsVector128Unsafe()).AsVector2(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 operator ^(Vector2 left, Vector2 right) => (left.AsVector128Unsafe() ^ right.AsVector128Unsafe()).AsVector2(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 operator <<(Vector2 value, int shiftAmount) => (value.AsVector128Unsafe() << shiftAmount).AsVector2(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 operator ~(Vector2 value) => (~value.AsVector128Unsafe()).AsVector2(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 operator >>(Vector2 value, int shiftAmount) => (value.AsVector128Unsafe() >> shiftAmount).AsVector2(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 operator +(Vector2 value) => value; + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 operator >>>(Vector2 value, int shiftAmount) => (value.AsVector128Unsafe() >>> shiftAmount).AsVector2(); + /// Returns a vector whose elements are the absolute values of each of the specified vector's elements. /// A vector. /// The absolute value vector. @@ -265,17 +317,55 @@ readonly get [Intrinsic] public static Vector2 Add(Vector2 left, Vector2 right) => left + right; - /// + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool All(Vector2 vector, float value) => Vector128.All(vector, value); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool AllWhereAllBitsSet(Vector2 vector) => Vector128.AllWhereAllBitsSet(vector); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 AndNot(Vector2 left, Vector2 right) => Vector128.AndNot(left.AsVector128Unsafe(), right.AsVector128Unsafe()).AsVector2(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool Any(Vector2 vector, float value) => Vector128.Any(vector, value); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool AnyWhereAllBitsSet(Vector2 vector) => Vector128.AnyWhereAllBitsSet(vector); + + /// + [Intrinsic] + public static Vector2 BitwiseAnd(Vector2 left, Vector2 right) => left & right; + + /// + [Intrinsic] + public static Vector2 BitwiseOr(Vector2 left, Vector2 right) => left | right; + + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Clamp(Vector2 value1, Vector2 min, Vector2 max) => Vector128.Clamp(value1.AsVector128Unsafe(), min.AsVector128Unsafe(), max.AsVector128Unsafe()).AsVector2(); - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 ClampNative(Vector2 value1, Vector2 min, Vector2 max) => Vector128.ClampNative(value1.AsVector128Unsafe(), min.AsVector128Unsafe(), max.AsVector128Unsafe()).AsVector2(); - /// + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 ConditionalSelect(Vector2 condition, Vector2 left, Vector2 right) => Vector128.ConditionalSelect(condition.AsVector128Unsafe(), left.AsVector128Unsafe(), right.AsVector128Unsafe()).AsVector2(); + + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 CopySign(Vector2 value, Vector2 sign) => Vector128.CopySign(value.AsVector128Unsafe(), sign.AsVector128Unsafe()).AsVector2(); @@ -284,6 +374,16 @@ readonly get [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Cos(Vector2 vector) => Vector128.Cos(vector.AsVector128()).AsVector2(); + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Count(Vector2 vector, float value) => Vector128.Count(vector, value); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int CountWhereAllBitsSet(Vector2 vector) => Vector128.CountWhereAllBitsSet(vector); + /// Creates a new object whose two elements have the same value. /// The value to assign to all two elements. /// A new whose two elements have the same value. @@ -304,7 +404,7 @@ readonly get [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Create(ReadOnlySpan values) { - if (values.Length < Count) + if (values.Length < ElementCount) { ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.values); } @@ -368,16 +468,146 @@ public static Vector2 Create(ReadOnlySpan values) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Exp(Vector2 vector) => Vector128.Exp(vector.AsVector128()).AsVector2(); + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 Equals(Vector2 left, Vector2 right) => Vector128.Equals(left.AsVector128Unsafe(), right.AsVector128Unsafe()).AsVector2(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool EqualsAll(Vector2 left, Vector2 right) => Vector128.EqualsAll(left.AsVector128Unsafe(), right.AsVector128Unsafe()); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool EqualsAny(Vector2 left, Vector2 right) => Vector128.EqualsAny(left.AsVector128Unsafe(), right.AsVector128Unsafe()); + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 FusedMultiplyAdd(Vector2 left, Vector2 right, Vector2 addend) => Vector128.FusedMultiplyAdd(left.AsVector128Unsafe(), right.AsVector128Unsafe(), addend.AsVector128Unsafe()).AsVector2(); + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 GreaterThan(Vector2 left, Vector2 right) => Vector128.GreaterThan(left.AsVector128Unsafe(), right.AsVector128Unsafe()).AsVector2(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool GreaterThanAll(Vector2 left, Vector2 right) => Vector128.GreaterThanAll(left.AsVector128Unsafe(), right.AsVector128Unsafe()); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool GreaterThanAny(Vector2 left, Vector2 right) => Vector128.GreaterThanAny(left.AsVector128Unsafe(), right.AsVector128Unsafe()); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 GreaterThanOrEqual(Vector2 left, Vector2 right) => Vector128.GreaterThanOrEqual(left.AsVector128Unsafe(), right.AsVector128Unsafe()).AsVector2(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool GreaterThanOrEqualAll(Vector2 left, Vector2 right) => Vector128.GreaterThanOrEqualAll(left.AsVector128Unsafe(), right.AsVector128Unsafe()); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool GreaterThanOrEqualAny(Vector2 left, Vector2 right) => Vector128.GreaterThanOrEqualAny(left.AsVector128Unsafe(), right.AsVector128Unsafe()); + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Hypot(Vector2 x, Vector2 y) => Vector128.Hypot(x.AsVector128Unsafe(), y.AsVector128Unsafe()).AsVector2(); + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int IndexOf(Vector2 vector, float value) => Vector128.IndexOf(vector, value); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int IndexOfWhereAllBitsSet(Vector2 vector) => Vector128.IndexOfWhereAllBitsSet(vector); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 IsEvenInteger(Vector2 vector) => Vector128.IsEvenInteger(vector.AsVector128()).AsVector2(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 IsFinite(Vector2 vector) => Vector128.IsFinite(vector.AsVector128()).AsVector2(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 IsInfinity(Vector2 vector) => Vector128.IsInfinity(vector.AsVector128()).AsVector2(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 IsInteger(Vector2 vector) => Vector128.IsInteger(vector.AsVector128()).AsVector2(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 IsNaN(Vector2 vector) => Vector128.IsNaN(vector.AsVector128()).AsVector2(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 IsNegative(Vector2 vector) => Vector128.IsNegative(vector.AsVector128()).AsVector2(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 IsNegativeInfinity(Vector2 vector) => Vector128.IsNegativeInfinity(vector.AsVector128()).AsVector2(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 IsNormal(Vector2 vector) => Vector128.IsNormal(vector.AsVector128()).AsVector2(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 IsOddInteger(Vector2 vector) => Vector128.IsOddInteger(vector.AsVector128()).AsVector2(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 IsPositive(Vector2 vector) => Vector128.IsPositive(vector.AsVector128()).AsVector2(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 IsPositiveInfinity(Vector2 vector) => Vector128.IsPositiveInfinity(vector.AsVector128()).AsVector2(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 IsSubnormal(Vector2 vector) => Vector128.IsSubnormal(vector.AsVector128()).AsVector2(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 IsZero(Vector2 vector) => Vector128.IsZero(vector.AsVector128()).AsVector2(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int LastIndexOf(Vector2 vector, float value) => Vector128.LastIndexOf(vector, value); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int LastIndexOfWhereAllBitsSet(Vector2 vector) => Vector128.LastIndexOfWhereAllBitsSet(vector); + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -388,6 +618,79 @@ public static Vector2 Create(ReadOnlySpan values) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Lerp(Vector2 value1, Vector2 value2, Vector2 amount) => Vector128.Lerp(value1.AsVector128Unsafe(), value2.AsVector128Unsafe(), amount.AsVector128Unsafe()).AsVector2(); + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 LessThan(Vector2 left, Vector2 right) => Vector128.LessThan(left.AsVector128Unsafe(), right.AsVector128Unsafe()).AsVector2(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool LessThanAll(Vector2 left, Vector2 right) => Vector128.LessThanAll(left.AsVector128Unsafe(), right.AsVector128Unsafe()); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool LessThanAny(Vector2 left, Vector2 right) => Vector128.LessThanAny(left.AsVector128Unsafe(), right.AsVector128Unsafe()); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 LessThanOrEqual(Vector2 left, Vector2 right) => Vector128.LessThanOrEqual(left.AsVector128Unsafe(), right.AsVector128Unsafe()).AsVector2(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool LessThanOrEqualAll(Vector2 left, Vector2 right) => Vector128.LessThanOrEqualAll(left.AsVector128Unsafe(), right.AsVector128Unsafe()); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool LessThanOrEqualAny(Vector2 left, Vector2 right) => Vector128.LessThanOrEqualAny(left.AsVector128Unsafe(), right.AsVector128Unsafe()); + + /// + [Intrinsic] + [CLSCompliant(false)] + public static unsafe Vector2 Load(float* source) => LoadUnsafe(in *source); + + /// + [Intrinsic] + [CLSCompliant(false)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe Vector2 LoadAligned(float* source) + { + if (((nuint)(source) % Alignment) != 0) + { + ThrowHelper.ThrowAccessViolationException(); + } + + return *(Vector2*)source; + } + + /// + [Intrinsic] + [CLSCompliant(false)] + public static unsafe Vector2 LoadAlignedNonTemporal(float* source) => LoadAligned(source); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 LoadUnsafe(ref readonly float source) + { + ref readonly byte address = ref Unsafe.As(ref Unsafe.AsRef(in source)); + return Unsafe.ReadUnaligned(in address); + } + + /// + [Intrinsic] + [CLSCompliant(false)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 LoadUnsafe(ref readonly float source, nuint elementOffset) + { + ref readonly byte address = ref Unsafe.As(ref Unsafe.Add(ref Unsafe.AsRef(in source), (nint)elementOffset)); + return Unsafe.ReadUnaligned(in address); + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Log(Vector2 vector) => Vector128.Log(Vector4.Create(vector, 1.0f, 1.0f).AsVector128()).AsVector2(); @@ -396,52 +699,52 @@ public static Vector2 Create(ReadOnlySpan values) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Log2(Vector2 vector) => Vector128.Log2(Vector4.Create(vector, 1.0f, 1.0f).AsVector128()).AsVector2(); - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Max(Vector2 value1, Vector2 value2) => Vector128.Max(value1.AsVector128Unsafe(), value2.AsVector128Unsafe()).AsVector2(); - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 MaxMagnitude(Vector2 value1, Vector2 value2) => Vector128.MaxMagnitude(value1.AsVector128Unsafe(), value2.AsVector128Unsafe()).AsVector2(); - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 MaxMagnitudeNumber(Vector2 value1, Vector2 value2) => Vector128.MaxMagnitudeNumber(value1.AsVector128Unsafe(), value2.AsVector128Unsafe()).AsVector2(); - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 MaxNative(Vector2 value1, Vector2 value2) => Vector128.MaxNative(value1.AsVector128Unsafe(), value2.AsVector128Unsafe()).AsVector2(); - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 MaxNumber(Vector2 value1, Vector2 value2) => Vector128.MaxNumber(value1.AsVector128Unsafe(), value2.AsVector128Unsafe()).AsVector2(); - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Min(Vector2 value1, Vector2 value2) => Vector128.Min(value1.AsVector128Unsafe(), value2.AsVector128Unsafe()).AsVector2(); - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 MinMagnitude(Vector2 value1, Vector2 value2) => Vector128.MinMagnitude(value1.AsVector128Unsafe(), value2.AsVector128Unsafe()).AsVector2(); - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 MinMagnitudeNumber(Vector2 value1, Vector2 value2) => Vector128.MinMagnitudeNumber(value1.AsVector128Unsafe(), value2.AsVector128Unsafe()).AsVector2(); - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 MinNative(Vector2 value1, Vector2 value2) => Vector128.MinNative(value1.AsVector128Unsafe(), value2.AsVector128Unsafe()).AsVector2(); - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 MinNumber(Vector2 value1, Vector2 value2) => Vector128.MinNumber(value1.AsVector128Unsafe(), value2.AsVector128Unsafe()).AsVector2(); @@ -478,12 +781,26 @@ public static Vector2 Create(ReadOnlySpan values) [Intrinsic] public static Vector2 Negate(Vector2 value) => -value; + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool None(Vector2 vector, float value) => Vector128.None(vector, value); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool NoneWhereAllBitsSet(Vector2 vector) => Vector128.NoneWhereAllBitsSet(vector); + /// Returns a vector with the same direction as the specified vector, but with a length of one. /// The vector to normalize. /// The normalized vector. [Intrinsic] public static Vector2 Normalize(Vector2 value) => value / value.Length(); + /// + [Intrinsic] + public static Vector2 OnesComplement(Vector2 value) => ~value; + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -512,6 +829,19 @@ public static Vector2 Reflect(Vector2 vector, Vector2 normal) [Intrinsic] public static Vector2 Round(Vector2 vector, MidpointRounding mode) => Vector128.Round(vector.AsVector128Unsafe(), mode).AsVector2(); + /// Creates a new vector by selecting values from an input vector using a set of indices. + /// The input vector from which values are selected. + /// The index used to select a value from to be used as the value of in the result. + /// The index used to select a value from to be used as the value of in the result + /// A new vector containing the values from selected by the given indices. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 Shuffle(Vector2 vector, byte xIndex, byte yIndex) + { + // We do `AsVector128` instead of `AsVector128Unsafe` so that indices which + // are out of range for Vector2 but in range for Vector128 still produce 0 + return Vector128.Shuffle(vector.AsVector128(), Vector128.Create(xIndex, yIndex, 2, 3)).AsVector2(); + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Sin(Vector2 vector) => Vector128.Sin(vector.AsVector128()).AsVector2(); @@ -538,6 +868,11 @@ public static (Vector2 Sin, Vector2 Cos) SinCos(Vector2 vector) [Intrinsic] public static Vector2 Subtract(Vector2 left, Vector2 right) => left - right; + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Sum(Vector2 value) => Vector128.Sum(value.AsVector128()); + /// Transforms a vector by a specified 3x2 matrix. /// The vector to transform. /// The transformation matrix. @@ -598,6 +933,10 @@ internal static Vector2 TransformNormal(Vector2 normal, in Matrix4x4.Impl matrix [Intrinsic] public static Vector2 Truncate(Vector2 vector) => Vector128.Truncate(vector.AsVector128Unsafe()).AsVector2(); + /// + [Intrinsic] + public static Vector2 Xor(Vector2 left, Vector2 right) => left ^ right; + /// Copies the elements of the vector to a specified array. /// The destination array. /// must have at least two elements. The method copies the vector's elements starting at index 0. @@ -609,7 +948,7 @@ public readonly void CopyTo(float[] array) { // We explicitly don't check for `null` because historically this has thrown `NullReferenceException` for perf reasons - if (array.Length < Count) + if (array.Length < ElementCount) { ThrowHelper.ThrowArgumentException_DestinationTooShort(); } @@ -637,7 +976,7 @@ public readonly void CopyTo(float[] array, int index) ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_IndexMustBeLess(); } - if ((array.Length - index) < Count) + if ((array.Length - index) < ElementCount) { ThrowHelper.ThrowArgumentException_DestinationTooShort(); } @@ -651,7 +990,7 @@ public readonly void CopyTo(float[] array, int index) [MethodImpl(MethodImplOptions.AggressiveInlining)] public readonly void CopyTo(Span destination) { - if (destination.Length < Count) + if (destination.Length < ElementCount) { ThrowHelper.ThrowArgumentException_DestinationTooShort(); } @@ -665,7 +1004,7 @@ public readonly void CopyTo(Span destination) [MethodImpl(MethodImplOptions.AggressiveInlining)] public readonly bool TryCopyTo(Span destination) { - if (destination.Length < Count) + if (destination.Length < ElementCount) { return false; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector3.Extensions.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector3.Extensions.cs index ba7457ba8310a8..b818143530be72 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector3.Extensions.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector3.Extensions.cs @@ -12,13 +12,94 @@ public static unsafe partial class Vector /// Converts a to a new with the new elements zeroed. /// The vector to convert. /// converted to a new with the new elements zeroed. - [Intrinsic] public static Vector4 AsVector4(this Vector3 value) => value.AsVector128().AsVector4(); /// Converts a to a new with the new elements undefined. /// The vector to convert. /// converted to a new with the new elements undefined. - [Intrinsic] public static Vector4 AsVector4Unsafe(this Vector3 value) => value.AsVector128Unsafe().AsVector4(); + + /// + [CLSCompliant(false)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint ExtractMostSignificantBits(this Vector3 vector) => vector.AsVector128().ExtractMostSignificantBits(); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float GetElement(this Vector3 vector, int index) + { + if ((uint)index >= Vector3.ElementCount) + { + ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index); + } + return vector.AsVector128Unsafe().GetElement(index); + } + + /// Stores a vector at the given destination. + /// The vector that will be stored. + /// The destination at which will be stored. + [CLSCompliant(false)] + public static void Store(this Vector3 source, float* destination) => source.StoreUnsafe(ref *destination); + + /// Stores a vector at the given 8-byte aligned destination. + /// The vector that will be stored. + /// The aligned destination at which will be stored. + /// is not 8-byte aligned. + [CLSCompliant(false)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void StoreAligned(this Vector3 source, float* destination) + { + if (((nuint)destination % (uint)(Vector3.Alignment)) != 0) + { + ThrowHelper.ThrowAccessViolationException(); + } + + *(Vector3*)destination = source; + } + + /// Stores a vector at the given 8-byte aligned destination. + /// The vector that will be stored. + /// The aligned destination at which will be stored. + /// is not 8-byte aligned. + /// This method may bypass the cache on certain platforms. + [CLSCompliant(false)] + public static void StoreAlignedNonTemporal(this Vector3 source, float* destination) => source.StoreAligned(destination); + + /// Stores a vector at the given destination. + /// The vector that will be stored. + /// The destination at which will be stored. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void StoreUnsafe(this Vector3 source, ref float destination) + { + ref byte address = ref Unsafe.As(ref destination); + Unsafe.WriteUnaligned(ref address, source); + } + + /// Stores a vector at the given destination. + /// The vector that will be stored. + /// The destination to which will be added before the vector will be stored. + /// The element offset from from which the vector will be stored. + [CLSCompliant(false)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void StoreUnsafe(this Vector3 source, ref float destination, nuint elementOffset) + { + destination = ref Unsafe.Add(ref destination, (nint)elementOffset); + Unsafe.WriteUnaligned(ref Unsafe.As(ref destination), source); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float ToScalar(this Vector3 vector) => vector.AsVector128Unsafe().ToScalar(); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 WithElement(this Vector3 vector, int index, float value) + { + if ((uint)index >= Vector3.ElementCount) + { + ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index); + } + return vector.AsVector128Unsafe().WithElement(index, value).AsVector3(); + } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector3.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector3.cs index 4641a86687271f..6091285eed3bb4 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector3.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector3.cs @@ -17,6 +17,24 @@ namespace System.Numerics [Intrinsic] public partial struct Vector3 : IEquatable, IFormattable { + /// Specifies the alignment of the vector as used by the and APIs. + /// + /// + /// Different environments all have their own concepts of alignment/packing. + /// For example, a Vector3 in .NET is 4-byte aligned and 12-bytes in size, + /// in GLSL a vec3 is 16-byte aligned and 16-byte sized, while in HLSL a + /// float3 is functionally 8-byte aligned and 12-byte sized. These differences + /// make it impossible to define a "correct" alignment; additionally, the nuance + /// in environments like HLSL where size is not a multiple of alignment introduce complications. + /// + /// + /// For the purposes of the LoadAligned and StoreAligned APIs we + /// therefore pick a value that allows for a broad range of compatibility while + /// also allowing more optimal codegen for various target platforms. + /// + /// + internal const int Alignment = 8; + /// The X component of the vector. public float X; @@ -26,7 +44,7 @@ public partial struct Vector3 : IEquatable, IFormattable /// The Z component of the vector. public float Z; - internal const int Count = 3; + internal const int ElementCount = 3; /// Creates a new object whose three elements have the same value. /// The value to assign to all three elements. @@ -63,6 +81,13 @@ public Vector3(ReadOnlySpan values) this = Create(values); } + /// + public static Vector3 AllBitsSet + { + [Intrinsic] + get => Vector128.AllBitsSet.AsVector3(); + } + /// public static Vector3 E { @@ -164,25 +189,12 @@ public static Vector3 Zero public float this[int index] { [Intrinsic] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - readonly get - { - if ((uint)index >= Count) - { - ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index); - } - return this.AsVector128Unsafe().GetElement(index); - } + readonly get => this.GetElement(index); [Intrinsic] - [MethodImpl(MethodImplOptions.AggressiveInlining)] set { - if ((uint)index >= Count) - { - ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index); - } - this = this.AsVector128Unsafe().WithElement(index, value).AsVector3(); + this = this.WithElement(index, value); } } @@ -272,6 +284,46 @@ readonly get [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 operator -(Vector3 value) => (-value.AsVector128Unsafe()).AsVector3(); + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 operator &(Vector3 left, Vector3 right) => (left.AsVector128Unsafe() & right.AsVector128Unsafe()).AsVector3(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 operator |(Vector3 left, Vector3 right) => (left.AsVector128Unsafe() | right.AsVector128Unsafe()).AsVector3(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 operator ^(Vector3 left, Vector3 right) => (left.AsVector128Unsafe() ^ right.AsVector128Unsafe()).AsVector3(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 operator <<(Vector3 value, int shiftAmount) => (value.AsVector128Unsafe() << shiftAmount).AsVector3(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 operator ~(Vector3 value) => (~value.AsVector128Unsafe()).AsVector3(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 operator >>(Vector3 value, int shiftAmount) => (value.AsVector128Unsafe() >> shiftAmount).AsVector3(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 operator +(Vector3 value) => value; + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 operator >>>(Vector3 value, int shiftAmount) => (value.AsVector128Unsafe() >>> shiftAmount).AsVector3(); + /// Returns a vector whose elements are the absolute values of each of the specified vector's elements. /// A vector. /// The absolute value vector. @@ -286,17 +338,55 @@ readonly get [Intrinsic] public static Vector3 Add(Vector3 left, Vector3 right) => left + right; - /// + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool All(Vector3 vector, float value) => Vector128.All(vector, value); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool AllWhereAllBitsSet(Vector3 vector) => Vector128.AllWhereAllBitsSet(vector); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 AndNot(Vector3 left, Vector3 right) => Vector128.AndNot(left.AsVector128Unsafe(), right.AsVector128Unsafe()).AsVector3(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool Any(Vector3 vector, float value) => Vector128.Any(vector, value); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool AnyWhereAllBitsSet(Vector3 vector) => Vector128.AnyWhereAllBitsSet(vector); + + /// + [Intrinsic] + public static Vector3 BitwiseAnd(Vector3 left, Vector3 right) => left & right; + + /// + [Intrinsic] + public static Vector3 BitwiseOr(Vector3 left, Vector3 right) => left | right; + + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Clamp(Vector3 value1, Vector3 min, Vector3 max) => Vector128.Clamp(value1.AsVector128Unsafe(), min.AsVector128Unsafe(), max.AsVector128Unsafe()).AsVector3(); - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 ClampNative(Vector3 value1, Vector3 min, Vector3 max) => Vector128.ClampNative(value1.AsVector128Unsafe(), min.AsVector128Unsafe(), max.AsVector128Unsafe()).AsVector3(); - /// + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 ConditionalSelect(Vector3 condition, Vector3 left, Vector3 right) => Vector128.ConditionalSelect(condition.AsVector128Unsafe(), left.AsVector128Unsafe(), right.AsVector128Unsafe()).AsVector3(); + + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 CopySign(Vector3 value, Vector3 sign) => Vector128.CopySign(value.AsVector128Unsafe(), sign.AsVector128Unsafe()).AsVector3(); @@ -305,6 +395,16 @@ readonly get [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Cos(Vector3 vector) => Vector128.Cos(vector.AsVector128()).AsVector3(); + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Count(Vector3 vector, float value) => Vector128.Count(vector, value); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int CountWhereAllBitsSet(Vector3 vector) => Vector128.CountWhereAllBitsSet(vector); + /// Creates a new object whose three elements have the same value. /// The value to assign to all three elements. /// A new whose three elements have the same value. @@ -339,7 +439,7 @@ public static Vector3 Create(Vector2 vector, float z) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Create(ReadOnlySpan values) { - if (values.Length < Count) + if (values.Length < ElementCount) { ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.values); } @@ -425,16 +525,146 @@ public static Vector3 Cross(Vector3 vector1, Vector3 vector2) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Exp(Vector3 vector) => Vector128.Exp(vector.AsVector128()).AsVector3(); + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 Equals(Vector3 left, Vector3 right) => Vector128.Equals(left.AsVector128Unsafe(), right.AsVector128Unsafe()).AsVector3(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool EqualsAll(Vector3 left, Vector3 right) => Vector128.EqualsAll(left.AsVector128Unsafe(), right.AsVector128Unsafe()); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool EqualsAny(Vector3 left, Vector3 right) => Vector128.EqualsAny(left.AsVector128Unsafe(), right.AsVector128Unsafe()); + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 FusedMultiplyAdd(Vector3 left, Vector3 right, Vector3 addend) => Vector128.FusedMultiplyAdd(left.AsVector128Unsafe(), right.AsVector128Unsafe(), addend.AsVector128Unsafe()).AsVector3(); + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 GreaterThan(Vector3 left, Vector3 right) => Vector128.GreaterThan(left.AsVector128Unsafe(), right.AsVector128Unsafe()).AsVector3(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool GreaterThanAll(Vector3 left, Vector3 right) => Vector128.GreaterThanAll(left.AsVector128Unsafe(), right.AsVector128Unsafe()); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool GreaterThanAny(Vector3 left, Vector3 right) => Vector128.GreaterThanAny(left.AsVector128Unsafe(), right.AsVector128Unsafe()); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 GreaterThanOrEqual(Vector3 left, Vector3 right) => Vector128.GreaterThanOrEqual(left.AsVector128Unsafe(), right.AsVector128Unsafe()).AsVector3(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool GreaterThanOrEqualAll(Vector3 left, Vector3 right) => Vector128.GreaterThanOrEqualAll(left.AsVector128Unsafe(), right.AsVector128Unsafe()); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool GreaterThanOrEqualAny(Vector3 left, Vector3 right) => Vector128.GreaterThanOrEqualAny(left.AsVector128Unsafe(), right.AsVector128Unsafe()); + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Hypot(Vector3 x, Vector3 y) => Vector128.Hypot(x.AsVector128Unsafe(), y.AsVector128Unsafe()).AsVector3(); + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int IndexOf(Vector3 vector, float value) => Vector128.IndexOf(vector, value); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int IndexOfWhereAllBitsSet(Vector3 vector) => Vector128.IndexOfWhereAllBitsSet(vector); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 IsEvenInteger(Vector3 vector) => Vector128.IsEvenInteger(vector.AsVector128()).AsVector3(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 IsFinite(Vector3 vector) => Vector128.IsFinite(vector.AsVector128()).AsVector3(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 IsInfinity(Vector3 vector) => Vector128.IsInfinity(vector.AsVector128()).AsVector3(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 IsInteger(Vector3 vector) => Vector128.IsInteger(vector.AsVector128()).AsVector3(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 IsNaN(Vector3 vector) => Vector128.IsNaN(vector.AsVector128()).AsVector3(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 IsNegative(Vector3 vector) => Vector128.IsNegative(vector.AsVector128()).AsVector3(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 IsNegativeInfinity(Vector3 vector) => Vector128.IsNegativeInfinity(vector.AsVector128()).AsVector3(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 IsNormal(Vector3 vector) => Vector128.IsNormal(vector.AsVector128()).AsVector3(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 IsOddInteger(Vector3 vector) => Vector128.IsOddInteger(vector.AsVector128()).AsVector3(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 IsPositive(Vector3 vector) => Vector128.IsPositive(vector.AsVector128()).AsVector3(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 IsPositiveInfinity(Vector3 vector) => Vector128.IsPositiveInfinity(vector.AsVector128()).AsVector3(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 IsSubnormal(Vector3 vector) => Vector128.IsSubnormal(vector.AsVector128()).AsVector3(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 IsZero(Vector3 vector) => Vector128.IsZero(vector.AsVector128()).AsVector3(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int LastIndexOf(Vector3 vector, float value) => Vector128.LastIndexOf(vector, value); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int LastIndexOfWhereAllBitsSet(Vector3 vector) => Vector128.LastIndexOfWhereAllBitsSet(vector); + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -445,6 +675,79 @@ public static Vector3 Cross(Vector3 vector1, Vector3 vector2) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Lerp(Vector3 value1, Vector3 value2, Vector3 amount) => Vector128.Lerp(value1.AsVector128Unsafe(), value2.AsVector128Unsafe(), amount.AsVector128Unsafe()).AsVector3(); + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 LessThan(Vector3 left, Vector3 right) => Vector128.LessThan(left.AsVector128Unsafe(), right.AsVector128Unsafe()).AsVector3(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool LessThanAll(Vector3 left, Vector3 right) => Vector128.LessThanAll(left.AsVector128Unsafe(), right.AsVector128Unsafe()); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool LessThanAny(Vector3 left, Vector3 right) => Vector128.LessThanAny(left.AsVector128Unsafe(), right.AsVector128Unsafe()); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 LessThanOrEqual(Vector3 left, Vector3 right) => Vector128.LessThanOrEqual(left.AsVector128Unsafe(), right.AsVector128Unsafe()).AsVector3(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool LessThanOrEqualAll(Vector3 left, Vector3 right) => Vector128.LessThanOrEqualAll(left.AsVector128Unsafe(), right.AsVector128Unsafe()); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool LessThanOrEqualAny(Vector3 left, Vector3 right) => Vector128.LessThanOrEqualAny(left.AsVector128Unsafe(), right.AsVector128Unsafe()); + + /// + [Intrinsic] + [CLSCompliant(false)] + public static unsafe Vector3 Load(float* source) => LoadUnsafe(in *source); + + /// + [Intrinsic] + [CLSCompliant(false)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe Vector3 LoadAligned(float* source) + { + if (((nuint)(source) % Alignment) != 0) + { + ThrowHelper.ThrowAccessViolationException(); + } + + return *(Vector3*)source; + } + + /// + [Intrinsic] + [CLSCompliant(false)] + public static unsafe Vector3 LoadAlignedNonTemporal(float* source) => LoadAligned(source); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 LoadUnsafe(ref readonly float source) + { + ref readonly byte address = ref Unsafe.As(ref Unsafe.AsRef(in source)); + return Unsafe.ReadUnaligned(in address); + } + + /// + [Intrinsic] + [CLSCompliant(false)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 LoadUnsafe(ref readonly float source, nuint elementOffset) + { + ref readonly byte address = ref Unsafe.As(ref Unsafe.Add(ref Unsafe.AsRef(in source), (nint)elementOffset)); + return Unsafe.ReadUnaligned(in address); + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Log(Vector3 vector) => Vector128.Log(Vector4.Create(vector, 1.0f).AsVector128()).AsVector3(); @@ -453,52 +756,52 @@ public static Vector3 Cross(Vector3 vector1, Vector3 vector2) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Log2(Vector3 vector) => Vector128.Log2(Vector4.Create(vector, 1.0f).AsVector128()).AsVector3(); - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Max(Vector3 value1, Vector3 value2) => Vector128.Max(value1.AsVector128Unsafe(), value2.AsVector128Unsafe()).AsVector3(); - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 MaxMagnitude(Vector3 value1, Vector3 value2) => Vector128.MaxMagnitude(value1.AsVector128Unsafe(), value2.AsVector128Unsafe()).AsVector3(); - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 MaxMagnitudeNumber(Vector3 value1, Vector3 value2) => Vector128.MaxMagnitudeNumber(value1.AsVector128Unsafe(), value2.AsVector128Unsafe()).AsVector3(); - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 MaxNative(Vector3 value1, Vector3 value2) => Vector128.MaxNative(value1.AsVector128Unsafe(), value2.AsVector128Unsafe()).AsVector3(); - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 MaxNumber(Vector3 value1, Vector3 value2) => Vector128.MaxNumber(value1.AsVector128Unsafe(), value2.AsVector128Unsafe()).AsVector3(); - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Min(Vector3 value1, Vector3 value2) => Vector128.Min(value1.AsVector128Unsafe(), value2.AsVector128Unsafe()).AsVector3(); - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 MinMagnitude(Vector3 value1, Vector3 value2) => Vector128.MinMagnitude(value1.AsVector128Unsafe(), value2.AsVector128Unsafe()).AsVector3(); - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 MinMagnitudeNumber(Vector3 value1, Vector3 value2) => Vector128.MinMagnitudeNumber(value1.AsVector128Unsafe(), value2.AsVector128Unsafe()).AsVector3(); - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 MinNative(Vector3 value1, Vector3 value2) => Vector128.MinNative(value1.AsVector128Unsafe(), value2.AsVector128Unsafe()).AsVector3(); - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 MinNumber(Vector3 value1, Vector3 value2) => Vector128.MinNumber(value1.AsVector128Unsafe(), value2.AsVector128Unsafe()).AsVector3(); @@ -535,12 +838,26 @@ public static Vector3 Cross(Vector3 vector1, Vector3 vector2) [Intrinsic] public static Vector3 Negate(Vector3 value) => -value; + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool None(Vector3 vector, float value) => Vector128.None(vector, value); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool NoneWhereAllBitsSet(Vector3 vector) => Vector128.NoneWhereAllBitsSet(vector); + /// Returns a vector with the same direction as the specified vector, but with a length of one. /// The vector to normalize. /// The normalized vector. [Intrinsic] public static Vector3 Normalize(Vector3 value) => value / value.Length(); + /// + [Intrinsic] + public static Vector3 OnesComplement(Vector3 value) => ~value; + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -569,6 +886,20 @@ public static Vector3 Reflect(Vector3 vector, Vector3 normal) [Intrinsic] public static Vector3 Round(Vector3 vector, MidpointRounding mode) => Vector128.Round(vector.AsVector128Unsafe(), mode).AsVector3(); + /// Creates a new vector by selecting values from an input vector using a set of indices. + /// The input vector from which values are selected. + /// The index used to select a value from to be used as the value of in the result. + /// The index used to select a value from to be used as the value of in the result + /// The index used to select a value from to be used as the value of in the result + /// A new vector containing the values from selected by the given indices. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 Shuffle(Vector3 vector, byte xIndex, byte yIndex, byte zIndex) + { + // We do `AsVector128` instead of `AsVector128Unsafe` so that indices which + // are out of range for Vector3 but in range for Vector128 still produce 0 + return Vector128.Shuffle(vector.AsVector128(), Vector128.Create(xIndex, yIndex, zIndex, 3)).AsVector3(); + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Sin(Vector3 vector) => Vector128.Sin(vector.AsVector128()).AsVector3(); @@ -595,6 +926,11 @@ public static (Vector3 Sin, Vector3 Cos) SinCos(Vector3 vector) [Intrinsic] public static Vector3 Subtract(Vector3 left, Vector3 right) => left - right; + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Sum(Vector3 value) => Vector128.Sum(value.AsVector128()); + /// Transforms a vector by a specified 4x4 matrix. /// The vector to transform. /// The transformation matrix. @@ -631,6 +967,10 @@ internal static Vector3 TransformNormal(Vector3 normal, in Matrix4x4.Impl matrix [Intrinsic] public static Vector3 Truncate(Vector3 vector) => Vector128.Truncate(vector.AsVector128Unsafe()).AsVector3(); + /// + [Intrinsic] + public static Vector3 Xor(Vector3 left, Vector3 right) => left ^ right; + /// Copies the elements of the vector to a specified array. /// The destination array. /// must have at least three elements. The method copies the vector's elements starting at index 0. @@ -642,7 +982,7 @@ public readonly void CopyTo(float[] array) { // We explicitly don't check for `null` because historically this has thrown `NullReferenceException` for perf reasons - if (array.Length < Count) + if (array.Length < ElementCount) { ThrowHelper.ThrowArgumentException_DestinationTooShort(); } @@ -670,7 +1010,7 @@ public readonly void CopyTo(float[] array, int index) ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_IndexMustBeLess(); } - if ((array.Length - index) < Count) + if ((array.Length - index) < ElementCount) { ThrowHelper.ThrowArgumentException_DestinationTooShort(); } @@ -684,7 +1024,7 @@ public readonly void CopyTo(float[] array, int index) [MethodImpl(MethodImplOptions.AggressiveInlining)] public readonly void CopyTo(Span destination) { - if (destination.Length < Count) + if (destination.Length < ElementCount) { ThrowHelper.ThrowArgumentException_DestinationTooShort(); } @@ -698,7 +1038,7 @@ public readonly void CopyTo(Span destination) [MethodImpl(MethodImplOptions.AggressiveInlining)] public readonly bool TryCopyTo(Span destination) { - if (destination.Length < Count) + if (destination.Length < ElementCount) { return false; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector4.Extensions.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector4.Extensions.cs index 8e243636d96e40..6aa93a2d4a47a8 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector4.Extensions.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector4.Extensions.cs @@ -12,7 +12,6 @@ public static unsafe partial class Vector /// Reinterprets a as a new . /// The vector to reinterpret. /// reinterpreted as a new . - [Intrinsic] public static Plane AsPlane(this Vector4 value) { #if MONO @@ -25,7 +24,6 @@ public static Plane AsPlane(this Vector4 value) /// Reinterprets a as a new . /// The vector to reinterpret. /// reinterpreted as a new . - [Intrinsic] public static Quaternion AsQuaternion(this Vector4 value) { #if MONO @@ -38,13 +36,64 @@ public static Quaternion AsQuaternion(this Vector4 value) /// Reinterprets a as a new . /// The vector to reinterpret. /// reinterpreted as a new . - [Intrinsic] public static Vector2 AsVector2(this Vector4 value) => value.AsVector128().AsVector2(); /// Reinterprets a as a new . /// The vector to reinterpret. /// reinterpreted as a new . - [Intrinsic] public static Vector3 AsVector3(this Vector4 value) => value.AsVector128().AsVector3(); + + /// + [CLSCompliant(false)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint ExtractMostSignificantBits(this Vector4 vector) => vector.AsVector128().ExtractMostSignificantBits(); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float GetElement(this Vector4 vector, int index) => vector.AsVector128().GetElement(index); + + /// Stores a vector at the given destination. + /// The vector that will be stored. + /// The destination at which will be stored. + [CLSCompliant(false)] + public static void Store(this Vector4 source, float* destination) => source.AsVector128().Store(destination); + + /// Stores a vector at the given 16-byte aligned destination. + /// The vector that will be stored. + /// The aligned destination at which will be stored. + /// is not 16-byte aligned. + [CLSCompliant(false)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void StoreAligned(this Vector4 source, float* destination) => source.AsVector128().StoreAligned(destination); + + /// Stores a vector at the given 16-byte aligned destination. + /// The vector that will be stored. + /// The aligned destination at which will be stored. + /// is not 16-byte aligned. + /// This method may bypass the cache on certain platforms. + [CLSCompliant(false)] + public static void StoreAlignedNonTemporal(this Vector4 source, float* destination) => source.AsVector128().StoreAlignedNonTemporal(destination); + + /// Stores a vector at the given destination. + /// The vector that will be stored. + /// The destination at which will be stored. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void StoreUnsafe(this Vector4 source, ref float destination) => source.AsVector128().StoreUnsafe(ref destination); + + /// Stores a vector at the given destination. + /// The vector that will be stored. + /// The destination to which will be added before the vector will be stored. + /// The element offset from from which the vector will be stored. + [CLSCompliant(false)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void StoreUnsafe(this Vector4 source, ref float destination, nuint elementOffset) => source.AsVector128().StoreUnsafe(ref destination, elementOffset); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float ToScalar(this Vector4 vector) => vector.AsVector128().ToScalar(); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 WithElement(this Vector4 vector, int index, float value) => vector.AsVector128().WithElement(index, value).AsVector4(); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector4.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector4.cs index 305992ed815a28..e0696871900333 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector4.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector4.cs @@ -16,6 +16,24 @@ namespace System.Numerics [Intrinsic] public partial struct Vector4 : IEquatable, IFormattable { + /// Specifies the alignment of the vector as used by the and APIs. + /// + /// + /// Different environments all have their own concepts of alignment/packing. + /// For example, a Vector3 in .NET is 4-byte aligned and 12-bytes in size, + /// in GLSL a vec3 is 16-byte aligned and 16-byte sized, while in HLSL a + /// float3 is functionally 8-byte aligned and 12-byte sized. These differences + /// make it impossible to define a "correct" alignment; additionally, the nuance + /// in environments like HLSL where size is not a multiple of alignment introduce complications. + /// + /// + /// For the purposes of the LoadAligned and StoreAligned APIs we + /// therefore pick a value that allows for a broad range of compatibility while + /// also allowing more optimal codegen for various target platforms. + /// + /// + internal const int Alignment = 16; + /// The X component of the vector. public float X; @@ -28,7 +46,7 @@ public partial struct Vector4 : IEquatable, IFormattable /// The W component of the vector. public float W; - internal const int Count = 4; + internal const int ElementCount = 4; /// Creates a new object whose four elements have the same value. /// The value to assign to all four elements. @@ -76,6 +94,14 @@ public Vector4(ReadOnlySpan values) this = Create(values); } + /// Gets a vector where all bits are set to 1. + /// A vector where all bits are set to 1. + public static Vector4 AllBitsSet + { + [Intrinsic] + get => Vector128.AllBitsSet.AsVector4(); + } + /// Gets a vector whose elements are equal to . /// A vector whose elements are equal to (that is, it returns the vector Create(float.E)). public static Vector4 E @@ -195,13 +221,12 @@ public static Vector4 Zero public float this[int index] { [Intrinsic] - readonly get => this.AsVector128().GetElement(index); + readonly get => this.GetElement(index); [Intrinsic] - [MethodImpl(MethodImplOptions.AggressiveInlining)] set { - this = this.AsVector128().WithElement(index, value).AsVector4(); + this = this.WithElement(index, value); } } @@ -291,6 +316,46 @@ public float this[int index] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 operator -(Vector4 value) => (-value.AsVector128()).AsVector4(); + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 operator &(Vector4 left, Vector4 right) => (left.AsVector128() & right.AsVector128()).AsVector4(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 operator |(Vector4 left, Vector4 right) => (left.AsVector128() | right.AsVector128()).AsVector4(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 operator ^(Vector4 left, Vector4 right) => (left.AsVector128() ^ right.AsVector128()).AsVector4(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 operator <<(Vector4 value, int shiftAmount) => (value.AsVector128() << shiftAmount).AsVector4(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 operator ~(Vector4 value) => (~value.AsVector128()).AsVector4(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 operator >>(Vector4 value, int shiftAmount) => (value.AsVector128() >> shiftAmount).AsVector4(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 operator +(Vector4 value) => value; + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 operator >>>(Vector4 value, int shiftAmount) => (value.AsVector128() >>> shiftAmount).AsVector4(); + /// Returns a vector whose elements are the absolute values of each of the specified vector's elements. /// A vector. /// The absolute value vector. @@ -305,17 +370,55 @@ public float this[int index] [Intrinsic] public static Vector4 Add(Vector4 left, Vector4 right) => left + right; - /// + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool All(Vector4 vector, float value) => Vector128.All(vector.AsVector128(), value); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool AllWhereAllBitsSet(Vector4 vector) => Vector128.AllWhereAllBitsSet(vector.AsVector128()); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 AndNot(Vector4 left, Vector4 right) => Vector128.AndNot(left.AsVector128(), right.AsVector128()).AsVector4(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool Any(Vector4 vector, float value) => Vector128.Any(vector.AsVector128(), value); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool AnyWhereAllBitsSet(Vector4 vector) => Vector128.AnyWhereAllBitsSet(vector.AsVector128()); + + /// + [Intrinsic] + public static Vector4 BitwiseAnd(Vector4 left, Vector4 right) => left & right; + + /// + [Intrinsic] + public static Vector4 BitwiseOr(Vector4 left, Vector4 right) => left | right; + + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Clamp(Vector4 value1, Vector4 min, Vector4 max) => Vector128.Clamp(value1.AsVector128(), min.AsVector128(), max.AsVector128()).AsVector4(); - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 ClampNative(Vector4 value1, Vector4 min, Vector4 max) => Vector128.ClampNative(value1.AsVector128(), min.AsVector128(), max.AsVector128()).AsVector4(); - /// + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 ConditionalSelect(Vector4 condition, Vector4 left, Vector4 right) => Vector128.ConditionalSelect(condition.AsVector128(), left.AsVector128(), right.AsVector128()).AsVector4(); + + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 CopySign(Vector4 value, Vector4 sign) => Vector128.CopySign(value.AsVector128(), sign.AsVector128()).AsVector4(); @@ -324,6 +427,16 @@ public float this[int index] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Cos(Vector4 vector) => Vector128.Cos(vector.AsVector128()).AsVector4(); + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Count(Vector4 vector, float value) => Vector128.Count(vector.AsVector128(), value); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int CountWhereAllBitsSet(Vector4 vector) => Vector128.CountWhereAllBitsSet(vector.AsVector128()); + /// Creates a new object whose four elements have the same value. /// The value to assign to all four elements. /// A new whose four elements have the same value. @@ -430,16 +543,146 @@ public static Vector4 Create(Vector3 vector, float w) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Exp(Vector4 vector) => Vector128.Exp(vector.AsVector128()).AsVector4(); + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 Equals(Vector4 left, Vector4 right) => Vector128.Equals(left.AsVector128(), right.AsVector128()).AsVector4(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool EqualsAll(Vector4 left, Vector4 right) => Vector128.EqualsAll(left.AsVector128(), right.AsVector128()); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool EqualsAny(Vector4 left, Vector4 right) => Vector128.EqualsAny(left.AsVector128(), right.AsVector128()); + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 FusedMultiplyAdd(Vector4 left, Vector4 right, Vector4 addend) => Vector128.FusedMultiplyAdd(left.AsVector128(), right.AsVector128(), addend.AsVector128()).AsVector4(); + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 GreaterThan(Vector4 left, Vector4 right) => Vector128.GreaterThan(left.AsVector128(), right.AsVector128()).AsVector4(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool GreaterThanAll(Vector4 left, Vector4 right) => Vector128.GreaterThanAll(left.AsVector128(), right.AsVector128()); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool GreaterThanAny(Vector4 left, Vector4 right) => Vector128.GreaterThanAny(left.AsVector128(), right.AsVector128()); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 GreaterThanOrEqual(Vector4 left, Vector4 right) => Vector128.GreaterThanOrEqual(left.AsVector128(), right.AsVector128()).AsVector4(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool GreaterThanOrEqualAll(Vector4 left, Vector4 right) => Vector128.GreaterThanOrEqualAll(left.AsVector128(), right.AsVector128()); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool GreaterThanOrEqualAny(Vector4 left, Vector4 right) => Vector128.GreaterThanOrEqualAny(left.AsVector128(), right.AsVector128()); + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Hypot(Vector4 x, Vector4 y) => Vector128.Hypot(x.AsVector128(), y.AsVector128()).AsVector4(); + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int IndexOf(Vector4 vector, float value) => Vector128.IndexOf(vector.AsVector128(), value); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int IndexOfWhereAllBitsSet(Vector4 vector) => Vector128.IndexOfWhereAllBitsSet(vector.AsVector128()); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 IsEvenInteger(Vector4 vector) => Vector128.IsEvenInteger(vector.AsVector128()).AsVector4(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 IsFinite(Vector4 vector) => Vector128.IsFinite(vector.AsVector128()).AsVector4(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 IsInfinity(Vector4 vector) => Vector128.IsInfinity(vector.AsVector128()).AsVector4(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 IsInteger(Vector4 vector) => Vector128.IsInteger(vector.AsVector128()).AsVector4(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 IsNaN(Vector4 vector) => Vector128.IsNaN(vector.AsVector128()).AsVector4(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 IsNegative(Vector4 vector) => Vector128.IsNegative(vector.AsVector128()).AsVector4(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 IsNegativeInfinity(Vector4 vector) => Vector128.IsNegativeInfinity(vector.AsVector128()).AsVector4(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 IsNormal(Vector4 vector) => Vector128.IsNormal(vector.AsVector128()).AsVector4(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 IsOddInteger(Vector4 vector) => Vector128.IsOddInteger(vector.AsVector128()).AsVector4(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 IsPositive(Vector4 vector) => Vector128.IsPositive(vector.AsVector128()).AsVector4(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 IsPositiveInfinity(Vector4 vector) => Vector128.IsPositiveInfinity(vector.AsVector128()).AsVector4(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 IsSubnormal(Vector4 vector) => Vector128.IsSubnormal(vector.AsVector128()).AsVector4(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 IsZero(Vector4 vector) => Vector128.IsZero(vector.AsVector128()).AsVector4(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int LastIndexOf(Vector4 vector, float value) => Vector128.LastIndexOf(vector.AsVector128(), value); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int LastIndexOfWhereAllBitsSet(Vector4 vector) => Vector128.LastIndexOfWhereAllBitsSet(vector.AsVector128()); + /// /// Vector128.Lerp(value1.AsVector128(), value2.AsVector128(), amount.AsVector128()).AsVector4(); + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 LessThan(Vector4 left, Vector4 right) => Vector128.LessThan(left.AsVector128(), right.AsVector128()).AsVector4(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool LessThanAll(Vector4 left, Vector4 right) => Vector128.LessThanAll(left.AsVector128(), right.AsVector128()); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool LessThanAny(Vector4 left, Vector4 right) => Vector128.LessThanAny(left.AsVector128(), right.AsVector128()); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 LessThanOrEqual(Vector4 left, Vector4 right) => Vector128.LessThanOrEqual(left.AsVector128(), right.AsVector128()).AsVector4(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool LessThanOrEqualAll(Vector4 left, Vector4 right) => Vector128.LessThanOrEqualAll(left.AsVector128(), right.AsVector128()); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool LessThanOrEqualAny(Vector4 left, Vector4 right) => Vector128.LessThanOrEqualAny(left.AsVector128(), right.AsVector128()); + + /// + [Intrinsic] + [CLSCompliant(false)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe Vector4 Load(float* source) => Vector128.Load(source).AsVector4(); + + /// + [Intrinsic] + [CLSCompliant(false)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe Vector4 LoadAligned(float* source) => Vector128.LoadAligned(source).AsVector4(); + + /// + [Intrinsic] + [CLSCompliant(false)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe Vector4 LoadAlignedNonTemporal(float* source) => Vector128.LoadAlignedNonTemporal(source).AsVector4(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 LoadUnsafe(ref readonly float source) => Vector128.LoadUnsafe(in source).AsVector4(); + + /// + [Intrinsic] + [CLSCompliant(false)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 LoadUnsafe(ref readonly float source, nuint elementOffset) => Vector128.LoadUnsafe(in source, elementOffset).AsVector4(); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Log(Vector4 vector) => Vector128.Log(vector.AsVector128()).AsVector4(); @@ -461,52 +763,52 @@ public static Vector4 Create(Vector3 vector, float w) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Log2(Vector4 vector) => Vector128.Log2(vector.AsVector128()).AsVector4(); - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Max(Vector4 value1, Vector4 value2) => Vector128.Max(value1.AsVector128(), value2.AsVector128()).AsVector4(); - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 MaxMagnitude(Vector4 value1, Vector4 value2) => Vector128.MaxMagnitude(value1.AsVector128(), value2.AsVector128()).AsVector4(); - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 MaxMagnitudeNumber(Vector4 value1, Vector4 value2) => Vector128.MaxMagnitudeNumber(value1.AsVector128(), value2.AsVector128()).AsVector4(); - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 MaxNative(Vector4 value1, Vector4 value2) => Vector128.MaxNative(value1.AsVector128(), value2.AsVector128()).AsVector4(); - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 MaxNumber(Vector4 value1, Vector4 value2) => Vector128.MaxNumber(value1.AsVector128(), value2.AsVector128()).AsVector4(); - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Min(Vector4 value1, Vector4 value2) => Vector128.Min(value1.AsVector128(), value2.AsVector128()).AsVector4(); - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 MinMagnitude(Vector4 value1, Vector4 value2) => Vector128.MinMagnitude(value1.AsVector128(), value2.AsVector128()).AsVector4(); - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 MinMagnitudeNumber(Vector4 value1, Vector4 value2) => Vector128.MinMagnitudeNumber(value1.AsVector128(), value2.AsVector128()).AsVector4(); - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 MinNative(Vector4 value1, Vector4 value2) => Vector128.MinNative(value1.AsVector128(), value2.AsVector128()).AsVector4(); - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 MinNumber(Vector4 value1, Vector4 value2) => Vector128.MinNumber(value1.AsVector128(), value2.AsVector128()).AsVector4(); @@ -543,12 +845,26 @@ public static Vector4 Create(Vector3 vector, float w) [Intrinsic] public static Vector4 Negate(Vector4 value) => -value; + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool None(Vector4 vector, float value) => Vector128.None(vector.AsVector128(), value); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool NoneWhereAllBitsSet(Vector4 vector) => Vector128.NoneWhereAllBitsSet(vector.AsVector128()); + /// Returns a vector with the same direction as the specified vector, but with a length of one. /// The vector to normalize. /// The normalized vector. [Intrinsic] public static Vector4 Normalize(Vector4 vector) => vector / vector.Length(); + /// + [Intrinsic] + public static Vector4 OnesComplement(Vector4 value) => ~value; + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -562,6 +878,19 @@ public static Vector4 Create(Vector3 vector, float w) [Intrinsic] public static Vector4 Round(Vector4 vector, MidpointRounding mode) => Vector128.Round(vector.AsVector128(), mode).AsVector4(); + /// Creates a new vector by selecting values from an input vector using a set of indices. + /// The input vector from which values are selected. + /// The index used to select a value from to be used as the value of in the result. + /// The index used to select a value from to be used as the value of in the result + /// The index used to select a value from to be used as the value of in the result + /// The index used to select a value from to be used as the value of in the result + /// A new vector containing the values from selected by the given indices. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 Shuffle(Vector4 vector, byte xIndex, byte yIndex, byte zIndex, byte wIndex) + { + return Vector128.Shuffle(vector.AsVector128(), Vector128.Create(xIndex, yIndex, zIndex, wIndex)).AsVector4(); + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Sin(Vector4 vector) => Vector128.Sin(vector.AsVector128()).AsVector4(); @@ -588,6 +917,11 @@ public static (Vector4 Sin, Vector4 Cos) SinCos(Vector4 vector) [Intrinsic] public static Vector4 Subtract(Vector4 left, Vector4 right) => left - right; + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Sum(Vector4 value) => Vector128.Sum(value.AsVector128()); + /// Transforms a two-dimensional vector by a specified 4x4 matrix. /// The vector to transform. /// The transformation matrix. @@ -675,6 +1009,10 @@ public static Vector4 Transform(Vector4 value, Quaternion rotation) [Intrinsic] public static Vector4 Truncate(Vector4 vector) => Vector128.Truncate(vector.AsVector128()).AsVector4(); + /// + [Intrinsic] + public static Vector4 Xor(Vector4 left, Vector4 right) => left ^ right; + /// Copies the elements of the vector to a specified array. /// The destination array. /// must have at least four elements. The method copies the vector's elements starting at index 0. diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector_1.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector_1.cs index 30a3cb9fa37287..3cea422e72c638 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector_1.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector_1.cs @@ -820,6 +820,9 @@ public bool TryCopyTo(Span destination) /// static int ISimdVector, T>.Alignment => Vector.Alignment; + /// + static int ISimdVector, T>.ElementCount => Vector.Count; + /// static bool ISimdVector, T>.IsHardwareAccelerated { @@ -835,10 +838,26 @@ static bool ISimdVector, T>.IsHardwareAccelerated [Intrinsic] static Vector ISimdVector, T>.Add(Vector left, Vector right) => left + right; + /// + [Intrinsic] + static bool ISimdVector, T>.All(Vector vector, T value) => Vector.All(vector, value); + + /// + [Intrinsic] + static bool ISimdVector, T>.AllWhereAllBitsSet(Vector vector) => Vector.AllWhereAllBitsSet(vector); + /// [Intrinsic] static Vector ISimdVector, T>.AndNot(Vector left, Vector right) => Vector.AndNot(left, right); + /// + [Intrinsic] + static bool ISimdVector, T>.Any(Vector vector, T value) => Vector.Any(vector, value); + + /// + [Intrinsic] + static bool ISimdVector, T>.AnyWhereAllBitsSet(Vector vector) => Vector.AnyWhereAllBitsSet(vector); + /// [Intrinsic] static Vector ISimdVector, T>.BitwiseAnd(Vector left, Vector right) => left & right; @@ -876,6 +895,14 @@ static bool ISimdVector, T>.IsHardwareAccelerated /// static void ISimdVector, T>.CopyTo(Vector vector, Span destination) => vector.CopyTo(destination); + /// + [Intrinsic] + static int ISimdVector, T>.Count(Vector vector, T value) => Vector.Count(vector, value); + + /// + [Intrinsic] + static int ISimdVector, T>.CountWhereAllBitsSet(Vector vector) => Vector.CountWhereAllBitsSet(vector); + /// [Intrinsic] static Vector ISimdVector, T>.Create(T value) => Vector.Create(value); @@ -953,6 +980,73 @@ static bool ISimdVector, T>.IsHardwareAccelerated [Intrinsic] static bool ISimdVector, T>.GreaterThanOrEqualAny(Vector left, Vector right) => Vector.GreaterThanOrEqualAny(left, right); + /// + [Intrinsic] + static int ISimdVector, T>.IndexOf(Vector vector, T value) => Vector.IndexOf(vector, value); + + /// + [Intrinsic] + static int ISimdVector, T>.IndexOfWhereAllBitsSet(Vector vector) => Vector.IndexOfWhereAllBitsSet(vector); + + /// + [Intrinsic] + static Vector ISimdVector, T>.IsEvenInteger(Vector vector) => Vector.IsEvenInteger(vector); + + /// + [Intrinsic] + static Vector ISimdVector, T>.IsFinite(Vector vector) => Vector.IsFinite(vector); + + /// + [Intrinsic] + static Vector ISimdVector, T>.IsInfinity(Vector vector) => Vector.IsInfinity(vector); + + /// + [Intrinsic] + static Vector ISimdVector, T>.IsInteger(Vector vector) => Vector.IsInteger(vector); + + /// + [Intrinsic] + static Vector ISimdVector, T>.IsNaN(Vector vector) => Vector.IsNaN(vector); + + /// + [Intrinsic] + static Vector ISimdVector, T>.IsNegative(Vector vector) => Vector.IsNegative(vector); + + /// + [Intrinsic] + static Vector ISimdVector, T>.IsNegativeInfinity(Vector vector) => Vector.IsNegativeInfinity(vector); + + /// + [Intrinsic] + static Vector ISimdVector, T>.IsNormal(Vector vector) => Vector.IsNormal(vector); + + /// + [Intrinsic] + static Vector ISimdVector, T>.IsOddInteger(Vector vector) => Vector.IsOddInteger(vector); + + /// + [Intrinsic] + static Vector ISimdVector, T>.IsPositive(Vector vector) => Vector.IsPositive(vector); + + /// + [Intrinsic] + static Vector ISimdVector, T>.IsPositiveInfinity(Vector vector) => Vector.IsPositiveInfinity(vector); + + /// + [Intrinsic] + static Vector ISimdVector, T>.IsSubnormal(Vector vector) => Vector.IsSubnormal(vector); + + /// + static Vector ISimdVector, T>.IsZero(Vector vector) => Vector.IsZero(vector); + + /// + [Intrinsic] + static int ISimdVector, T>.LastIndexOf(Vector vector, T value) => Vector.LastIndexOf(vector, value); + + /// + [Intrinsic] + static int ISimdVector, T>.LastIndexOfWhereAllBitsSet(Vector vector) => Vector.LastIndexOfWhereAllBitsSet(vector); + /// [Intrinsic] static Vector ISimdVector, T>.LessThan(Vector left, Vector right) => Vector.LessThan(left, right); @@ -1053,6 +1147,14 @@ static bool ISimdVector, T>.IsHardwareAccelerated [Intrinsic] static Vector ISimdVector, T>.Negate(Vector vector) => -vector; + /// + [Intrinsic] + static bool ISimdVector, T>.None(Vector vector, T value) => Vector.None(vector, value); + + /// + [Intrinsic] + static bool ISimdVector, T>.NoneWhereAllBitsSet(Vector vector) => Vector.NoneWhereAllBitsSet(vector); + /// [Intrinsic] static Vector ISimdVector, T>.OnesComplement(Vector vector) => ~vector; @@ -1123,48 +1225,5 @@ static bool ISimdVector, T>.IsHardwareAccelerated /// [Intrinsic] static Vector ISimdVector, T>.Xor(Vector left, Vector right) => left ^ right; - - // - // New Surface Area - // - - static bool ISimdVector, T>.AnyWhereAllBitsSet(Vector vector) => Vector.EqualsAny(vector, AllBitsSet); - - static bool ISimdVector, T>.Any(Vector vector, T value) => Vector.EqualsAny(vector, Vector.Create(value)); - - static int ISimdVector, T>.IndexOfLastMatch(Vector vector) - { - if (sizeof(Vector) == 64) - { - ulong mask = vector.AsVector512().ExtractMostSignificantBits(); - return 63 - BitOperations.LeadingZeroCount(mask); // 63 = 64 (bits in Int64) - 1 (indexing from zero) - } - else if (sizeof(Vector) == 32) - { - uint mask = vector.AsVector256().ExtractMostSignificantBits(); - return 31 - BitOperations.LeadingZeroCount(mask); // 31 = 32 (bits in Int32) - 1 (indexing from zero) - } - else - { - Debug.Assert(sizeof(Vector) == 16); - uint mask = vector.AsVector128().ExtractMostSignificantBits(); - return 31 - BitOperations.LeadingZeroCount(mask); // 31 = 32 (bits in Int32) - 1 (indexing from zero) - } - } - - [Intrinsic] - static Vector ISimdVector, T>.IsNaN(Vector vector) => Vector.IsNaN(vector); - - [Intrinsic] - static Vector ISimdVector, T>.IsNegative(Vector vector) => Vector.IsNegative(vector); - - [Intrinsic] - static Vector ISimdVector, T>.IsPositive(Vector vector) => Vector.IsPositive(vector); - - [Intrinsic] - static Vector ISimdVector, T>.IsPositiveInfinity(Vector vector) => Vector.IsPositiveInfinity(vector); - - [Intrinsic] - static Vector ISimdVector, T>.IsZero(Vector vector) => Vector.IsZero(vector); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/NFloat.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/NFloat.cs index f0e1f6d28aeacc..5939bc9e159450 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/NFloat.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/NFloat.cs @@ -1247,18 +1247,27 @@ bool IFloatingPoint.TryWriteSignificandLittleEndian(Span destinati /// public static NFloat Clamp(NFloat value, NFloat min, NFloat max) => new NFloat(NativeType.Clamp(value._value, min._value, max._value)); + /// + public static NFloat ClampNative(NFloat value, NFloat min, NFloat max) => new NFloat(NativeType.ClampNative(value._value, min._value, max._value)); + /// public static NFloat CopySign(NFloat value, NFloat sign) => new NFloat(NativeType.CopySign(value._value, sign._value)); /// public static NFloat Max(NFloat x, NFloat y) => new NFloat(NativeType.Max(x._value, y._value)); + /// + public static NFloat MaxNative(NFloat x, NFloat y) => new NFloat(NativeType.MaxNative(x._value, y._value)); + /// public static NFloat MaxNumber(NFloat x, NFloat y) => new NFloat(NativeType.MaxNumber(x._value, y._value)); /// public static NFloat Min(NFloat x, NFloat y) => new NFloat(NativeType.Min(x._value, y._value)); + /// + public static NFloat MinNative(NFloat x, NFloat y) => new NFloat(NativeType.MinNative(x._value, y._value)); + /// public static NFloat MinNumber(NFloat x, NFloat y) => new NFloat(NativeType.MinNumber(x._value, y._value)); diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/ISimdVector_2.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/ISimdVector_2.cs index ec4f3640f1475c..bec27899e9f6b5 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/ISimdVector_2.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/ISimdVector_2.cs @@ -42,7 +42,7 @@ internal unsafe interface ISimdVector /// Gets the number of that are in the vector. /// The type of the elements in the vector () is not supported. - static abstract int Count { get; } + static abstract int ElementCount { get; } /// Gets a value that indicates whether the vector operations are subject to hardware acceleration through JIT intrinsic support. /// if the vector operations are subject to hardware acceleration; otherwise, . @@ -93,12 +93,38 @@ internal unsafe interface ISimdVector /// The type of and () is not supported. static virtual TSelf Add(TSelf left, TSelf right) => left + right; + /// Determines if all elements of a vector are equal to a given value. + /// The vector whose elements are being checked. + /// The value to check for in + /// true if all elements of are equal to ; otherwise, false. + /// The type of and () is not supported. + static abstract bool All(TSelf vector, T value); + + /// Determines if all elements of a vector have all their bits set. + /// The vector whose elements are being checked. + /// true if all elements of have all their bits set; otherwise, false. + /// The type of () is not supported. + static abstract bool AllWhereAllBitsSet(TSelf vector); + /// Computes the bitwise-and of a given vector and the ones complement of another vector. /// The vector to bitwise-and with . /// The vector to that is ones-complemented before being bitwise-and with . /// The bitwise-and of and the ones-complement of . static virtual TSelf AndNot(TSelf left, TSelf right) => left & ~right; + /// Determines if any elements of a vector are equal to a given value. + /// The vector whose elements are being checked. + /// The value to check for in + /// true if any elements of are equal to ; otherwise, false. + /// The type of and () is not supported. + static abstract bool Any(TSelf vector, T value); + + /// Determines if any elements of a vector have all their bits set. + /// The vector whose elements are being checked. + /// true if any elements of have all their bits set; otherwise, false. + /// The type of () is not supported. + static abstract bool AnyWhereAllBitsSet(TSelf vector); + /// Computes the bitwise-and of two vectors. /// The vector to bitwise-and with . /// The vector to bitwise-and with . @@ -173,13 +199,26 @@ internal unsafe interface ISimdVector /// The type of the elements in the vector () is not supported. static virtual void CopyTo(TSelf vector, Span destination) { - if (destination.Length < TSelf.Count) + if (destination.Length < TSelf.ElementCount) { ThrowHelper.ThrowArgumentException_DestinationTooShort(); } TSelf.StoreUnsafe(vector, ref MemoryMarshal.GetReference(destination)); } + /// Determines the number of elements in a vector that are equal to a given value. + /// The vector whose elements are being checked. + /// The value to check for in + /// The number of elements in that are equal to . + /// The type of and () is not supported. + static abstract int Count(TSelf vector, T value); + + /// Determines the number of elements in a vector that have all their bits set. + /// The vector whose elements are being checked. + /// The number of elements in that have all their bits set. + /// The type of () is not supported. + static abstract int CountWhereAllBitsSet(TSelf vector); + /// Creates a new vector with all elements initialized to the specified value. /// The value that all elements will be initialized to. /// A new vector with all elements initialized to . @@ -210,7 +249,7 @@ static virtual void CopyTo(TSelf vector, Span destination) /// The type of the elements in the vector () is not supported. static virtual TSelf Create(ReadOnlySpan values) { - if (values.Length < TSelf.Count) + if (values.Length < TSelf.ElementCount) { ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.values); } @@ -332,6 +371,46 @@ static virtual TSelf CreateScalarUnsafe(T value) /// The type of the elements in the vector () is not supported. static abstract bool GreaterThanOrEqualAny(TSelf left, TSelf right); + /// Determines the index of the first element in a vector that is equal to a given value. + /// The vector whose elements are being checked. + /// The value to check for in + /// The index into representing the first element that was equal to ; otherwise, -1 if no such element exists. + /// The type of and () is not supported. + static abstract int IndexOf(TSelf vector, T value); + + /// Determines the index of the first element in a vector that has all bits set. + /// The vector whose elements are being checked. + /// The index into representing the first element that had all bits set; otherwise, -1 if no such element exists. + /// The type of () is not supported. + static abstract int IndexOfWhereAllBitsSet(TSelf vector); + + /// Determines which elements in a vector are even integral values. + /// The vector to be checked. + /// A vector whose elements are all-bits-set or zero, depending on if the corresponding elements in were even integral values. + /// + /// This correctly handles floating-point values and so 2.0 will return all-bits-set while 2.2 will return zero. + /// This functioning returning zero for a corresponding element does not imply that will return all-bits-set for that element. A number with a fractional portion, 3.3, is not even nor odd. + /// + static abstract TSelf IsEvenInteger(TSelf vector); + + /// Determines which elements in a vector are finite. + /// The vector to be checked. + /// A vector whose elements are all-bits-set or zero, depending on if the corresponding elements in were finite. + /// This function returning zero for a corresponding element does not imply that will return all-bits-set for that element. NaN is not finite nor infinite. + static abstract TSelf IsFinite(TSelf vector); + + /// Determines which elements in a vector are infinity. + /// The vector to be checked. + /// A vector whose elements are all-bits-set or zero, depending on if the corresponding elements in were infinity. + /// This function returning zero for a corresponding element does not imply that will return all-bits-set for that element. NaN is not finite nor infinite. + static abstract TSelf IsInfinity(TSelf vector); + + /// Determines which elements in a vector are integral values. + /// The vector to be checked. + /// A vector whose elements are all-bits-set or zero, depending on if the corresponding elements in were integral values. + /// This correctly handles floating-point values and so 2.0 and 3.0 will return all-bits-set for a corresponding element while 2.2 and 3.3 will return zero. + static abstract TSelf IsInteger(TSelf vector); + /// Determines which elements in a vector are NaN. /// The vector to be checked. /// A vector whose elements are all-bits-set or zero, depending on if the corresponding elements in were NaN. @@ -340,11 +419,32 @@ static virtual TSelf CreateScalarUnsafe(T value) /// Determines which elements in a vector represents negative real numbers. /// The vector to be checked. /// A vector whose elements are all-bits-set or zero, depending on if the corresponding elements in were negative. + /// If this type has signed zero, then -0 is also considered negative. static abstract TSelf IsNegative(TSelf vector); + /// Determines which elements in a vector are negative infinity. + /// The vector to be checked. + /// A vector whose elements are all-bits-set or zero, depending on if the corresponding elements in were negative infinity. + static abstract TSelf IsNegativeInfinity(TSelf vector); + + /// Determines which elements in a vector are normal. + /// The vector to be checked. + /// A vector whose elements are all-bits-set or zero, depending on if the corresponding elements in were normal. + static abstract TSelf IsNormal(TSelf vector); + + /// Determines which elements in a vector are odd integral values. + /// The vector to be checked. + /// A vector whose elements are all-bits-set or zero, depending on if the corresponding elements in were odd integral values. + /// + /// This correctly handles floating-point values and so 3.0 will return all-bits-set for a corresponding element while 3.3 will return zero. + /// This functioning returning zero for a corresponding element does not imply that will return all-bits-set for that element. A number with a fractional portion, 3.3, is neither even nor odd. + /// + static abstract TSelf IsOddInteger(TSelf vector); + /// Determines which elements in a vector represents positive real numbers. /// The vector to be checked. /// A vector whose elements are all-bits-set or zero, depending on if the corresponding elements in were positive. + /// If this type has signed zero, then -0 is not considered positive, but +0 is. static abstract TSelf IsPositive(TSelf vector); /// Determines which elements in a vector are positive infinity. @@ -352,11 +452,29 @@ static virtual TSelf CreateScalarUnsafe(T value) /// A vector whose elements are all-bits-set or zero, depending on if the corresponding elements in were positive infinity. static abstract TSelf IsPositiveInfinity(TSelf vector); + /// Determines which elements in a vector are subnormal. + /// The vector to be checked. + /// A vector whose elements are all-bits-set or zero, depending on if the corresponding elements in were subnormal. + static abstract TSelf IsSubnormal(TSelf vector); + /// Determines which elements in a vector are zero. /// The vector to be checked. /// A vector whose elements are all-bits-set or zero, depending on if the corresponding elements in were zero. static abstract TSelf IsZero(TSelf vector); + /// Determines the index of the last element in a vector that is equal to a given value. + /// The vector whose elements are being checked. + /// The value to check for in + /// The index into representing the last element that was equal to ; otherwise, -1 if no such element exists. + /// The type of and () is not supported. + static abstract int LastIndexOf(TSelf vector, T value); + + /// Determines the index of the last element in a vector that has all bits set. + /// The vector whose elements are being checked. + /// The index into representing the last element that had all bits set; otherwise, -1 if no such element exists. + /// The type of () is not supported. + static abstract int LastIndexOfWhereAllBitsSet(TSelf vector); + /// Compares two vectors to determine which is less on a per-element basis. /// The vector to compare with . /// The vector to compare with . @@ -547,6 +665,19 @@ static virtual TSelf LoadAligned(T* source) /// The type of () is not supported. static virtual TSelf Negate(TSelf vector) => -vector; + /// Determines if no elements of a vector are equal to a given value. + /// The vector whose elements are being checked. + /// The value to check for in + /// true if no elements of are equal to ; otherwise, false. + /// The type of and () is not supported. + static abstract bool None(TSelf vector, T value); + + /// Determines if no elements of a vector have all their bits set. + /// The vector whose elements are being checked. + /// true if no elements of have all their bits set; otherwise, false. + /// The type of () is not supported. + static abstract bool NoneWhereAllBitsSet(TSelf vector); + /// Computes the ones-complement of a vector. /// The vector whose ones-complement is to be computed. /// A vector whose elements are the ones-complement of the corresponding elements in . @@ -652,7 +783,7 @@ static virtual void StoreAligned(TSelf source, T* destination) /// The type of the elements in the vector () is not supported. static virtual bool TryCopyTo(TSelf vector, Span destination) { - if (destination.Length < TSelf.Count) + if (destination.Length < TSelf.ElementCount) { return false; } @@ -676,24 +807,5 @@ static virtual bool TryCopyTo(TSelf vector, Span destination) /// The exclusive-or of and . /// The type of and () is not supported. static virtual TSelf Xor(TSelf left, TSelf right) => left ^ right; - - // - // New Surface Area - // - - /// Checks if any of the vector lanes are equivalent to value. - /// The Vector. - /// The Value to check. - /// true if has any lanes equivalent to otherwise, false if none of the lanes are equivalent to />. - /// The type of the elements in the vector () is not supported. - static abstract bool Any(TSelf vector, T value); - - /// Checks if any of the vector lanes have All Bits set. - /// The Vector to check. - /// true if has any lanes with All Bits set otherwise, false if none of the lanes have All Bits set />. - /// The type of the elements in the vector () is not supported. - static abstract bool AnyWhereAllBitsSet(TSelf vector); - - static abstract int IndexOfLastMatch(TSelf vector); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.Numerics.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.Numerics.cs new file mode 100644 index 00000000000000..699c8c5f6734c2 --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.Numerics.cs @@ -0,0 +1,321 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics; +using System.Numerics; +using System.Runtime.CompilerServices; + +namespace System.Runtime.Intrinsics +{ + public static partial class Vector128 + { + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static bool All(Vector2 vector, float value) => vector.AsVector128() == Vector2.Create(value).AsVector128(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static bool All(Vector3 vector, float value) => vector.AsVector128() == Vector3.Create(value).AsVector128(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static bool AllWhereAllBitsSet(Vector2 vector) => vector.AsVector128().AsInt32() == Vector2.AllBitsSet.AsVector128().AsInt32(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static bool AllWhereAllBitsSet(Vector3 vector) => vector.AsVector128().AsInt32() == Vector3.AllBitsSet.AsVector128().AsInt32(); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static bool Any(Vector2 vector, float value) => EqualsAny(vector.AsVector128(), Create(value, value, -1, -1)); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static bool Any(Vector3 vector, float value) => EqualsAny(vector.AsVector128(), Create(value, value, value, -1)); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static bool AnyWhereAllBitsSet(Vector2 vector) => EqualsAny(vector.AsVector128().AsInt32(), Vector128.AllBitsSet); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static bool AnyWhereAllBitsSet(Vector3 vector) => EqualsAny(vector.AsVector128().AsInt32(), Vector128.AllBitsSet); + + /// Reinterprets a as a new . + /// The vector to reinterpret. + /// reinterpreted as a new . + [Intrinsic] + internal static Plane AsPlane(this Vector128 value) + { +#if MONO + return Unsafe.As, Plane>(ref value); +#else + return Unsafe.BitCast, Plane>(value); +#endif + } + + /// Reinterprets a as a new . + /// The vector to reinterpret. + /// reinterpreted as a new . + [Intrinsic] + internal static Quaternion AsQuaternion(this Vector128 value) + { +#if MONO + return Unsafe.As, Quaternion>(ref value); +#else + return Unsafe.BitCast, Quaternion>(value); +#endif + } + + /// Reinterprets a as a new . + /// The plane to reinterpret. + /// reinterpreted as a new . + [Intrinsic] + internal static Vector128 AsVector128(this Plane value) + { +#if MONO + return Unsafe.As>(ref value); +#else + return Unsafe.BitCast>(value); +#endif + } + + /// Reinterprets a as a new . + /// The quaternion to reinterpret. + /// reinterpreted as a new . + [Intrinsic] + internal static Vector128 AsVector128(this Quaternion value) + { +#if MONO + return Unsafe.As>(ref value); +#else + return Unsafe.BitCast>(value); +#endif + } + + /// Reinterprets a as a new with the new elements zeroed. + /// The vector to reinterpret. + /// reinterpreted as a new with the new elements zeroed. + [Intrinsic] + public static Vector128 AsVector128(this Vector2 value) => Vector4.Create(value, 0, 0).AsVector128(); + + /// Reinterprets a as a new with the new elements zeroed. + /// The vector to reinterpret. + /// reinterpreted as a new with the new elements zeroed. + [Intrinsic] + public static Vector128 AsVector128(this Vector3 value) => Vector4.Create(value, 0).AsVector128(); + + /// Reinterprets a as a new . + /// The vector to reinterpret. + /// reinterpreted as a new . + [Intrinsic] + public static Vector128 AsVector128(this Vector4 value) + { +#if MONO + return Unsafe.As>(ref value); +#else + return Unsafe.BitCast>(value); +#endif + } + + /// Reinterprets a as a new . + /// The type of the elements in the vector. + /// The vector to reinterpret. + /// reinterpreted as a new . + /// The type of () is not supported. + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector128 AsVector128(this Vector value) + { + Debug.Assert(Vector.Count >= Vector128.Count); + ThrowHelper.ThrowForUnsupportedIntrinsicsVector128BaseType(); + + ref byte address = ref Unsafe.As, byte>(ref value); + return Unsafe.ReadUnaligned>(ref address); + } + + /// Reinterprets a as a new , leaving the new elements undefined. + /// The vector to reinterpret. + /// reinterpreted as a new . + [Intrinsic] + public static Vector128 AsVector128Unsafe(this Vector2 value) + { + // This relies on us stripping the "init" flag from the ".locals" + // declaration to let the upper bits be uninitialized. + + Unsafe.SkipInit(out Vector128 result); + Unsafe.WriteUnaligned(ref Unsafe.As, byte>(ref result), value); + return result; + } + + /// Reinterprets a as a new , leaving the new elements undefined. + /// The vector to reinterpret. + /// reinterpreted as a new . + [Intrinsic] + public static Vector128 AsVector128Unsafe(this Vector3 value) + { + // This relies on us stripping the "init" flag from the ".locals" + // declaration to let the upper bits be uninitialized. + + Unsafe.SkipInit(out Vector128 result); + Unsafe.WriteUnaligned(ref Unsafe.As, byte>(ref result), value); + return result; + } + + /// Reinterprets a as a new . + /// The vector to reinterpret. + /// reinterpreted as a new . + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 AsVector2(this Vector128 value) + { + ref byte address = ref Unsafe.As, byte>(ref value); + return Unsafe.ReadUnaligned(ref address); + } + + /// Reinterprets a as a new . + /// The vector to reinterpret. + /// reinterpreted as a new . + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 AsVector3(this Vector128 value) + { + ref byte address = ref Unsafe.As, byte>(ref value); + return Unsafe.ReadUnaligned(ref address); + } + + /// Reinterprets a as a new . + /// The vector to reinterpret. + /// reinterpreted as a new . + [Intrinsic] + public static Vector4 AsVector4(this Vector128 value) + { +#if MONO + return Unsafe.As, Vector4>(ref value); +#else + return Unsafe.BitCast, Vector4>(value); +#endif + } + + /// Reinterprets a as a new . + /// The type of the elements in the vector. + /// The vector to reinterpret. + /// reinterpreted as a new . + /// The type of () is not supported. + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector AsVector(this Vector128 value) + { + Debug.Assert(Vector.Count >= Vector128.Count); + ThrowHelper.ThrowForUnsupportedIntrinsicsVector128BaseType(); + + Vector result = default; + Unsafe.WriteUnaligned(ref Unsafe.As, byte>(ref result), value); + return result; + } + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static int Count(Vector2 vector, float value) => BitOperations.PopCount(Equals(vector.AsVector128(), Create(value, value, -1, -1)).ExtractMostSignificantBits()); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static int Count(Vector3 vector, float value) => BitOperations.PopCount(Equals(vector.AsVector128(), Create(value, value, value, -1)).ExtractMostSignificantBits()); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static int CountWhereAllBitsSet(Vector2 vector) => BitOperations.PopCount(Equals(vector.AsVector128().AsInt32(), Vector128.AllBitsSet).ExtractMostSignificantBits()); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static int CountWhereAllBitsSet(Vector3 vector) => BitOperations.PopCount(Equals(vector.AsVector128().AsInt32(), Vector128.AllBitsSet).ExtractMostSignificantBits()); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static int IndexOf(Vector2 vector, float value) + { + int result = BitOperations.TrailingZeroCount(Equals(vector.AsVector128(), Create(value, value, -1, -1)).ExtractMostSignificantBits()); + return (result != 32) ? result : -1; + } + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static int IndexOf(Vector3 vector, float value) + { + int result = BitOperations.TrailingZeroCount(Equals(vector.AsVector128(), Create(value, value, value, -1)).ExtractMostSignificantBits()); + return (result != 32) ? result : -1; + } + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static int IndexOfWhereAllBitsSet(Vector2 vector) + { + int result = BitOperations.TrailingZeroCount(Equals(vector.AsVector128().AsInt32(), Vector128.AllBitsSet).ExtractMostSignificantBits()); + return (result != 32) ? result : -1; + } + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static int IndexOfWhereAllBitsSet(Vector3 vector) + { + int result = BitOperations.TrailingZeroCount(Equals(vector.AsVector128().AsInt32(), Vector128.AllBitsSet).ExtractMostSignificantBits()); + return (result != 32) ? result : -1; + } + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static int LastIndexOf(Vector2 vector, float value) => 31 - BitOperations.LeadingZeroCount(Equals(vector.AsVector128(), Create(value, value, -1, -1)).ExtractMostSignificantBits()); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static int LastIndexOf(Vector3 vector, float value) => 31 - BitOperations.LeadingZeroCount(Equals(vector.AsVector128(), Create(value, value, value, -1)).ExtractMostSignificantBits()); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static int LastIndexOfWhereAllBitsSet(Vector2 vector) => 31 - BitOperations.LeadingZeroCount(Equals(vector.AsVector128().AsInt32(), Vector128.AllBitsSet).ExtractMostSignificantBits()); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static int LastIndexOfWhereAllBitsSet(Vector3 vector) => 31 - BitOperations.LeadingZeroCount(Equals(vector.AsVector128().AsInt32(), Vector128.AllBitsSet).ExtractMostSignificantBits()); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static bool None(Vector2 vector, float value) => !EqualsAny(vector.AsVector128(), Create(value, value, -1, -1)); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static bool None(Vector3 vector, float value) => !EqualsAny(vector.AsVector128(), Create(value, value, value, -1)); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static bool NoneWhereAllBitsSet(Vector2 vector) => !EqualsAny(vector.AsVector128().AsInt32(), Vector128.AllBitsSet); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static bool NoneWhereAllBitsSet(Vector3 vector) => !EqualsAny(vector.AsVector128().AsInt32(), Vector128.AllBitsSet); + } +} diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs index 8fb3436cf3cf8e..6831123b931848 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs @@ -30,7 +30,7 @@ namespace System.Runtime.Intrinsics // the internal inlining limits of the JIT. /// Provides a collection of static methods for creating, manipulating, and otherwise operating on 128-bit vectors. - public static class Vector128 + public static partial class Vector128 { internal const int Size = 16; @@ -84,6 +84,30 @@ public static Vector128 Abs(Vector128 vector) [Intrinsic] public static Vector128 Add(Vector128 left, Vector128 right) => left + right; + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool All(Vector128 vector, T value) => vector == Create(value); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool AllWhereAllBitsSet(Vector128 vector) + { + if (typeof(T) == typeof(float)) + { + return All(vector.AsInt32(), -1); + } + else if (typeof(T) == typeof(double)) + { + return All(vector.AsInt64(), -1); + } + else + { + return All(vector, Scalar.AllBitsSet); + } + } + /// Computes the bitwise-and of a given vector and the ones complement of another vector. /// The type of the elements in the vector. /// The vector to bitwise-and with . @@ -93,6 +117,30 @@ public static Vector128 Abs(Vector128 vector) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector128 AndNot(Vector128 left, Vector128 right) => left & ~right; + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool Any(Vector128 vector, T value) => EqualsAny(vector, Create(value)); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool AnyWhereAllBitsSet(Vector128 vector) + { + if (typeof(T) == typeof(float)) + { + return Any(vector.AsInt32(), -1); + } + else if (typeof(T) == typeof(double)) + { + return Any(vector.AsInt64(), -1); + } + else + { + return Any(vector, Scalar.AllBitsSet); + } + } + /// Reinterprets a as a new . /// The type of the elements in the input vector. /// The type of the elements in the output vector. @@ -170,32 +218,6 @@ public static Vector128 As(this Vector128 vector) [CLSCompliant(false)] public static Vector128 AsNUInt(this Vector128 vector) => vector.As(); - /// Reinterprets a as a new . - /// The vector to reinterpret. - /// reinterpreted as a new . - [Intrinsic] - internal static Plane AsPlane(this Vector128 value) - { -#if MONO - return Unsafe.As, Plane>(ref value); -#else - return Unsafe.BitCast, Plane>(value); -#endif - } - - /// Reinterprets a as a new . - /// The vector to reinterpret. - /// reinterpreted as a new . - [Intrinsic] - internal static Quaternion AsQuaternion(this Vector128 value) - { -#if MONO - return Unsafe.As, Quaternion>(ref value); -#else - return Unsafe.BitCast, Quaternion>(value); -#endif - } - /// Reinterprets a as a new . /// The type of the elements in the vector. /// The vector to reinterpret. @@ -240,153 +262,6 @@ internal static Quaternion AsQuaternion(this Vector128 value) [CLSCompliant(false)] public static Vector128 AsUInt64(this Vector128 vector) => vector.As(); - /// Reinterprets a as a new . - /// The plane to reinterpret. - /// reinterpreted as a new . - [Intrinsic] - internal static Vector128 AsVector128(this Plane value) - { -#if MONO - return Unsafe.As>(ref value); -#else - return Unsafe.BitCast>(value); -#endif - } - - /// Reinterprets a as a new . - /// The quaternion to reinterpret. - /// reinterpreted as a new . - [Intrinsic] - internal static Vector128 AsVector128(this Quaternion value) - { -#if MONO - return Unsafe.As>(ref value); -#else - return Unsafe.BitCast>(value); -#endif - } - - /// Reinterprets a as a new with the new elements zeroed. - /// The vector to reinterpret. - /// reinterpreted as a new with the new elements zeroed. - [Intrinsic] - public static Vector128 AsVector128(this Vector2 value) => Vector4.Create(value, 0, 0).AsVector128(); - - /// Reinterprets a as a new with the new elements zeroed. - /// The vector to reinterpret. - /// reinterpreted as a new with the new elements zeroed. - [Intrinsic] - public static Vector128 AsVector128(this Vector3 value) => Vector4.Create(value, 0).AsVector128(); - - /// Reinterprets a as a new . - /// The vector to reinterpret. - /// reinterpreted as a new . - [Intrinsic] - public static Vector128 AsVector128(this Vector4 value) - { -#if MONO - return Unsafe.As>(ref value); -#else - return Unsafe.BitCast>(value); -#endif - } - - /// Reinterprets a as a new . - /// The type of the elements in the vector. - /// The vector to reinterpret. - /// reinterpreted as a new . - /// The type of () is not supported. - [Intrinsic] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector128 AsVector128(this Vector value) - { - Debug.Assert(Vector.Count >= Vector128.Count); - ThrowHelper.ThrowForUnsupportedIntrinsicsVector128BaseType(); - - ref byte address = ref Unsafe.As, byte>(ref value); - return Unsafe.ReadUnaligned>(ref address); - } - - /// Reinterprets a as a new , leaving the new elements undefined. - /// The vector to reinterpret. - /// reinterpreted as a new . - [Intrinsic] - public static Vector128 AsVector128Unsafe(this Vector2 value) - { - // This relies on us stripping the "init" flag from the ".locals" - // declaration to let the upper bits be uninitialized. - - Unsafe.SkipInit(out Vector128 result); - Unsafe.WriteUnaligned(ref Unsafe.As, byte>(ref result), value); - return result; - } - - /// Reinterprets a as a new , leaving the new elements undefined. - /// The vector to reinterpret. - /// reinterpreted as a new . - [Intrinsic] - public static Vector128 AsVector128Unsafe(this Vector3 value) - { - // This relies on us stripping the "init" flag from the ".locals" - // declaration to let the upper bits be uninitialized. - - Unsafe.SkipInit(out Vector128 result); - Unsafe.WriteUnaligned(ref Unsafe.As, byte>(ref result), value); - return result; - } - - /// Reinterprets a as a new . - /// The vector to reinterpret. - /// reinterpreted as a new . - [Intrinsic] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2 AsVector2(this Vector128 value) - { - ref byte address = ref Unsafe.As, byte>(ref value); - return Unsafe.ReadUnaligned(ref address); - } - - /// Reinterprets a as a new . - /// The vector to reinterpret. - /// reinterpreted as a new . - [Intrinsic] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector3 AsVector3(this Vector128 value) - { - ref byte address = ref Unsafe.As, byte>(ref value); - return Unsafe.ReadUnaligned(ref address); - } - - /// Reinterprets a as a new . - /// The vector to reinterpret. - /// reinterpreted as a new . - [Intrinsic] - public static Vector4 AsVector4(this Vector128 value) - { -#if MONO - return Unsafe.As, Vector4>(ref value); -#else - return Unsafe.BitCast, Vector4>(value); -#endif - } - - /// Reinterprets a as a new . - /// The type of the elements in the vector. - /// The vector to reinterpret. - /// reinterpreted as a new . - /// The type of () is not supported. - [Intrinsic] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector AsVector(this Vector128 value) - { - Debug.Assert(Vector.Count >= Vector128.Count); - ThrowHelper.ThrowForUnsupportedIntrinsicsVector128BaseType(); - - Vector result = default; - Unsafe.WriteUnaligned(ref Unsafe.As, byte>(ref result), value); - return result; - } - /// Computes the bitwise-and of two vectors. /// The type of the elements in the vector. /// The vector to bitwise-and with . @@ -448,7 +323,7 @@ internal static Vector128 Ceiling(Vector128 vector) [Intrinsic] public static Vector128 Ceiling(Vector128 vector) => Ceiling(vector); - /// + /// [Intrinsic] public static Vector128 Clamp(Vector128 value, Vector128 min, Vector128 max) { @@ -456,7 +331,7 @@ public static Vector128 Clamp(Vector128 value, Vector128 min, Vector return Min(Max(value, min), max); } - /// + /// [Intrinsic] public static Vector128 ClampNative(Vector128 value, Vector128 min, Vector128 max) { @@ -734,7 +609,7 @@ public static unsafe Vector128 ConvertToUInt64Native(Vector128 ve ); } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector128 CopySign(Vector128 value, Vector128 sign) @@ -865,6 +740,30 @@ public static Vector128 Cos(Vector128 vector) } } + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Count(Vector128 vector, T value) => BitOperations.PopCount(Equals(vector, Create(value)).ExtractMostSignificantBits()); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int CountWhereAllBitsSet(Vector128 vector) + { + if (typeof(T) == typeof(float)) + { + return Count(vector.AsInt32(), -1); + } + else if (typeof(T) == typeof(double)) + { + return Count(vector.AsInt64(), -1); + } + else + { + return Count(vector, Scalar.AllBitsSet); + } + } + /// Creates a new instance with all elements initialized to the specified value. /// The type of the elements in the vector. /// The value that all elements will be initialized to. @@ -1921,7 +1820,91 @@ public static Vector128 Hypot(Vector128 x, Vector128 y) } } - /// + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int IndexOf(Vector128 vector, T value) + { + int result = BitOperations.TrailingZeroCount(Equals(vector, Create(value)).ExtractMostSignificantBits()); + return (result != 32) ? result : -1; + } + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int IndexOfWhereAllBitsSet(Vector128 vector) + { + if (typeof(T) == typeof(float)) + { + return IndexOf(vector.AsInt32(), -1); + } + else if (typeof(T) == typeof(double)) + { + return IndexOf(vector.AsInt64(), -1); + } + else + { + return IndexOf(vector, Scalar.AllBitsSet); + } + } + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector128 IsEvenInteger(Vector128 vector) + { + if (typeof(T) == typeof(float)) + { + return VectorMath.IsEvenIntegerSingle, Vector128>(vector.AsSingle()).As(); + } + else if (typeof(T) == typeof(double)) + { + return VectorMath.IsEvenIntegerDouble, Vector128>(vector.AsDouble()).As(); + } + return IsZero(vector & Vector128.One); + } + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector128 IsFinite(Vector128 vector) + { + if (typeof(T) == typeof(float)) + { + return ~IsZero(AndNot(Create(float.PositiveInfinityBits), vector.AsUInt32())).As(); + } + else if (typeof(T) == typeof(double)) + { + return ~IsZero(AndNot(Create(double.PositiveInfinityBits), vector.AsUInt64())).As(); + } + return Vector128.AllBitsSet; + } + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector128 IsInfinity(Vector128 vector) + { + if ((typeof(T) == typeof(float)) || (typeof(T) == typeof(double))) + { + return IsPositiveInfinity(Abs(vector)); + } + return Vector128.Zero; + } + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector128 IsInteger(Vector128 vector) + { + if ((typeof(T) == typeof(float)) || (typeof(T) == typeof(double))) + { + return IsFinite(vector) & Equals(vector, Truncate(vector)); + } + return Vector128.AllBitsSet; + } + + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector128 IsNaN(Vector128 vector) @@ -1933,7 +1916,7 @@ public static Vector128 IsNaN(Vector128 vector) return Vector128.Zero; } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector128 IsNegative(Vector128 vector) @@ -1960,7 +1943,55 @@ public static Vector128 IsNegative(Vector128 vector) } } - /// + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector128 IsNegativeInfinity(Vector128 vector) + { + if (typeof(T) == typeof(float)) + { + return Equals(vector, Create(float.NegativeInfinity).As()); + } + else if (typeof(T) == typeof(double)) + { + return Equals(vector, Create(double.NegativeInfinity).As()); + } + return Vector128.Zero; + } + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector128 IsNormal(Vector128 vector) + { + if (typeof(T) == typeof(float)) + { + return LessThan(Abs(vector).AsUInt32() - Create(float.SmallestNormalBits), Create(float.PositiveInfinityBits - float.SmallestNormalBits)).As(); + } + else if (typeof(T) == typeof(double)) + { + return LessThan(Abs(vector).AsUInt64() - Create(double.SmallestNormalBits), Create(double.PositiveInfinityBits - double.SmallestNormalBits)).As(); + } + return ~IsZero(vector); + } + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector128 IsOddInteger(Vector128 vector) + { + if (typeof(T) == typeof(float)) + { + return VectorMath.IsOddIntegerSingle, Vector128>(vector.AsSingle()).As(); + } + else if (typeof(T) == typeof(double)) + { + return VectorMath.IsOddIntegerDouble, Vector128>(vector.AsDouble()).As(); + } + return ~IsZero(vector & Vector128.One); + } + + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector128 IsPositive(Vector128 vector) @@ -1987,7 +2018,7 @@ public static Vector128 IsPositive(Vector128 vector) } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector128 IsPositiveInfinity(Vector128 vector) @@ -2003,11 +2034,51 @@ public static Vector128 IsPositiveInfinity(Vector128 vector) return Vector128.Zero; } - /// + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector128 IsSubnormal(Vector128 vector) + { + if (typeof(T) == typeof(float)) + { + return LessThan(Abs(vector).AsUInt32() - Vector128.One, Create(float.MaxTrailingSignificand)).As(); + } + else if (typeof(T) == typeof(double)) + { + return LessThan(Abs(vector).AsUInt64() - Vector128.One, Create(double.MaxTrailingSignificand)).As(); + } + return Vector128.Zero; + } + + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector128 IsZero(Vector128 vector) => Equals(vector, Vector128.Zero); + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int LastIndexOf(Vector128 vector, T value) => 31 - BitOperations.LeadingZeroCount(Equals(vector, Create(value)).ExtractMostSignificantBits()); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int LastIndexOfWhereAllBitsSet(Vector128 vector) + { + if (typeof(T) == typeof(float)) + { + return LastIndexOf(vector.AsInt32(), -1); + } + else if (typeof(T) == typeof(double)) + { + return LastIndexOf(vector.AsInt64(), -1); + } + else + { + return LastIndexOf(vector, Scalar.AllBitsSet); + } + } + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -2280,7 +2351,7 @@ public static Vector128 Log2(Vector128 vector) } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector128 Max(Vector128 left, Vector128 right) @@ -2298,7 +2369,7 @@ public static Vector128 Max(Vector128 left, Vector128 right) } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector128 MaxMagnitude(Vector128 left, Vector128 right) @@ -2316,7 +2387,7 @@ public static Vector128 MaxMagnitude(Vector128 left, Vector128 right } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector128 MaxMagnitudeNumber(Vector128 left, Vector128 right) @@ -2334,7 +2405,7 @@ public static Vector128 MaxMagnitudeNumber(Vector128 left, Vector128 } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector128 MaxNative(Vector128 left, Vector128 right) @@ -2352,7 +2423,7 @@ public static Vector128 MaxNative(Vector128 left, Vector128 right) } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector128 MaxNumber(Vector128 left, Vector128 right) @@ -2370,7 +2441,7 @@ public static Vector128 MaxNumber(Vector128 left, Vector128 right) } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector128 Min(Vector128 left, Vector128 right) @@ -2388,7 +2459,7 @@ public static Vector128 Min(Vector128 left, Vector128 right) } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector128 MinMagnitude(Vector128 left, Vector128 right) @@ -2406,7 +2477,7 @@ public static Vector128 MinMagnitude(Vector128 left, Vector128 right } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector128 MinMagnitudeNumber(Vector128 left, Vector128 right) @@ -2424,7 +2495,7 @@ public static Vector128 MinMagnitudeNumber(Vector128 left, Vector128 } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector128 MinNative(Vector128 left, Vector128 right) @@ -2442,7 +2513,7 @@ public static Vector128 MinNative(Vector128 left, Vector128 right) } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector128 MinNumber(Vector128 left, Vector128 right) @@ -2629,6 +2700,30 @@ public static unsafe Vector128 Narrow(Vector128 lower, Vector128
    Negate(Vector128 vector) => -vector; + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool None(Vector128 vector, T value) => !EqualsAny(vector, Create(value)); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool NoneWhereAllBitsSet(Vector128 vector) + { + if (typeof(T) == typeof(float)) + { + return None(vector.AsInt32(), -1); + } + else if (typeof(T) == typeof(double)) + { + return None(vector.AsInt64(), -1); + } + else + { + return None(vector, Scalar.AllBitsSet); + } + } + /// Computes the ones-complement of a vector. /// The type of the elements in the vector. /// The vector whose ones-complement is to be computed. @@ -2789,6 +2884,15 @@ internal static Vector128 Round(Vector128 vector) [CLSCompliant(false)] public static Vector128 ShiftLeft(Vector128 vector, int shiftCount) => vector << shiftCount; + [Intrinsic] + internal static Vector128 ShiftLeft(Vector128 vector, Vector128 shiftCount) + { + return Create( + Vector64.ShiftLeft(vector._lower, shiftCount._lower), + Vector64.ShiftLeft(vector._lower, shiftCount._upper) + ); + } + /// Shifts each element of a vector left by the specified amount. /// The vector whose elements are to be shifted. /// The number of bits by which to shift each element. @@ -2797,6 +2901,15 @@ internal static Vector128 Round(Vector128 vector) [CLSCompliant(false)] public static Vector128 ShiftLeft(Vector128 vector, int shiftCount) => vector << shiftCount; + [Intrinsic] + internal static Vector128 ShiftLeft(Vector128 vector, Vector128 shiftCount) + { + return Create( + Vector64.ShiftLeft(vector._lower, shiftCount._lower), + Vector64.ShiftLeft(vector._lower, shiftCount._upper) + ); + } + /// Shifts (signed) each element of a vector right by the specified amount. /// The vector whose elements are to be shifted. /// The number of bits by which to shift each element. @@ -3495,7 +3608,7 @@ internal static Vector128 Truncate(Vector128 vector) [Intrinsic] public static Vector128 Truncate(Vector128 vector) => Truncate(vector); - /// Tries to copy a to a given span. + /// Tries to copy a to a given span. /// The type of the input vector. /// The vector to copy. /// The span to which is copied. diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128_1.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128_1.cs index 46c2ae3cb1c93d..bfcf28021c5845 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128_1.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128_1.cs @@ -471,6 +471,9 @@ private string ToString([StringSyntax(StringSyntaxAttribute.NumericFormat)] stri /// static int ISimdVector, T>.Alignment => Vector128.Alignment; + /// + static int ISimdVector, T>.ElementCount => Vector128.Count; + /// static bool ISimdVector, T>.IsHardwareAccelerated { @@ -486,10 +489,26 @@ static bool ISimdVector, T>.IsHardwareAccelerated [Intrinsic] static Vector128 ISimdVector, T>.Add(Vector128 left, Vector128 right) => left + right; + /// + [Intrinsic] + static bool ISimdVector, T>.All(Vector128 vector, T value) => Vector128.All(vector, value); + + /// + [Intrinsic] + static bool ISimdVector, T>.AllWhereAllBitsSet(Vector128 vector) => Vector128.AllWhereAllBitsSet(vector); + /// [Intrinsic] static Vector128 ISimdVector, T>.AndNot(Vector128 left, Vector128 right) => Vector128.AndNot(left, right); + /// + [Intrinsic] + static bool ISimdVector, T>.Any(Vector128 vector, T value) => Vector128.Any(vector, value); + + /// + [Intrinsic] + static bool ISimdVector, T>.AnyWhereAllBitsSet(Vector128 vector) => Vector128.AnyWhereAllBitsSet(vector); + /// [Intrinsic] static Vector128 ISimdVector, T>.BitwiseAnd(Vector128 left, Vector128 right) => left & right; @@ -527,6 +546,14 @@ static bool ISimdVector, T>.IsHardwareAccelerated /// static void ISimdVector, T>.CopyTo(Vector128 vector, Span destination) => vector.CopyTo(destination); + /// + [Intrinsic] + static int ISimdVector, T>.Count(Vector128 vector, T value) => Vector128.Count(vector, value); + + /// + [Intrinsic] + static int ISimdVector, T>.CountWhereAllBitsSet(Vector128 vector) => Vector128.CountWhereAllBitsSet(vector); + /// [Intrinsic] static Vector128 ISimdVector, T>.Create(T value) => Vector128.Create(value); @@ -604,6 +631,74 @@ static bool ISimdVector, T>.IsHardwareAccelerated [Intrinsic] static bool ISimdVector, T>.GreaterThanOrEqualAny(Vector128 left, Vector128 right) => Vector128.GreaterThanOrEqualAny(left, right); + /// + [Intrinsic] + static int ISimdVector, T>.IndexOf(Vector128 vector, T value) => Vector128.IndexOf(vector, value); + + /// + [Intrinsic] + static int ISimdVector, T>.IndexOfWhereAllBitsSet(Vector128 vector) => Vector128.IndexOfWhereAllBitsSet(vector); + + /// + [Intrinsic] + static Vector128 ISimdVector, T>.IsEvenInteger(Vector128 vector) => Vector128.IsEvenInteger(vector); + + /// + [Intrinsic] + static Vector128 ISimdVector, T>.IsFinite(Vector128 vector) => Vector128.IsFinite(vector); + + /// + [Intrinsic] + static Vector128 ISimdVector, T>.IsInfinity(Vector128 vector) => Vector128.IsInfinity(vector); + + /// + [Intrinsic] + static Vector128 ISimdVector, T>.IsInteger(Vector128 vector) => Vector128.IsInteger(vector); + + /// + [Intrinsic] + static Vector128 ISimdVector, T>.IsNaN(Vector128 vector) => Vector128.IsNaN(vector); + + /// + [Intrinsic] + static Vector128 ISimdVector, T>.IsNegative(Vector128 vector) => Vector128.IsNegative(vector); + + /// + [Intrinsic] + static Vector128 ISimdVector, T>.IsNegativeInfinity(Vector128 vector) => Vector128.IsNegativeInfinity(vector); + + /// + [Intrinsic] + static Vector128 ISimdVector, T>.IsNormal(Vector128 vector) => Vector128.IsNormal(vector); + + /// + [Intrinsic] + static Vector128 ISimdVector, T>.IsOddInteger(Vector128 vector) => Vector128.IsOddInteger(vector); + + /// + [Intrinsic] + static Vector128 ISimdVector, T>.IsPositive(Vector128 vector) => Vector128.IsPositive(vector); + + /// + [Intrinsic] + static Vector128 ISimdVector, T>.IsPositiveInfinity(Vector128 vector) => Vector128.IsPositiveInfinity(vector); + + /// + [Intrinsic] + static Vector128 ISimdVector, T>.IsSubnormal(Vector128 vector) => Vector128.IsSubnormal(vector); + + /// + [Intrinsic] + static Vector128 ISimdVector, T>.IsZero(Vector128 vector) => Vector128.IsZero(vector); + + /// + [Intrinsic] + static int ISimdVector, T>.LastIndexOf(Vector128 vector, T value) => Vector128.LastIndexOf(vector, value); + + /// + [Intrinsic] + static int ISimdVector, T>.LastIndexOfWhereAllBitsSet(Vector128 vector) => Vector128.LastIndexOfWhereAllBitsSet(vector); + /// [Intrinsic] static Vector128 ISimdVector, T>.LessThan(Vector128 left, Vector128 right) => Vector128.LessThan(left, right); @@ -704,6 +799,14 @@ static bool ISimdVector, T>.IsHardwareAccelerated [Intrinsic] static Vector128 ISimdVector, T>.Negate(Vector128 vector) => -vector; + /// + [Intrinsic] + static bool ISimdVector, T>.None(Vector128 vector, T value) => Vector128.None(vector, value); + + /// + [Intrinsic] + static bool ISimdVector, T>.NoneWhereAllBitsSet(Vector128 vector) => Vector128.NoneWhereAllBitsSet(vector); + /// [Intrinsic] static Vector128 ISimdVector, T>.OnesComplement(Vector128 vector) => ~vector; @@ -774,34 +877,5 @@ static bool ISimdVector, T>.IsHardwareAccelerated /// [Intrinsic] static Vector128 ISimdVector, T>.Xor(Vector128 left, Vector128 right) => left ^ right; - - // - // New Surface Area - // - - static bool ISimdVector, T>.AnyWhereAllBitsSet(Vector128 vector) => Vector128.EqualsAny(vector, AllBitsSet); - - static bool ISimdVector, T>.Any(Vector128 vector, T value) => Vector128.EqualsAny(vector, Vector128.Create(value)); - - static int ISimdVector, T>.IndexOfLastMatch(Vector128 vector) - { - uint mask = vector.ExtractMostSignificantBits(); - return 31 - BitOperations.LeadingZeroCount(mask); // 31 = 32 (bits in Int32) - 1 (indexing from zero) - } - - [Intrinsic] - static Vector128 ISimdVector, T>.IsNaN(Vector128 vector) => Vector128.IsNaN(vector); - - [Intrinsic] - static Vector128 ISimdVector, T>.IsNegative(Vector128 vector) => Vector128.IsNegative(vector); - - [Intrinsic] - static Vector128 ISimdVector, T>.IsPositive(Vector128 vector) => Vector128.IsPositive(vector); - - [Intrinsic] - static Vector128 ISimdVector, T>.IsPositiveInfinity(Vector128 vector) => Vector128.IsPositiveInfinity(vector); - - [Intrinsic] - static Vector128 ISimdVector, T>.IsZero(Vector128 vector) => Vector128.IsZero(vector); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256.cs index 6708b81a203610..36093c16b86d94 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256.cs @@ -88,6 +88,30 @@ public static Vector256 Abs(Vector256 vector) [Intrinsic] public static Vector256 Add(Vector256 left, Vector256 right) => left + right; + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool All(Vector256 vector, T value) => vector == Create(value); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool AllWhereAllBitsSet(Vector256 vector) + { + if (typeof(T) == typeof(float)) + { + return All(vector.AsInt32(), -1); + } + else if (typeof(T) == typeof(double)) + { + return All(vector.AsInt64(), -1); + } + else + { + return All(vector, Scalar.AllBitsSet); + } + } + /// Computes the bitwise-and of a given vector and the ones complement of another vector. /// The type of the elements in the vector. /// The vector to bitwise-and with . @@ -98,6 +122,30 @@ public static Vector256 Abs(Vector256 vector) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector256 AndNot(Vector256 left, Vector256 right) => left & ~right; + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool Any(Vector256 vector, T value) => EqualsAny(vector, Create(value)); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool AnyWhereAllBitsSet(Vector256 vector) + { + if (typeof(T) == typeof(float)) + { + return Any(vector.AsInt32(), -1); + } + else if (typeof(T) == typeof(double)) + { + return Any(vector.AsInt64(), -1); + } + else + { + return Any(vector, Scalar.AllBitsSet); + } + } + /// Reinterprets a as a new . /// The type of the elements in the input vector. /// The type of the elements in the output vector. @@ -313,7 +361,7 @@ internal static Vector256 Ceiling(Vector256 vector) [Intrinsic] public static Vector256 Ceiling(Vector256 vector) => Ceiling(vector); - /// + /// [Intrinsic] public static Vector256 Clamp(Vector256 value, Vector256 min, Vector256 max) { @@ -321,7 +369,7 @@ public static Vector256 Clamp(Vector256 value, Vector256 min, Vector return Min(Max(value, min), max); } - /// + /// [Intrinsic] public static Vector256 ClampNative(Vector256 value, Vector256 min, Vector256 max) { @@ -573,7 +621,7 @@ public static Vector256 ConvertToUInt64Native(Vector256 vector) ); } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector256 CopySign(Vector256 value, Vector256 sign) @@ -704,6 +752,30 @@ public static Vector256 Cos(Vector256 vector) } } + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Count(Vector256 vector, T value) => BitOperations.PopCount(Equals(vector, Create(value)).ExtractMostSignificantBits()); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int CountWhereAllBitsSet(Vector256 vector) + { + if (typeof(T) == typeof(float)) + { + return Count(vector.AsInt32(), -1); + } + else if (typeof(T) == typeof(double)) + { + return Count(vector.AsInt64(), -1); + } + else + { + return Count(vector, Scalar.AllBitsSet); + } + } + /// Creates a new instance with all elements initialized to the specified value. /// The type of the elements in the vector. /// The value that all elements will be initialized to. @@ -1837,7 +1909,91 @@ public static Vector256 Hypot(Vector256 x, Vector256 y) } } - /// + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int IndexOf(Vector256 vector, T value) + { + int result = BitOperations.TrailingZeroCount(Equals(vector, Create(value)).ExtractMostSignificantBits()); + return (result != 32) ? result : -1; + } + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int IndexOfWhereAllBitsSet(Vector256 vector) + { + if (typeof(T) == typeof(float)) + { + return IndexOf(vector.AsInt32(), -1); + } + else if (typeof(T) == typeof(double)) + { + return IndexOf(vector.AsInt64(), -1); + } + else + { + return IndexOf(vector, Scalar.AllBitsSet); + } + } + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector256 IsEvenInteger(Vector256 vector) + { + if (typeof(T) == typeof(float)) + { + return VectorMath.IsEvenIntegerSingle, Vector256>(vector.AsSingle()).As(); + } + else if (typeof(T) == typeof(double)) + { + return VectorMath.IsEvenIntegerDouble, Vector256>(vector.AsDouble()).As(); + } + return IsZero(vector & Vector256.One); + } + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector256 IsFinite(Vector256 vector) + { + if (typeof(T) == typeof(float)) + { + return ~IsZero(AndNot(Create(float.PositiveInfinityBits), vector.AsUInt32())).As(); + } + else if (typeof(T) == typeof(double)) + { + return ~IsZero(AndNot(Create(double.PositiveInfinityBits), vector.AsUInt64())).As(); + } + return Vector256.AllBitsSet; + } + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector256 IsInfinity(Vector256 vector) + { + if ((typeof(T) == typeof(float)) || (typeof(T) == typeof(double))) + { + return IsPositiveInfinity(Abs(vector)); + } + return Vector256.Zero; + } + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector256 IsInteger(Vector256 vector) + { + if ((typeof(T) == typeof(float)) || (typeof(T) == typeof(double))) + { + return IsFinite(vector) & Equals(vector, Truncate(vector)); + } + return Vector256.AllBitsSet; + } + + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector256 IsNaN(Vector256 vector) @@ -1849,7 +2005,7 @@ public static Vector256 IsNaN(Vector256 vector) return Vector256.Zero; } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector256 IsNegative(Vector256 vector) @@ -1876,7 +2032,55 @@ public static Vector256 IsNegative(Vector256 vector) } } - /// + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector256 IsNegativeInfinity(Vector256 vector) + { + if (typeof(T) == typeof(float)) + { + return Equals(vector, Create(float.NegativeInfinity).As()); + } + else if (typeof(T) == typeof(double)) + { + return Equals(vector, Create(double.NegativeInfinity).As()); + } + return Vector256.Zero; + } + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector256 IsNormal(Vector256 vector) + { + if (typeof(T) == typeof(float)) + { + return LessThan(Abs(vector).AsUInt32() - Create(float.SmallestNormalBits), Create(float.PositiveInfinityBits - float.SmallestNormalBits)).As(); + } + else if (typeof(T) == typeof(double)) + { + return LessThan(Abs(vector).AsUInt64() - Create(double.SmallestNormalBits), Create(double.PositiveInfinityBits - double.SmallestNormalBits)).As(); + } + return ~IsZero(vector); + } + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector256 IsOddInteger(Vector256 vector) + { + if (typeof(T) == typeof(float)) + { + return VectorMath.IsOddIntegerSingle, Vector256>(vector.AsSingle()).As(); + } + else if (typeof(T) == typeof(double)) + { + return VectorMath.IsOddIntegerDouble, Vector256>(vector.AsDouble()).As(); + } + return ~IsZero(vector & Vector256.One); + } + + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector256 IsPositive(Vector256 vector) @@ -1903,7 +2107,7 @@ public static Vector256 IsPositive(Vector256 vector) } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector256 IsPositiveInfinity(Vector256 vector) @@ -1919,11 +2123,51 @@ public static Vector256 IsPositiveInfinity(Vector256 vector) return Vector256.Zero; } - /// + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector256 IsSubnormal(Vector256 vector) + { + if (typeof(T) == typeof(float)) + { + return LessThan(Abs(vector).AsUInt32() - Vector256.One, Create(float.MaxTrailingSignificand)).As(); + } + else if (typeof(T) == typeof(double)) + { + return LessThan(Abs(vector).AsUInt64() - Vector256.One, Create(double.MaxTrailingSignificand)).As(); + } + return Vector256.Zero; + } + + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector256 IsZero(Vector256 vector) => Equals(vector, Vector256.Zero); + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int LastIndexOf(Vector256 vector, T value) => 31 - BitOperations.LeadingZeroCount(Equals(vector, Create(value)).ExtractMostSignificantBits()); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int LastIndexOfWhereAllBitsSet(Vector256 vector) + { + if (typeof(T) == typeof(float)) + { + return LastIndexOf(vector.AsInt32(), -1); + } + else if (typeof(T) == typeof(double)) + { + return LastIndexOf(vector.AsInt64(), -1); + } + else + { + return LastIndexOf(vector, Scalar.AllBitsSet); + } + } + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -2196,7 +2440,7 @@ public static Vector256 Log2(Vector256 vector) } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector256 Max(Vector256 left, Vector256 right) @@ -2214,7 +2458,7 @@ public static Vector256 Max(Vector256 left, Vector256 right) } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector256 MaxMagnitude(Vector256 left, Vector256 right) @@ -2232,7 +2476,7 @@ public static Vector256 MaxMagnitude(Vector256 left, Vector256 right } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector256 MaxMagnitudeNumber(Vector256 left, Vector256 right) @@ -2250,7 +2494,7 @@ public static Vector256 MaxMagnitudeNumber(Vector256 left, Vector256 } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector256 MaxNative(Vector256 left, Vector256 right) @@ -2268,7 +2512,7 @@ public static Vector256 MaxNative(Vector256 left, Vector256 right) } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector256 MaxNumber(Vector256 left, Vector256 right) @@ -2286,7 +2530,7 @@ public static Vector256 MaxNumber(Vector256 left, Vector256 right) } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector256 Min(Vector256 left, Vector256 right) @@ -2304,7 +2548,7 @@ public static Vector256 Min(Vector256 left, Vector256 right) } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector256 MinMagnitude(Vector256 left, Vector256 right) @@ -2322,7 +2566,7 @@ public static Vector256 MinMagnitude(Vector256 left, Vector256 right } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector256 MinMagnitudeNumber(Vector256 left, Vector256 right) @@ -2340,7 +2584,7 @@ public static Vector256 MinMagnitudeNumber(Vector256 left, Vector256 } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector256 MinNative(Vector256 left, Vector256 right) @@ -2358,7 +2602,7 @@ public static Vector256 MinNative(Vector256 left, Vector256 right) } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector256 MinNumber(Vector256 left, Vector256 right) @@ -2545,6 +2789,30 @@ public static Vector256 Narrow(Vector256 lower, Vector256 up [Intrinsic] public static Vector256 Negate(Vector256 vector) => -vector; + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool None(Vector256 vector, T value) => !EqualsAny(vector, Create(value)); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool NoneWhereAllBitsSet(Vector256 vector) + { + if (typeof(T) == typeof(float)) + { + return None(vector.AsInt32(), -1); + } + else if (typeof(T) == typeof(double)) + { + return None(vector.AsInt64(), -1); + } + else + { + return None(vector, Scalar.AllBitsSet); + } + } + /// Computes the ones-complement of a vector. /// The type of the elements in the vector. /// The vector whose ones-complement is to be computed. @@ -2705,6 +2973,15 @@ internal static Vector256 Round(Vector256 vector) [CLSCompliant(false)] public static Vector256 ShiftLeft(Vector256 vector, int shiftCount) => vector << shiftCount; + [Intrinsic] + internal static Vector256 ShiftLeft(Vector256 vector, Vector256 shiftCount) + { + return Create( + Vector128.ShiftLeft(vector._lower, shiftCount._lower), + Vector128.ShiftLeft(vector._lower, shiftCount._upper) + ); + } + /// Shifts each element of a vector left by the specified amount. /// The vector whose elements are to be shifted. /// The number of bits by which to shift each element. @@ -2713,6 +2990,15 @@ internal static Vector256 Round(Vector256 vector) [CLSCompliant(false)] public static Vector256 ShiftLeft(Vector256 vector, int shiftCount) => vector << shiftCount; + [Intrinsic] + internal static Vector256 ShiftLeft(Vector256 vector, Vector256 shiftCount) + { + return Create( + Vector128.ShiftLeft(vector._lower, shiftCount._lower), + Vector128.ShiftLeft(vector._lower, shiftCount._upper) + ); + } + /// Shifts (signed) each element of a vector right by the specified amount. /// The vector whose elements are to be shifted. /// The number of bits by which to shift each element. diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256_1.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256_1.cs index b4c2996484f9eb..d9fdbd88f3db9d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256_1.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256_1.cs @@ -460,6 +460,9 @@ private string ToString([StringSyntax(StringSyntaxAttribute.NumericFormat)] stri /// static int ISimdVector, T>.Alignment => Vector256.Alignment; + /// + static int ISimdVector, T>.ElementCount => Vector256.Count; + /// static bool ISimdVector, T>.IsHardwareAccelerated { @@ -475,10 +478,26 @@ static bool ISimdVector, T>.IsHardwareAccelerated [Intrinsic] static Vector256 ISimdVector, T>.Add(Vector256 left, Vector256 right) => left + right; + /// + [Intrinsic] + static bool ISimdVector, T>.All(Vector256 vector, T value) => Vector256.All(vector, value); + + /// + [Intrinsic] + static bool ISimdVector, T>.AllWhereAllBitsSet(Vector256 vector) => Vector256.AllWhereAllBitsSet(vector); + /// [Intrinsic] static Vector256 ISimdVector, T>.AndNot(Vector256 left, Vector256 right) => Vector256.AndNot(left, right); + /// + [Intrinsic] + static bool ISimdVector, T>.Any(Vector256 vector, T value) => Vector256.Any(vector, value); + + /// + [Intrinsic] + static bool ISimdVector, T>.AnyWhereAllBitsSet(Vector256 vector) => Vector256.AnyWhereAllBitsSet(vector); + /// [Intrinsic] static Vector256 ISimdVector, T>.BitwiseAnd(Vector256 left, Vector256 right) => left & right; @@ -516,6 +535,14 @@ static bool ISimdVector, T>.IsHardwareAccelerated /// static void ISimdVector, T>.CopyTo(Vector256 vector, Span destination) => vector.CopyTo(destination); + /// + [Intrinsic] + static int ISimdVector, T>.Count(Vector256 vector, T value) => Vector256.Count(vector, value); + + /// + [Intrinsic] + static int ISimdVector, T>.CountWhereAllBitsSet(Vector256 vector) => Vector256.CountWhereAllBitsSet(vector); + /// [Intrinsic] static Vector256 ISimdVector, T>.Create(T value) => Vector256.Create(value); @@ -593,6 +620,73 @@ static bool ISimdVector, T>.IsHardwareAccelerated [Intrinsic] static bool ISimdVector, T>.GreaterThanOrEqualAny(Vector256 left, Vector256 right) => Vector256.GreaterThanOrEqualAny(left, right); + /// + [Intrinsic] + static int ISimdVector, T>.IndexOf(Vector256 vector, T value) => Vector256.IndexOf(vector, value); + + /// + [Intrinsic] + static int ISimdVector, T>.IndexOfWhereAllBitsSet(Vector256 vector) => Vector256.IndexOfWhereAllBitsSet(vector); + + /// + [Intrinsic] + static Vector256 ISimdVector, T>.IsEvenInteger(Vector256 vector) => Vector256.IsEvenInteger(vector); + + /// + [Intrinsic] + static Vector256 ISimdVector, T>.IsFinite(Vector256 vector) => Vector256.IsFinite(vector); + + /// + [Intrinsic] + static Vector256 ISimdVector, T>.IsInfinity(Vector256 vector) => Vector256.IsInfinity(vector); + + /// + [Intrinsic] + static Vector256 ISimdVector, T>.IsInteger(Vector256 vector) => Vector256.IsInteger(vector); + + /// + [Intrinsic] + static Vector256 ISimdVector, T>.IsNaN(Vector256 vector) => Vector256.IsNaN(vector); + + /// + [Intrinsic] + static Vector256 ISimdVector, T>.IsNegative(Vector256 vector) => Vector256.IsNegative(vector); + + /// + [Intrinsic] + static Vector256 ISimdVector, T>.IsNegativeInfinity(Vector256 vector) => Vector256.IsNegativeInfinity(vector); + + /// + [Intrinsic] + static Vector256 ISimdVector, T>.IsNormal(Vector256 vector) => Vector256.IsNormal(vector); + + /// + [Intrinsic] + static Vector256 ISimdVector, T>.IsOddInteger(Vector256 vector) => Vector256.IsOddInteger(vector); + + /// + [Intrinsic] + static Vector256 ISimdVector, T>.IsPositive(Vector256 vector) => Vector256.IsPositive(vector); + + /// + [Intrinsic] + static Vector256 ISimdVector, T>.IsPositiveInfinity(Vector256 vector) => Vector256.IsPositiveInfinity(vector); + + /// + [Intrinsic] + static Vector256 ISimdVector, T>.IsSubnormal(Vector256 vector) => Vector256.IsSubnormal(vector); + + /// + static Vector256 ISimdVector, T>.IsZero(Vector256 vector) => Vector256.IsZero(vector); + + /// + [Intrinsic] + static int ISimdVector, T>.LastIndexOf(Vector256 vector, T value) => Vector256.LastIndexOf(vector, value); + + /// + [Intrinsic] + static int ISimdVector, T>.LastIndexOfWhereAllBitsSet(Vector256 vector) => Vector256.LastIndexOfWhereAllBitsSet(vector); + /// [Intrinsic] static Vector256 ISimdVector, T>.LessThan(Vector256 left, Vector256 right) => Vector256.LessThan(left, right); @@ -693,6 +787,14 @@ static bool ISimdVector, T>.IsHardwareAccelerated [Intrinsic] static Vector256 ISimdVector, T>.Negate(Vector256 vector) => -vector; + /// + [Intrinsic] + static bool ISimdVector, T>.None(Vector256 vector, T value) => Vector256.None(vector, value); + + /// + [Intrinsic] + static bool ISimdVector, T>.NoneWhereAllBitsSet(Vector256 vector) => Vector256.NoneWhereAllBitsSet(vector); + /// [Intrinsic] static Vector256 ISimdVector, T>.OnesComplement(Vector256 vector) => ~vector; @@ -763,34 +865,5 @@ static bool ISimdVector, T>.IsHardwareAccelerated /// [Intrinsic] static Vector256 ISimdVector, T>.Xor(Vector256 left, Vector256 right) => left ^ right; - - // - // New Surface Area - // - - static bool ISimdVector, T>.AnyWhereAllBitsSet(Vector256 vector) => Vector256.EqualsAny(vector, AllBitsSet); - - static bool ISimdVector, T>.Any(Vector256 vector, T value) => Vector256.EqualsAny(vector, Vector256.Create(value)); - - static int ISimdVector, T>.IndexOfLastMatch(Vector256 vector) - { - uint mask = vector.ExtractMostSignificantBits(); - return 31 - BitOperations.LeadingZeroCount(mask); // 31 = 32 (bits in Int32) - 1 (indexing from zero) - } - - [Intrinsic] - static Vector256 ISimdVector, T>.IsNaN(Vector256 vector) => Vector256.IsNaN(vector); - - [Intrinsic] - static Vector256 ISimdVector, T>.IsNegative(Vector256 vector) => Vector256.IsNegative(vector); - - [Intrinsic] - static Vector256 ISimdVector, T>.IsPositive(Vector256 vector) => Vector256.IsPositive(vector); - - [Intrinsic] - static Vector256 ISimdVector, T>.IsPositiveInfinity(Vector256 vector) => Vector256.IsPositiveInfinity(vector); - - [Intrinsic] - static Vector256 ISimdVector, T>.IsZero(Vector256 vector) => Vector256.IsZero(vector); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512.cs index 2b683f06524f45..6877dae70af508 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512.cs @@ -88,6 +88,30 @@ public static Vector512 Abs(Vector512 vector) [Intrinsic] public static Vector512 Add(Vector512 left, Vector512 right) => left + right; + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool All(Vector512 vector, T value) => vector == Create(value); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool AllWhereAllBitsSet(Vector512 vector) + { + if (typeof(T) == typeof(float)) + { + return All(vector.AsInt32(), -1); + } + else if (typeof(T) == typeof(double)) + { + return All(vector.AsInt64(), -1); + } + else + { + return All(vector, Scalar.AllBitsSet); + } + } + /// Computes the bitwise-and of a given vector and the ones complement of another vector. /// The type of the elements in the vector. /// The vector to bitwise-and with . @@ -98,6 +122,30 @@ public static Vector512 Abs(Vector512 vector) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector512 AndNot(Vector512 left, Vector512 right) => left & ~right; + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool Any(Vector512 vector, T value) => EqualsAny(vector, Create(value)); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool AnyWhereAllBitsSet(Vector512 vector) + { + if (typeof(T) == typeof(float)) + { + return Any(vector.AsInt32(), -1); + } + else if (typeof(T) == typeof(double)) + { + return Any(vector.AsInt64(), -1); + } + else + { + return Any(vector, Scalar.AllBitsSet); + } + } + /// Reinterprets a as a new . /// The type of the elements in the input vector. /// The type of the elements in the output vector. @@ -313,7 +361,7 @@ internal static Vector512 Ceiling(Vector512 vector) [Intrinsic] public static Vector512 Ceiling(Vector512 vector) => Ceiling(vector); - /// + /// [Intrinsic] public static Vector512 Clamp(Vector512 value, Vector512 min, Vector512 max) { @@ -321,7 +369,7 @@ public static Vector512 Clamp(Vector512 value, Vector512 min, Vector return Min(Max(value, min), max); } - /// + /// [Intrinsic] public static Vector512 ClampNative(Vector512 value, Vector512 min, Vector512 max) { @@ -502,7 +550,7 @@ public static Vector512 ConvertToUInt64Native(Vector512 vector) ); } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector512 CopySign(Vector512 value, Vector512 sign) @@ -623,6 +671,30 @@ public static Vector512 Cos(Vector512 vector) } } + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Count(Vector512 vector, T value) => BitOperations.PopCount(Equals(vector, Create(value)).ExtractMostSignificantBits()); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int CountWhereAllBitsSet(Vector512 vector) + { + if (typeof(T) == typeof(float)) + { + return Count(vector.AsInt32(), -1); + } + else if (typeof(T) == typeof(double)) + { + return Count(vector.AsInt64(), -1); + } + else + { + return Count(vector, Scalar.AllBitsSet); + } + } + /// Creates a new instance with all elements initialized to the specified value. /// The type of the elements in the vector. /// The value that all elements will be initialized to. @@ -1879,7 +1951,91 @@ public static Vector512 Hypot(Vector512 x, Vector512 y) } } - /// + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int IndexOf(Vector512 vector, T value) + { + int result = BitOperations.TrailingZeroCount(Equals(vector, Create(value)).ExtractMostSignificantBits()); + return (result != 64) ? result : -1; + } + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int IndexOfWhereAllBitsSet(Vector512 vector) + { + if (typeof(T) == typeof(float)) + { + return IndexOf(vector.AsInt32(), -1); + } + else if (typeof(T) == typeof(double)) + { + return IndexOf(vector.AsInt64(), -1); + } + else + { + return IndexOf(vector, Scalar.AllBitsSet); + } + } + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector512 IsEvenInteger(Vector512 vector) + { + if (typeof(T) == typeof(float)) + { + return VectorMath.IsEvenIntegerSingle, Vector512>(vector.AsSingle()).As(); + } + else if (typeof(T) == typeof(double)) + { + return VectorMath.IsEvenIntegerDouble, Vector512>(vector.AsDouble()).As(); + } + return IsZero(vector & Vector512.One); + } + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector512 IsFinite(Vector512 vector) + { + if (typeof(T) == typeof(float)) + { + return ~IsZero(AndNot(Create(float.PositiveInfinityBits), vector.AsUInt32())).As(); + } + else if (typeof(T) == typeof(double)) + { + return ~IsZero(AndNot(Create(double.PositiveInfinityBits), vector.AsUInt64())).As(); + } + return Vector512.AllBitsSet; + } + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector512 IsInfinity(Vector512 vector) + { + if ((typeof(T) == typeof(float)) || (typeof(T) == typeof(double))) + { + return IsPositiveInfinity(Abs(vector)); + } + return Vector512.Zero; + } + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector512 IsInteger(Vector512 vector) + { + if ((typeof(T) == typeof(float)) || (typeof(T) == typeof(double))) + { + return IsFinite(vector) & Equals(vector, Truncate(vector)); + } + return Vector512.AllBitsSet; + } + + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector512 IsNaN(Vector512 vector) @@ -1891,7 +2047,7 @@ public static Vector512 IsNaN(Vector512 vector) return Vector512.Zero; } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector512 IsNegative(Vector512 vector) @@ -1918,7 +2074,55 @@ public static Vector512 IsNegative(Vector512 vector) } } - /// + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector512 IsNegativeInfinity(Vector512 vector) + { + if (typeof(T) == typeof(float)) + { + return Equals(vector, Create(float.NegativeInfinity).As()); + } + else if (typeof(T) == typeof(double)) + { + return Equals(vector, Create(double.NegativeInfinity).As()); + } + return Vector512.Zero; + } + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector512 IsNormal(Vector512 vector) + { + if (typeof(T) == typeof(float)) + { + return LessThan(Abs(vector).AsUInt32() - Create(float.SmallestNormalBits), Create(float.PositiveInfinityBits - float.SmallestNormalBits)).As(); + } + else if (typeof(T) == typeof(double)) + { + return LessThan(Abs(vector).AsUInt64() - Create(double.SmallestNormalBits), Create(double.PositiveInfinityBits - double.SmallestNormalBits)).As(); + } + return ~IsZero(vector); + } + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector512 IsOddInteger(Vector512 vector) + { + if (typeof(T) == typeof(float)) + { + return VectorMath.IsOddIntegerSingle, Vector512>(vector.AsSingle()).As(); + } + else if (typeof(T) == typeof(double)) + { + return VectorMath.IsOddIntegerDouble, Vector512>(vector.AsDouble()).As(); + } + return ~IsZero(vector & Vector512.One); + } + + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector512 IsPositive(Vector512 vector) @@ -1945,7 +2149,7 @@ public static Vector512 IsPositive(Vector512 vector) } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector512 IsPositiveInfinity(Vector512 vector) @@ -1961,11 +2165,51 @@ public static Vector512 IsPositiveInfinity(Vector512 vector) return Vector512.Zero; } - /// + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector512 IsSubnormal(Vector512 vector) + { + if (typeof(T) == typeof(float)) + { + return LessThan(Abs(vector).AsUInt32() - Vector512.One, Create(float.MaxTrailingSignificand)).As(); + } + else if (typeof(T) == typeof(double)) + { + return LessThan(Abs(vector).AsUInt64() - Vector512.One, Create(double.MaxTrailingSignificand)).As(); + } + return Vector512.Zero; + } + + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector512 IsZero(Vector512 vector) => Equals(vector, Vector512.Zero); + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int LastIndexOf(Vector512 vector, T value) => 63 - BitOperations.LeadingZeroCount(Equals(vector, Create(value)).ExtractMostSignificantBits()); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int LastIndexOfWhereAllBitsSet(Vector512 vector) + { + if (typeof(T) == typeof(float)) + { + return LastIndexOf(vector.AsInt32(), -1); + } + else if (typeof(T) == typeof(double)) + { + return LastIndexOf(vector.AsInt64(), -1); + } + else + { + return LastIndexOf(vector, Scalar.AllBitsSet); + } + } + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -2238,7 +2482,7 @@ public static Vector512 Log2(Vector512 vector) } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector512 Max(Vector512 left, Vector512 right) @@ -2256,7 +2500,7 @@ public static Vector512 Max(Vector512 left, Vector512 right) } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector512 MaxMagnitude(Vector512 left, Vector512 right) @@ -2274,7 +2518,7 @@ public static Vector512 MaxMagnitude(Vector512 left, Vector512 right } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector512 MaxMagnitudeNumber(Vector512 left, Vector512 right) @@ -2292,7 +2536,7 @@ public static Vector512 MaxMagnitudeNumber(Vector512 left, Vector512 } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector512 MaxNative(Vector512 left, Vector512 right) @@ -2310,7 +2554,7 @@ public static Vector512 MaxNative(Vector512 left, Vector512 right) } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector512 MaxNumber(Vector512 left, Vector512 right) @@ -2328,7 +2572,7 @@ public static Vector512 MaxNumber(Vector512 left, Vector512 right) } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector512 Min(Vector512 left, Vector512 right) @@ -2346,7 +2590,7 @@ public static Vector512 Min(Vector512 left, Vector512 right) } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector512 MinMagnitude(Vector512 left, Vector512 right) @@ -2364,7 +2608,7 @@ public static Vector512 MinMagnitude(Vector512 left, Vector512 right } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector512 MinMagnitudeNumber(Vector512 left, Vector512 right) @@ -2382,7 +2626,7 @@ public static Vector512 MinMagnitudeNumber(Vector512 left, Vector512 } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector512 MinNative(Vector512 left, Vector512 right) @@ -2400,7 +2644,7 @@ public static Vector512 MinNative(Vector512 left, Vector512 right) } } - /// + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector512 MinNumber(Vector512 left, Vector512 right) @@ -2586,6 +2830,30 @@ public static Vector512 Narrow(Vector512 lower, Vector512 up [Intrinsic] public static Vector512 Negate(Vector512 vector) => -vector; + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool None(Vector512 vector, T value) => !EqualsAny(vector, Create(value)); + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool NoneWhereAllBitsSet(Vector512 vector) + { + if (typeof(T) == typeof(float)) + { + return None(vector.AsInt32(), -1); + } + else if (typeof(T) == typeof(double)) + { + return None(vector.AsInt64(), -1); + } + else + { + return None(vector, Scalar.AllBitsSet); + } + } + /// Computes the ones-complement of a vector. /// The type of the elements in the vector. /// The vector whose ones-complement is to be computed. @@ -2746,6 +3014,15 @@ internal static Vector512 Round(Vector512 vector) [CLSCompliant(false)] public static Vector512 ShiftLeft(Vector512 vector, int shiftCount) => vector << shiftCount; + [Intrinsic] + internal static Vector512 ShiftLeft(Vector512 vector, Vector512 shiftCount) + { + return Create( + Vector256.ShiftLeft(vector._lower, shiftCount._lower), + Vector256.ShiftLeft(vector._lower, shiftCount._upper) + ); + } + /// Shifts each element of a vector left by the specified amount. /// The vector whose elements are to be shifted. /// The number of bits by which to shift each element. @@ -2754,6 +3031,15 @@ internal static Vector512 Round(Vector512 vector) [CLSCompliant(false)] public static Vector512 ShiftLeft(Vector512 vector, int shiftCount) => vector << shiftCount; + [Intrinsic] + internal static Vector512 ShiftLeft(Vector512 vector, Vector512 shiftCount) + { + return Create( + Vector256.ShiftLeft(vector._lower, shiftCount._lower), + Vector256.ShiftLeft(vector._lower, shiftCount._upper) + ); + } + /// Shifts (signed) each element of a vector right by the specified amount. /// The vector whose elements are to be shifted. /// The number of bits by which to shift each element. diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512_1.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512_1.cs index 2105c18257a195..b1c40fcfa72c1b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512_1.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512_1.cs @@ -460,6 +460,9 @@ private string ToString([StringSyntax(StringSyntaxAttribute.NumericFormat)] stri /// static int ISimdVector, T>.Alignment => Vector512.Alignment; + /// + static int ISimdVector, T>.ElementCount => Vector512.Count; + /// static bool ISimdVector, T>.IsHardwareAccelerated { @@ -475,10 +478,26 @@ static bool ISimdVector, T>.IsHardwareAccelerated [Intrinsic] static Vector512 ISimdVector, T>.Add(Vector512 left, Vector512 right) => left + right; + /// + [Intrinsic] + static bool ISimdVector, T>.All(Vector512 vector, T value) => Vector512.All(vector, value); + + /// + [Intrinsic] + static bool ISimdVector, T>.AllWhereAllBitsSet(Vector512 vector) => Vector512.AllWhereAllBitsSet(vector); + /// [Intrinsic] static Vector512 ISimdVector, T>.AndNot(Vector512 left, Vector512 right) => Vector512.AndNot(left, right); + /// + [Intrinsic] + static bool ISimdVector, T>.Any(Vector512 vector, T value) => Vector512.Any(vector, value); + + /// + [Intrinsic] + static bool ISimdVector, T>.AnyWhereAllBitsSet(Vector512 vector) => Vector512.AnyWhereAllBitsSet(vector); + /// [Intrinsic] static Vector512 ISimdVector, T>.BitwiseAnd(Vector512 left, Vector512 right) => left & right; @@ -516,6 +535,14 @@ static bool ISimdVector, T>.IsHardwareAccelerated /// static void ISimdVector, T>.CopyTo(Vector512 vector, Span destination) => vector.CopyTo(destination); + /// + [Intrinsic] + static int ISimdVector, T>.Count(Vector512 vector, T value) => Vector512.Count(vector, value); + + /// + [Intrinsic] + static int ISimdVector, T>.CountWhereAllBitsSet(Vector512 vector) => Vector512.CountWhereAllBitsSet(vector); + /// [Intrinsic] static Vector512 ISimdVector, T>.Create(T value) => Vector512.Create(value); @@ -593,6 +620,73 @@ static bool ISimdVector, T>.IsHardwareAccelerated [Intrinsic] static bool ISimdVector, T>.GreaterThanOrEqualAny(Vector512 left, Vector512 right) => Vector512.GreaterThanOrEqualAny(left, right); + /// + [Intrinsic] + static int ISimdVector, T>.IndexOf(Vector512 vector, T value) => Vector512.IndexOf(vector, value); + + /// + [Intrinsic] + static int ISimdVector, T>.IndexOfWhereAllBitsSet(Vector512 vector) => Vector512.IndexOfWhereAllBitsSet(vector); + + /// + [Intrinsic] + static Vector512 ISimdVector, T>.IsEvenInteger(Vector512 vector) => Vector512.IsEvenInteger(vector); + + /// + [Intrinsic] + static Vector512 ISimdVector, T>.IsFinite(Vector512 vector) => Vector512.IsFinite(vector); + + /// + [Intrinsic] + static Vector512 ISimdVector, T>.IsInfinity(Vector512 vector) => Vector512.IsInfinity(vector); + + /// + [Intrinsic] + static Vector512 ISimdVector, T>.IsInteger(Vector512 vector) => Vector512.IsInteger(vector); + + /// + [Intrinsic] + static Vector512 ISimdVector, T>.IsNaN(Vector512 vector) => Vector512.IsNaN(vector); + + /// + [Intrinsic] + static Vector512 ISimdVector, T>.IsNegative(Vector512 vector) => Vector512.IsNegative(vector); + + /// + [Intrinsic] + static Vector512 ISimdVector, T>.IsNegativeInfinity(Vector512 vector) => Vector512.IsNegativeInfinity(vector); + + /// + [Intrinsic] + static Vector512 ISimdVector, T>.IsNormal(Vector512 vector) => Vector512.IsNormal(vector); + + /// + [Intrinsic] + static Vector512 ISimdVector, T>.IsOddInteger(Vector512 vector) => Vector512.IsOddInteger(vector); + + /// + [Intrinsic] + static Vector512 ISimdVector, T>.IsPositive(Vector512 vector) => Vector512.IsPositive(vector); + + /// + [Intrinsic] + static Vector512 ISimdVector, T>.IsPositiveInfinity(Vector512 vector) => Vector512.IsPositiveInfinity(vector); + + /// + [Intrinsic] + static Vector512 ISimdVector, T>.IsSubnormal(Vector512 vector) => Vector512.IsSubnormal(vector); + + /// + static Vector512 ISimdVector, T>.IsZero(Vector512 vector) => Vector512.IsZero(vector); + + /// + [Intrinsic] + static int ISimdVector, T>.LastIndexOf(Vector512 vector, T value) => Vector512.LastIndexOf(vector, value); + + /// + [Intrinsic] + static int ISimdVector, T>.LastIndexOfWhereAllBitsSet(Vector512 vector) => Vector512.LastIndexOfWhereAllBitsSet(vector); + /// [Intrinsic] static Vector512 ISimdVector, T>.LessThan(Vector512 left, Vector512 right) => Vector512.LessThan(left, right); @@ -693,6 +787,14 @@ static bool ISimdVector, T>.IsHardwareAccelerated [Intrinsic] static Vector512 ISimdVector, T>.Negate(Vector512 vector) => -vector; + /// + [Intrinsic] + static bool ISimdVector, T>.None(Vector512 vector, T value) => Vector512.None(vector, value); + + /// + [Intrinsic] + static bool ISimdVector, T>.NoneWhereAllBitsSet(Vector512 vector) => Vector512.NoneWhereAllBitsSet(vector); + /// [Intrinsic] static Vector512 ISimdVector, T>.OnesComplement(Vector512 vector) => ~vector; @@ -763,34 +865,5 @@ static bool ISimdVector, T>.IsHardwareAccelerated /// [Intrinsic] static Vector512 ISimdVector, T>.Xor(Vector512 left, Vector512 right) => left ^ right; - - // - // New Surface Area - // - - static bool ISimdVector, T>.AnyWhereAllBitsSet(Vector512 vector) => Vector512.EqualsAny(vector, AllBitsSet); - - static bool ISimdVector, T>.Any(Vector512 vector, T value) => Vector512.EqualsAny(vector, Vector512.Create(value)); - - static int ISimdVector, T>.IndexOfLastMatch(Vector512 vector) - { - ulong mask = vector.ExtractMostSignificantBits(); - return 63 - BitOperations.LeadingZeroCount(mask); // 63 = 64 (bits in Int64) - 1 (indexing from zero) - } - - [Intrinsic] - static Vector512 ISimdVector, T>.IsNaN(Vector512 vector) => Vector512.IsNaN(vector); - - [Intrinsic] - static Vector512 ISimdVector, T>.IsNegative(Vector512 vector) => Vector512.IsNegative(vector); - - [Intrinsic] - static Vector512 ISimdVector, T>.IsPositive(Vector512 vector) => Vector512.IsPositive(vector); - - [Intrinsic] - static Vector512 ISimdVector, T>.IsPositiveInfinity(Vector512 vector) => Vector512.IsPositiveInfinity(vector); - - [Intrinsic] - static Vector512 ISimdVector, T>.IsZero(Vector512 vector) => Vector512.IsZero(vector); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector64.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector64.cs index 570933c7abbba2..4ddbe5eb4831b6 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector64.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector64.cs @@ -67,6 +67,39 @@ public static Vector64 Abs(Vector64 vector) [Intrinsic] public static Vector64 Add(Vector64 left, Vector64 right) => left + right; + /// Determines if all elements of a vector are equal to a given value. + /// The type of the elements in the vector. + /// The vector whose elements are being checked. + /// The value to check for in + /// true if all elements of are equal to ; otherwise, false. + /// The type of and () is not supported. + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool All(Vector64 vector, T value) => vector == Create(value); + + /// Determines if all elements of a vector have all their bits set. + /// The type of the elements in the vector. + /// The vector whose elements are being checked. + /// true if all elements of have all their bits set; otherwise, false. + /// The type of () is not supported. + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool AllWhereAllBitsSet(Vector64 vector) + { + if (typeof(T) == typeof(float)) + { + return All(vector.AsInt32(), -1); + } + else if (typeof(T) == typeof(double)) + { + return All(vector.AsInt64(), -1); + } + else + { + return All(vector, Scalar.AllBitsSet); + } + } + /// Computes the bitwise-and of a given vector and the ones complement of another vector. /// The type of the elements in the vector. /// The vector to bitwise-and with . @@ -76,6 +109,39 @@ public static Vector64 Abs(Vector64 vector) [Intrinsic] public static Vector64 AndNot(Vector64 left, Vector64 right) => left & ~right; + /// Determines if any elements of a vector are equal to a given value. + /// The type of the elements in the vector. + /// The vector whose elements are being checked. + /// The value to check for in + /// true if any elements of are equal to ; otherwise, false. + /// The type of and () is not supported. + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool Any(Vector64 vector, T value) => EqualsAny(vector, Create(value)); + + /// Determines if any elements of a vector have all their bits set. + /// The type of the elements in the vector. + /// The vector whose elements are being checked. + /// true if any elements of have all their bits set; otherwise, false. + /// The type of () is not supported. + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool AnyWhereAllBitsSet(Vector64 vector) + { + if (typeof(T) == typeof(float)) + { + return Any(vector.AsInt32(), -1); + } + else if (typeof(T) == typeof(double)) + { + return Any(vector.AsInt64(), -1); + } + else + { + return Any(vector, Scalar.AllBitsSet); + } + } + /// Reinterprets a as a new . /// The type of the elements in the input vector. /// The type of the elements in the output vector. @@ -660,6 +726,39 @@ public static Vector64 Cos(Vector64 vector) } } + /// Determines the number of elements in a vector that are equal to a given value. + /// The type of the elements in the vector. + /// The vector whose elements are being checked. + /// The value to check for in + /// The number of elements in that are equal to . + /// The type of and () is not supported. + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Count(Vector64 vector, T value) => BitOperations.PopCount(Equals(vector, Create(value)).ExtractMostSignificantBits()); + + /// Determines the number of elements in a vector that have all their bits set. + /// The type of the elements in the vector. + /// The vector whose elements are being checked. + /// The number of elements in that have all their bits set. + /// The type of () is not supported. + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int CountWhereAllBitsSet(Vector64 vector) + { + if (typeof(T) == typeof(float)) + { + return Count(vector.AsInt32(), -1); + } + else if (typeof(T) == typeof(double)) + { + return Count(vector.AsInt64(), -1); + } + else + { + return Count(vector, Scalar.AllBitsSet); + } + } + /// Creates a new instance with all elements initialized to the specified value. /// The type of the elements in the vector. /// The value that all elements will be initialized to. @@ -1649,6 +1748,99 @@ public static Vector64 Hypot(Vector64 x, Vector64 y) } } + /// Determines the index of the first element in a vector that is equal to a given value. + /// The type of the elements in the vector. + /// The vector whose elements are being checked. + /// The value to check for in + /// The index into representing the first element that was equal to ; otherwise, -1 if no such element exists. + /// The type of and () is not supported. + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int IndexOf(Vector64 vector, T value) + { + int result = BitOperations.TrailingZeroCount(Equals(vector, Create(value)).ExtractMostSignificantBits()); + return (result != 32) ? result : -1; + } + + /// Determines the index of the first element in a vector that has all bits set. + /// The type of the elements in the vector. + /// The vector whose elements are being checked. + /// The index into representing the first element that had all bits set; otherwise, -1 if no such element exists. + /// The type of () is not supported. + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int IndexOfWhereAllBitsSet(Vector64 vector) + { + if (typeof(T) == typeof(float)) + { + return IndexOf(vector.AsInt32(), -1); + } + else if (typeof(T) == typeof(double)) + { + return IndexOf(vector.AsInt64(), -1); + } + else + { + return IndexOf(vector, Scalar.AllBitsSet); + } + } + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector64 IsEvenInteger(Vector64 vector) + { + if (typeof(T) == typeof(float)) + { + return VectorMath.IsEvenIntegerSingle, Vector64>(vector.AsSingle()).As(); + } + else if (typeof(T) == typeof(double)) + { + return VectorMath.IsEvenIntegerDouble, Vector64>(vector.AsDouble()).As(); + } + return IsZero(vector & Vector64.One); + } + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector64 IsFinite(Vector64 vector) + { + if (typeof(T) == typeof(float)) + { + return ~IsZero(AndNot(Create(float.PositiveInfinityBits), vector.AsUInt32())).As(); + } + else if (typeof(T) == typeof(double)) + { + return ~IsZero(AndNot(Create(double.PositiveInfinityBits), vector.AsUInt64())).As(); + } + return Vector64.AllBitsSet; + } + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector64 IsInfinity(Vector64 vector) + { + if ((typeof(T) == typeof(float)) || (typeof(T) == typeof(double))) + { + return IsPositiveInfinity(Abs(vector)); + } + return Vector64.Zero; + } + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector64 IsInteger(Vector64 vector) + { + if ((typeof(T) == typeof(float)) || (typeof(T) == typeof(double))) + { + return IsFinite(vector) & Equals(vector, Truncate(vector)); + } + return Vector64.AllBitsSet; + } + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1688,6 +1880,54 @@ public static Vector64 IsNegative(Vector64 vector) } } + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector64 IsNegativeInfinity(Vector64 vector) + { + if (typeof(T) == typeof(float)) + { + return Equals(vector, Create(float.NegativeInfinity).As()); + } + else if (typeof(T) == typeof(double)) + { + return Equals(vector, Create(double.NegativeInfinity).As()); + } + return Vector64.Zero; + } + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector64 IsNormal(Vector64 vector) + { + if (typeof(T) == typeof(float)) + { + return LessThan(Abs(vector).AsUInt32() - Create(float.SmallestNormalBits), Create(float.PositiveInfinityBits - float.SmallestNormalBits)).As(); + } + else if (typeof(T) == typeof(double)) + { + return LessThan(Abs(vector).AsUInt64() - Create(double.SmallestNormalBits), Create(double.PositiveInfinityBits - double.SmallestNormalBits)).As(); + } + return ~IsZero(vector); + } + + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector64 IsOddInteger(Vector64 vector) + { + if (typeof(T) == typeof(float)) + { + return VectorMath.IsOddIntegerSingle, Vector64>(vector.AsSingle()).As(); + } + else if (typeof(T) == typeof(double)) + { + return VectorMath.IsOddIntegerDouble, Vector64>(vector.AsDouble()).As(); + } + return ~IsZero(vector & Vector64.One); + } + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1731,11 +1971,60 @@ public static Vector64 IsPositiveInfinity(Vector64 vector) return Vector64.Zero; } + /// + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector64 IsSubnormal(Vector64 vector) + { + if (typeof(T) == typeof(float)) + { + return LessThan(Abs(vector).AsUInt32() - Vector64.One, Create(float.MaxTrailingSignificand)).As(); + } + else if (typeof(T) == typeof(double)) + { + return LessThan(Abs(vector).AsUInt64() - Vector64.One, Create(double.MaxTrailingSignificand)).As(); + } + return Vector64.Zero; + } + /// [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector64 IsZero(Vector64 vector) => Equals(vector, Vector64.Zero); + /// Determines the index of the last element in a vector that is equal to a given value. + /// The type of the elements in the vector. + /// The vector whose elements are being checked. + /// The value to check for in + /// The index into representing the last element that was equal to ; otherwise, -1 if no such element exists. + /// The type of and () is not supported. + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int LastIndexOf(Vector64 vector, T value) => 31 - BitOperations.LeadingZeroCount(Equals(vector, Create(value)).ExtractMostSignificantBits()); + + /// Determines the index of the last element in a vector that has all bits set. + /// The type of the elements in the vector. + /// The vector whose elements are being checked. + /// The index into representing the last element that had all bits set; otherwise, -1 if no such element exists. + /// The type of () is not supported. + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int LastIndexOfWhereAllBitsSet(Vector64 vector) + { + if (typeof(T) == typeof(float)) + { + return LastIndexOf(vector.AsInt32(), -1); + } + else if (typeof(T) == typeof(double)) + { + return LastIndexOf(vector.AsInt64(), -1); + } + else + { + return LastIndexOf(vector, Scalar.AllBitsSet); + } + } + internal static Vector64 Lerp(Vector64 x, Vector64 y, Vector64 amount) where T : IFloatingPointIeee754 { @@ -2582,6 +2871,39 @@ public static unsafe Vector64 Narrow(Vector64 lower, Vector64 Negate(Vector64 vector) => -vector; + /// Determines if no elements of a vector are equal to a given value. + /// The type of the elements in the vector. + /// The vector whose elements are being checked. + /// The value to check for in + /// true if no elements of are equal to ; otherwise, false. + /// The type of and () is not supported. + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool None(Vector64 vector, T value) => !EqualsAny(vector, Create(value)); + + /// Determines if no elements of a vector have all their bits set. + /// The type of the elements in the vector. + /// The vector whose elements are being checked. + /// true if no elements of have all their bits set; otherwise, false. + /// The type of () is not supported. + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool NoneWhereAllBitsSet(Vector64 vector) + { + if (typeof(T) == typeof(float)) + { + return None(vector.AsInt32(), -1); + } + else if (typeof(T) == typeof(double)) + { + return None(vector.AsInt64(), -1); + } + else + { + return None(vector, Scalar.AllBitsSet); + } + } + /// Computes the ones-complement of a vector. /// The type of the elements in the vector. /// The vector whose ones-complement is to be computed. @@ -2765,6 +3087,20 @@ internal static Vector64 Round(Vector64 vector) [CLSCompliant(false)] public static Vector64 ShiftLeft(Vector64 vector, int shiftCount) => vector << shiftCount; + [Intrinsic] + internal static Vector64 ShiftLeft(Vector64 vector, Vector64 shiftCount) + { + Unsafe.SkipInit(out Vector64 result); + + for (int index = 0; index < Vector64.Count; index++) + { + uint element = vector.GetElementUnsafe(index) << (int)shiftCount.GetElementUnsafe(index); + result.SetElementUnsafe(index, element); + } + + return result; + } + /// Shifts each element of a vector left by the specified amount. /// The vector whose elements are to be shifted. /// The number of bits by which to shift each element. @@ -2773,6 +3109,20 @@ internal static Vector64 Round(Vector64 vector) [CLSCompliant(false)] public static Vector64 ShiftLeft(Vector64 vector, int shiftCount) => vector << shiftCount; + [Intrinsic] + internal static Vector64 ShiftLeft(Vector64 vector, Vector64 shiftCount) + { + Unsafe.SkipInit(out Vector64 result); + + for (int index = 0; index < Vector64.Count; index++) + { + ulong element = vector.GetElementUnsafe(index) << (int)shiftCount.GetElementUnsafe(index); + result.SetElementUnsafe(index, element); + } + + return result; + } + /// Shifts (signed) each element of a vector right by the specified amount. /// The vector whose elements are to be shifted. /// The number of bits by which to shift each element. diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector64_1.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector64_1.cs index 9ced0d4f2950fd..e3e4d8c1f55344 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector64_1.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector64_1.cs @@ -528,37 +528,70 @@ private string ToString([StringSyntax(StringSyntaxAttribute.NumericFormat)] stri /// static int ISimdVector, T>.Alignment => Vector64.Alignment; + /// + static int ISimdVector, T>.ElementCount => Vector64.Count; + /// - static bool ISimdVector, T>.IsHardwareAccelerated => Vector64.IsHardwareAccelerated; + static bool ISimdVector, T>.IsHardwareAccelerated + { + [Intrinsic] + get => Vector64.IsHardwareAccelerated; + } /// + [Intrinsic] static Vector64 ISimdVector, T>.Abs(Vector64 vector) => Vector64.Abs(vector); /// + [Intrinsic] static Vector64 ISimdVector, T>.Add(Vector64 left, Vector64 right) => left + right; + /// + [Intrinsic] + static bool ISimdVector, T>.All(Vector64 vector, T value) => Vector64.All(vector, value); + + /// + [Intrinsic] + static bool ISimdVector, T>.AllWhereAllBitsSet(Vector64 vector) => Vector64.AllWhereAllBitsSet(vector); + /// + [Intrinsic] static Vector64 ISimdVector, T>.AndNot(Vector64 left, Vector64 right) => Vector64.AndNot(left, right); + /// + [Intrinsic] + static bool ISimdVector, T>.Any(Vector64 vector, T value) => Vector64.Any(vector, value); + + /// + [Intrinsic] + static bool ISimdVector, T>.AnyWhereAllBitsSet(Vector64 vector) => Vector64.AnyWhereAllBitsSet(vector); + /// + [Intrinsic] static Vector64 ISimdVector, T>.BitwiseAnd(Vector64 left, Vector64 right) => left & right; /// + [Intrinsic] static Vector64 ISimdVector, T>.BitwiseOr(Vector64 left, Vector64 right) => left | right; /// + [Intrinsic] static Vector64 ISimdVector, T>.Ceiling(Vector64 vector) => Vector64.Ceiling(vector); /// + [Intrinsic] static Vector64 ISimdVector, T>.Clamp(Vector64 value, Vector64 min, Vector64 max) => Vector64.Clamp(value, min, max); /// + [Intrinsic] static Vector64 ISimdVector, T>.ClampNative(Vector64 value, Vector64 min, Vector64 max) => Vector64.ClampNative(value, min, max); /// + [Intrinsic] static Vector64 ISimdVector, T>.ConditionalSelect(Vector64 condition, Vector64 left, Vector64 right) => Vector64.ConditionalSelect(condition, left, right); /// + [Intrinsic] static Vector64 ISimdVector, T>.CopySign(Vector64 value, Vector64 sign) => Vector64.CopySign(value, sign); /// @@ -570,7 +603,16 @@ private string ToString([StringSyntax(StringSyntaxAttribute.NumericFormat)] stri /// static void ISimdVector, T>.CopyTo(Vector64 vector, Span destination) => vector.CopyTo(destination); + /// + [Intrinsic] + static int ISimdVector, T>.Count(Vector64 vector, T value) => Vector64.Count(vector, value); + + /// + [Intrinsic] + static int ISimdVector, T>.CountWhereAllBitsSet(Vector64 vector) => Vector64.CountWhereAllBitsSet(vector); + /// + [Intrinsic] static Vector64 ISimdVector, T>.Create(T value) => Vector64.Create(value); /// @@ -583,204 +625,314 @@ private string ToString([StringSyntax(StringSyntaxAttribute.NumericFormat)] stri static Vector64 ISimdVector, T>.Create(ReadOnlySpan values) => Vector64.Create(values); /// + [Intrinsic] static Vector64 ISimdVector, T>.CreateScalar(T value) => Vector64.CreateScalar(value); /// + [Intrinsic] static Vector64 ISimdVector, T>.CreateScalarUnsafe(T value) => Vector64.CreateScalarUnsafe(value); /// + [Intrinsic] static Vector64 ISimdVector, T>.Divide(Vector64 left, Vector64 right) => left / right; /// + [Intrinsic] static Vector64 ISimdVector, T>.Divide(Vector64 left, T right) => left / right; /// + [Intrinsic] static T ISimdVector, T>.Dot(Vector64 left, Vector64 right) => Vector64.Dot(left, right); /// + [Intrinsic] static Vector64 ISimdVector, T>.Equals(Vector64 left, Vector64 right) => Vector64.Equals(left, right); /// + [Intrinsic] static bool ISimdVector, T>.EqualsAll(Vector64 left, Vector64 right) => left == right; /// + [Intrinsic] static bool ISimdVector, T>.EqualsAny(Vector64 left, Vector64 right) => Vector64.EqualsAny(left, right); /// + [Intrinsic] static Vector64 ISimdVector, T>.Floor(Vector64 vector) => Vector64.Floor(vector); /// + [Intrinsic] static T ISimdVector, T>.GetElement(Vector64 vector, int index) => vector.GetElement(index); /// + [Intrinsic] static Vector64 ISimdVector, T>.GreaterThan(Vector64 left, Vector64 right) => Vector64.GreaterThan(left, right); /// + [Intrinsic] static bool ISimdVector, T>.GreaterThanAll(Vector64 left, Vector64 right) => Vector64.GreaterThanAll(left, right); /// + [Intrinsic] static bool ISimdVector, T>.GreaterThanAny(Vector64 left, Vector64 right) => Vector64.GreaterThanAny(left, right); /// + [Intrinsic] static Vector64 ISimdVector, T>.GreaterThanOrEqual(Vector64 left, Vector64 right) => Vector64.GreaterThanOrEqual(left, right); /// + [Intrinsic] static bool ISimdVector, T>.GreaterThanOrEqualAll(Vector64 left, Vector64 right) => Vector64.GreaterThanOrEqualAll(left, right); /// + [Intrinsic] static bool ISimdVector, T>.GreaterThanOrEqualAny(Vector64 left, Vector64 right) => Vector64.GreaterThanOrEqualAny(left, right); + /// + [Intrinsic] + static int ISimdVector, T>.IndexOf(Vector64 vector, T value) => Vector64.IndexOf(vector, value); + + /// + [Intrinsic] + static int ISimdVector, T>.IndexOfWhereAllBitsSet(Vector64 vector) => Vector64.IndexOfWhereAllBitsSet(vector); + + /// + [Intrinsic] + static Vector64 ISimdVector, T>.IsEvenInteger(Vector64 vector) => Vector64.IsEvenInteger(vector); + + /// + [Intrinsic] + static Vector64 ISimdVector, T>.IsFinite(Vector64 vector) => Vector64.IsFinite(vector); + + /// + [Intrinsic] + static Vector64 ISimdVector, T>.IsInfinity(Vector64 vector) => Vector64.IsInfinity(vector); + + /// + [Intrinsic] + static Vector64 ISimdVector, T>.IsInteger(Vector64 vector) => Vector64.IsInteger(vector); + + /// + [Intrinsic] + static Vector64 ISimdVector, T>.IsNaN(Vector64 vector) => Vector64.IsNaN(vector); + + /// + [Intrinsic] + static Vector64 ISimdVector, T>.IsNegative(Vector64 vector) => Vector64.IsNegative(vector); + + /// + [Intrinsic] + static Vector64 ISimdVector, T>.IsNegativeInfinity(Vector64 vector) => Vector64.IsNegativeInfinity(vector); + + /// + [Intrinsic] + static Vector64 ISimdVector, T>.IsNormal(Vector64 vector) => Vector64.IsNormal(vector); + + /// + [Intrinsic] + static Vector64 ISimdVector, T>.IsOddInteger(Vector64 vector) => Vector64.IsOddInteger(vector); + + /// + [Intrinsic] + static Vector64 ISimdVector, T>.IsPositive(Vector64 vector) => Vector64.IsPositive(vector); + + /// + [Intrinsic] + static Vector64 ISimdVector, T>.IsPositiveInfinity(Vector64 vector) => Vector64.IsPositiveInfinity(vector); + + /// + [Intrinsic] + static Vector64 ISimdVector, T>.IsSubnormal(Vector64 vector) => Vector64.IsSubnormal(vector); + + /// + [Intrinsic] + static Vector64 ISimdVector, T>.IsZero(Vector64 vector) => Vector64.IsZero(vector); + + /// + [Intrinsic] + static int ISimdVector, T>.LastIndexOf(Vector64 vector, T value) => Vector64.LastIndexOf(vector, value); + + /// + [Intrinsic] + static int ISimdVector, T>.LastIndexOfWhereAllBitsSet(Vector64 vector) => Vector64.LastIndexOfWhereAllBitsSet(vector); + /// + [Intrinsic] static Vector64 ISimdVector, T>.LessThan(Vector64 left, Vector64 right) => Vector64.LessThan(left, right); /// + [Intrinsic] static bool ISimdVector, T>.LessThanAll(Vector64 left, Vector64 right) => Vector64.LessThanAll(left, right); /// + [Intrinsic] static bool ISimdVector, T>.LessThanAny(Vector64 left, Vector64 right) => Vector64.LessThanAny(left, right); /// + [Intrinsic] static Vector64 ISimdVector, T>.LessThanOrEqual(Vector64 left, Vector64 right) => Vector64.LessThanOrEqual(left, right); /// + [Intrinsic] static bool ISimdVector, T>.LessThanOrEqualAll(Vector64 left, Vector64 right) => Vector64.LessThanOrEqualAll(left, right); /// + [Intrinsic] static bool ISimdVector, T>.LessThanOrEqualAny(Vector64 left, Vector64 right) => Vector64.LessThanOrEqualAny(left, right); /// + [Intrinsic] static Vector64 ISimdVector, T>.Load(T* source) => Vector64.Load(source); /// + [Intrinsic] static Vector64 ISimdVector, T>.LoadAligned(T* source) => Vector64.LoadAligned(source); /// + [Intrinsic] static Vector64 ISimdVector, T>.LoadAlignedNonTemporal(T* source) => Vector64.LoadAlignedNonTemporal(source); /// + [Intrinsic] static Vector64 ISimdVector, T>.LoadUnsafe(ref readonly T source) => Vector64.LoadUnsafe(in source); /// + [Intrinsic] static Vector64 ISimdVector, T>.LoadUnsafe(ref readonly T source, nuint elementOffset) => Vector64.LoadUnsafe(in source, elementOffset); /// + [Intrinsic] static Vector64 ISimdVector, T>.Max(Vector64 left, Vector64 right) => Vector64.Max(left, right); /// + [Intrinsic] static Vector64 ISimdVector, T>.MaxMagnitude(Vector64 left, Vector64 right) => Vector64.MaxMagnitude(left, right); /// + [Intrinsic] static Vector64 ISimdVector, T>.MaxMagnitudeNumber(Vector64 left, Vector64 right) => Vector64.MaxMagnitudeNumber(left, right); /// + [Intrinsic] static Vector64 ISimdVector, T>.MaxNative(Vector64 left, Vector64 right) => Vector64.MaxNative(left, right); /// + [Intrinsic] static Vector64 ISimdVector, T>.MaxNumber(Vector64 left, Vector64 right) => Vector64.MaxNumber(left, right); /// + [Intrinsic] static Vector64 ISimdVector, T>.Min(Vector64 left, Vector64 right) => Vector64.Min(left, right); /// + [Intrinsic] static Vector64 ISimdVector, T>.MinMagnitude(Vector64 left, Vector64 right) => Vector64.MinMagnitude(left, right); /// + [Intrinsic] static Vector64 ISimdVector, T>.MinMagnitudeNumber(Vector64 left, Vector64 right) => Vector64.MinMagnitudeNumber(left, right); /// + [Intrinsic] static Vector64 ISimdVector, T>.MinNative(Vector64 left, Vector64 right) => Vector64.MinNative(left, right); /// + [Intrinsic] static Vector64 ISimdVector, T>.MinNumber(Vector64 left, Vector64 right) => Vector64.MinNumber(left, right); /// + [Intrinsic] static Vector64 ISimdVector, T>.Multiply(Vector64 left, Vector64 right) => left * right; /// + [Intrinsic] static Vector64 ISimdVector, T>.Multiply(Vector64 left, T right) => left * right; /// + [Intrinsic] static Vector64 ISimdVector, T>.MultiplyAddEstimate(Vector64 left, Vector64 right, Vector64 addend) => Vector64.MultiplyAddEstimate(left, right, addend); /// + [Intrinsic] static Vector64 ISimdVector, T>.Negate(Vector64 vector) => -vector; + /// + [Intrinsic] + static bool ISimdVector, T>.None(Vector64 vector, T value) => Vector64.None(vector, value); + + /// + [Intrinsic] + static bool ISimdVector, T>.NoneWhereAllBitsSet(Vector64 vector) => Vector64.NoneWhereAllBitsSet(vector); + /// + [Intrinsic] static Vector64 ISimdVector, T>.OnesComplement(Vector64 vector) => ~vector; /// + [Intrinsic] static Vector64 ISimdVector, T>.Round(Vector64 vector) => Vector64.Round(vector); /// + [Intrinsic] static Vector64 ISimdVector, T>.ShiftLeft(Vector64 vector, int shiftCount) => vector << shiftCount; /// + [Intrinsic] static Vector64 ISimdVector, T>.ShiftRightArithmetic(Vector64 vector, int shiftCount) => vector >> shiftCount; /// + [Intrinsic] static Vector64 ISimdVector, T>.ShiftRightLogical(Vector64 vector, int shiftCount) => vector >>> shiftCount; /// + [Intrinsic] static Vector64 ISimdVector, T>.Sqrt(Vector64 vector) => Vector64.Sqrt(vector); /// + [Intrinsic] static void ISimdVector, T>.Store(Vector64 source, T* destination) => source.Store(destination); /// + [Intrinsic] static void ISimdVector, T>.StoreAligned(Vector64 source, T* destination) => source.StoreAligned(destination); /// + [Intrinsic] static void ISimdVector, T>.StoreAlignedNonTemporal(Vector64 source, T* destination) => source.StoreAlignedNonTemporal(destination); /// + [Intrinsic] static void ISimdVector, T>.StoreUnsafe(Vector64 vector, ref T destination) => vector.StoreUnsafe(ref destination); /// + [Intrinsic] static void ISimdVector, T>.StoreUnsafe(Vector64 vector, ref T destination, nuint elementOffset) => vector.StoreUnsafe(ref destination, elementOffset); /// + [Intrinsic] static Vector64 ISimdVector, T>.Subtract(Vector64 left, Vector64 right) => left - right; /// + [Intrinsic] static T ISimdVector, T>.Sum(Vector64 vector) => Vector64.Sum(vector); /// + [Intrinsic] static T ISimdVector, T>.ToScalar(Vector64 vector) => vector.ToScalar(); /// + [Intrinsic] static Vector64 ISimdVector, T>.Truncate(Vector64 vector) => Vector64.Truncate(vector); /// static bool ISimdVector, T>.TryCopyTo(Vector64 vector, Span destination) => vector.TryCopyTo(destination); /// + [Intrinsic] static Vector64 ISimdVector, T>.WithElement(Vector64 vector, int index, T value) => vector.WithElement(index, value); /// + [Intrinsic] static Vector64 ISimdVector, T>.Xor(Vector64 left, Vector64 right) => left ^ right; - - // - // New Surface Area - // - - static bool ISimdVector, T>.AnyWhereAllBitsSet(Vector64 vector) => Vector64.EqualsAny(vector, AllBitsSet); - - static bool ISimdVector, T>.Any(Vector64 vector, T value) => Vector64.EqualsAny(vector, Vector64.Create(value)); - - static int ISimdVector, T>.IndexOfLastMatch(Vector64 vector) - { - uint mask = vector.ExtractMostSignificantBits(); - return 31 - BitOperations.LeadingZeroCount(mask); // 31 = 32 (bits in Int32) - 1 (indexing from zero) - } - - static Vector64 ISimdVector, T>.IsNaN(Vector64 vector) => Vector64.IsNaN(vector); - - static Vector64 ISimdVector, T>.IsNegative(Vector64 vector) => Vector64.IsNegative(vector); - - static Vector64 ISimdVector, T>.IsPositive(Vector64 vector) => Vector64.IsPositive(vector); - - static Vector64 ISimdVector, T>.IsPositiveInfinity(Vector64 vector) => Vector64.IsPositiveInfinity(vector); - - static Vector64 ISimdVector, T>.IsZero(Vector64 vector) => Vector64.IsZero(vector); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/VectorMath.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/VectorMath.cs index ba2838dd336e32..f5216c5dd48b46 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/VectorMath.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/VectorMath.cs @@ -136,7 +136,7 @@ static TVectorDouble ScalarFallback(TVectorDouble x) { TVectorDouble result = TVectorDouble.Zero; - for (int i = 0; i < TVectorDouble.Count; i++) + for (int i = 0; i < TVectorDouble.ElementCount; i++) { double scalar = double.Cos(x[i]); result = result.WithElement(i, scalar); @@ -225,7 +225,7 @@ public static TVectorSingle CosSingle= 2^-13 - if (TVectorSingle.Count == TVectorDouble.Count) + if (TVectorSingle.ElementCount == TVectorDouble.ElementCount) { result = Narrow( CosSingleSmall(Widen(x)) @@ -250,7 +250,7 @@ public static TVectorSingle CosSingle (pi / 4) -or- infinite -or- nan - if (TVectorSingle.Count == TVectorDouble.Count) + if (TVectorSingle.ElementCount == TVectorDouble.ElementCount) { result = Narrow( CoreImpl(Widen(ax)) @@ -300,7 +300,7 @@ static TVectorSingle ScalarFallback(TVectorSingle x) { TVectorSingle result = TVectorSingle.Zero; - for (int i = 0; i < TVectorSingle.Count; i++) + for (int i = 0; i < TVectorSingle.ElementCount; i++) { float scalar = float.Cos(x[i]); result = result.WithElement(i, scalar); @@ -461,7 +461,7 @@ static TVectorDouble ScalarFallback(TVectorDouble x) { TVectorDouble expResult = TVectorDouble.Zero; - for (int i = 0; i < TVectorDouble.Count; i++) + for (int i = 0; i < TVectorDouble.ElementCount; i++) { double expScalar = double.Exp(x[i]); expResult = expResult.WithElement(i, expScalar); @@ -524,7 +524,7 @@ public static TVectorSingle ExpSingle( CoreImpl(Widen(x)) @@ -608,7 +608,7 @@ public static TVectorDouble HypotDouble(TVectorDou TVectorUInt64 xBits = Unsafe.BitCast(ax); TVectorUInt64 yBits = Unsafe.BitCast(ay); - TVectorUInt64 shiftedExponentMask = TVectorUInt64.Create(double.ShiftedExponentMask); + TVectorUInt64 shiftedExponentMask = TVectorUInt64.Create(double.ShiftedBiasedExponentMask); TVectorUInt64 xExp = (xBits >> double.BiasedExponentShift) & shiftedExponentMask; TVectorUInt64 yExp = (yBits >> double.BiasedExponentShift) & shiftedExponentMask; @@ -737,7 +737,7 @@ public static TVectorSingle HypotSingle(TVectorSin TVectorSingle result; - if (TVectorSingle.Count == TVectorDouble.Count) + if (TVectorSingle.ElementCount == TVectorDouble.ElementCount) { result = Narrow( CoreImpl(Widen(ax), Widen(ay)) @@ -768,6 +768,98 @@ static TVectorDouble CoreImpl(TVectorDouble x, TVectorDouble y) } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static TVectorSingle IsEvenIntegerSingle(TVectorSingle vector) + where TVectorSingle : unmanaged, ISimdVector + where TVectorUInt32 : unmanaged, ISimdVector + { + TVectorUInt32 bits = Unsafe.BitCast(TVectorSingle.Abs(vector)); + + TVectorUInt32 exponent = ((bits >> float.BiasedExponentShift) & TVectorUInt32.Create(float.ShiftedBiasedExponentMask)) - TVectorUInt32.Create(float.ExponentBias); + TVectorUInt32 fractionalBits = TVectorUInt32.Create(float.BiasedExponentShift) - exponent; + TVectorUInt32 firstIntegralBit = ShiftLeftUInt32(TVectorUInt32.One, fractionalBits); + TVectorUInt32 fractionalBitMask = firstIntegralBit - TVectorUInt32.One; + + // We must be an integer in the range [1, 2^24) with the least significant integral bit clear + // or in the range [2^24, +Infinity) in which case we are known to be an even integer + TVectorUInt32 result = TVectorUInt32.GreaterThan(bits, TVectorUInt32.Create(0x3FFF_FFFF)) + & TVectorUInt32.LessThan(bits, TVectorUInt32.Create(float.PositiveInfinityBits)) + & ((TVectorUInt32.IsZero(bits & fractionalBitMask) & TVectorUInt32.IsZero(bits & firstIntegralBit)) + | TVectorUInt32.GreaterThan(bits, TVectorUInt32.Create(0x4B7F_FFFF))); + + // We are also an even integer if we are zero + result |= TVectorUInt32.IsZero(bits); + + return Unsafe.BitCast(result); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static TVectorDouble IsEvenIntegerDouble(TVectorDouble vector) + where TVectorDouble : unmanaged, ISimdVector + where TVectorUInt64 : unmanaged, ISimdVector + { + TVectorUInt64 bits = Unsafe.BitCast(TVectorDouble.Abs(vector)); + + TVectorUInt64 exponent = ((bits >> double.BiasedExponentShift) & TVectorUInt64.Create(double.ShiftedBiasedExponentMask)) - TVectorUInt64.Create(double.ExponentBias); + TVectorUInt64 fractionalBits = TVectorUInt64.Create(double.BiasedExponentShift) - exponent; + TVectorUInt64 firstIntegralBit = ShiftLeftUInt64(TVectorUInt64.One, fractionalBits); + TVectorUInt64 fractionalBitMask = firstIntegralBit - TVectorUInt64.One; + + // We must be an integer in the range [1, 2^53) with the least significant integral bit clear + // or in the range [2^53, +Infinity) in which case we are known to be an even integer + TVectorUInt64 result = TVectorUInt64.GreaterThan(bits, TVectorUInt64.Create(0x3FFF_FFFF_FFFF_FFFF)) + & TVectorUInt64.LessThan(bits, TVectorUInt64.Create(double.PositiveInfinityBits)) + & ((TVectorUInt64.IsZero(bits & fractionalBitMask) & TVectorUInt64.IsZero(bits & firstIntegralBit)) + | TVectorUInt64.GreaterThan(bits, TVectorUInt64.Create(0x433F_FFFF_FFFF_FFFF))); + + // We are also an even integer if we are zero + result |= TVectorUInt64.IsZero(bits); + + return Unsafe.BitCast(result); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static TVectorSingle IsOddIntegerSingle(TVectorSingle vector) + where TVectorSingle : unmanaged, ISimdVector + where TVectorUInt32 : unmanaged, ISimdVector + { + TVectorUInt32 bits = Unsafe.BitCast(TVectorSingle.Abs(vector)); + + TVectorUInt32 exponent = ((bits >> float.BiasedExponentShift) & TVectorUInt32.Create(float.ShiftedBiasedExponentMask)) - TVectorUInt32.Create(float.ExponentBias); + TVectorUInt32 fractionalBits = TVectorUInt32.Create(float.BiasedExponentShift) - exponent; + TVectorUInt32 firstIntegralBit = ShiftLeftUInt32(TVectorUInt32.One, fractionalBits); + TVectorUInt32 fractionalBitMask = firstIntegralBit - TVectorUInt32.One; + + // We must be an integer in the range [1, 2^24) with the least significant integral bit set + TVectorUInt32 result = TVectorUInt32.GreaterThan(bits, TVectorUInt32.Create(0x3F7F_FFFF)) + & TVectorUInt32.LessThan(bits, TVectorUInt32.Create(0x4B80_0000)) + & TVectorUInt32.IsZero(bits & fractionalBitMask) + & ~TVectorUInt32.IsZero(bits & firstIntegralBit); + + return Unsafe.BitCast(result); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static TVectorDouble IsOddIntegerDouble(TVectorDouble vector) + where TVectorDouble : unmanaged, ISimdVector + where TVectorUInt64 : unmanaged, ISimdVector + { + TVectorUInt64 bits = Unsafe.BitCast(TVectorDouble.Abs(vector)); + + TVectorUInt64 exponent = ((bits >> double.BiasedExponentShift) & TVectorUInt64.Create(double.ShiftedBiasedExponentMask)) - TVectorUInt64.Create(double.ExponentBias); + TVectorUInt64 fractionalBits = TVectorUInt64.Create(double.BiasedExponentShift) - exponent; + TVectorUInt64 firstIntegralBit = ShiftLeftUInt64(TVectorUInt64.One, fractionalBits); + TVectorUInt64 fractionalBitMask = firstIntegralBit - TVectorUInt64.One; + + // We must be an integer in the range [1, 2^53) with the least significant integral bit set + TVectorUInt64 result = TVectorUInt64.GreaterThan(bits, TVectorUInt64.Create(0x3FEF_FFFF_FFFF_FFFF)) + & TVectorUInt64.LessThan(bits, TVectorUInt64.Create(0x4340_0000_0000_0000)) + & TVectorUInt64.IsZero(bits & fractionalBitMask) + & ~TVectorUInt64.IsZero(bits & firstIntegralBit); + + return Unsafe.BitCast(result); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TVector Lerp(TVector x, TVector y, TVector amount) where TVector : unmanaged, ISimdVector @@ -1796,7 +1888,7 @@ public static (TVectorDouble Sin, TVectorDouble Cos) SinCosDouble= 2^-13 - if (TVectorSingle.Count == TVectorDouble.Count) + if (TVectorSingle.ElementCount == TVectorDouble.ElementCount) { TVectorDouble dx = Widen(x); @@ -1880,7 +1972,7 @@ public static (TVectorSingle Sin, TVectorSingle Cos) SinCosSingle (pi / 4) -or- infinite -or- nan - if (TVectorSingle.Count == TVectorDouble.Count) + if (TVectorSingle.ElementCount == TVectorDouble.ElementCount) { (TVectorDouble sin, TVectorDouble cos) = CoreImpl(Widen(x)); @@ -1957,7 +2049,7 @@ public static (TVectorSingle Sin, TVectorSingle Cos) SinCosSingle= 2^-13 - if (TVectorSingle.Count == TVectorDouble.Count) + if (TVectorSingle.ElementCount == TVectorDouble.ElementCount) { result = Narrow( SinSinglePoly(Widen(x)) @@ -2195,7 +2287,7 @@ public static TVectorSingle SinSingle (pi / 4) -or- infinite -or- nan - if (TVectorSingle.Count == TVectorDouble.Count) + if (TVectorSingle.ElementCount == TVectorDouble.ElementCount) { result = Narrow( CoreImpl(Widen(x)) @@ -2248,7 +2340,7 @@ static TVectorSingle ScalarFallback(TVectorSingle x) { TVectorSingle result = TVectorSingle.Zero; - for (int i = 0; i < TVectorSingle.Count; i++) + for (int i = 0; i < TVectorSingle.ElementCount; i++) { float scalar = float.Sin(x[i]); result = result.WithElement(i, scalar); @@ -2583,6 +2675,104 @@ private static TVectorSingle Narrow(TVectorDouble return result; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static TVectorUInt32 ShiftLeftUInt32(TVectorUInt32 vector, TVectorUInt32 shiftAmount) + where TVectorUInt32 : unmanaged, ISimdVector + { + Unsafe.SkipInit(out TVectorUInt32 result); + + if (typeof(TVectorUInt32) == typeof(Vector)) + { + result = (TVectorUInt32)(object)Vector.ShiftLeft( + (Vector)(object)vector, + (Vector)(object)shiftAmount + ); + } + else if (typeof(TVectorUInt32) == typeof(Vector64)) + { + result = (TVectorUInt32)(object)Vector64.ShiftLeft( + (Vector64)(object)vector, + (Vector64)(object)shiftAmount + ); + } + else if (typeof(TVectorUInt32) == typeof(Vector128)) + { + result = (TVectorUInt32)(object)Vector128.ShiftLeft( + (Vector128)(object)vector, + (Vector128)(object)shiftAmount + ); + } + else if (typeof(TVectorUInt32) == typeof(Vector256)) + { + result = (TVectorUInt32)(object)Vector256.ShiftLeft( + (Vector256)(object)vector, + (Vector256)(object)shiftAmount + ); + } + else if (typeof(TVectorUInt32) == typeof(Vector512)) + { + result = (TVectorUInt32)(object)Vector512.ShiftLeft( + (Vector512)(object)vector, + (Vector512)(object)shiftAmount + ); + } + else + { + ThrowHelper.ThrowNotSupportedException(); + } + + return result; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static TVectorUInt64 ShiftLeftUInt64(TVectorUInt64 vector, TVectorUInt64 shiftAmount) + where TVectorUInt64 : unmanaged, ISimdVector + { + Unsafe.SkipInit(out TVectorUInt64 result); + + if (typeof(TVectorUInt64) == typeof(Vector)) + { + result = (TVectorUInt64)(object)Vector.ShiftLeft( + (Vector)(object)vector, + (Vector)(object)shiftAmount + ); + } + else if (typeof(TVectorUInt64) == typeof(Vector64)) + { + result = (TVectorUInt64)(object)Vector64.ShiftLeft( + (Vector64)(object)vector, + (Vector64)(object)shiftAmount + ); + } + else if (typeof(TVectorUInt64) == typeof(Vector128)) + { + result = (TVectorUInt64)(object)Vector128.ShiftLeft( + (Vector128)(object)vector, + (Vector128)(object)shiftAmount + ); + } + else if (typeof(TVectorUInt64) == typeof(Vector256)) + { + result = (TVectorUInt64)(object)Vector256.ShiftLeft( + (Vector256)(object)vector, + (Vector256)(object)shiftAmount + ); + } + else if (typeof(TVectorUInt64) == typeof(Vector512)) + { + result = (TVectorUInt64)(object)Vector512.ShiftLeft( + (Vector512)(object)vector, + (Vector512)(object)shiftAmount + ); + } + else + { + ThrowHelper.ThrowNotSupportedException(); + } + + return result; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static TVectorDouble SinDoubleLarge(TVectorDouble r, TVectorDouble rr) where TVectorDouble : unmanaged, ISimdVector diff --git a/src/libraries/System.Private.CoreLib/src/System/Single.cs b/src/libraries/System.Private.CoreLib/src/System/Single.cs index 28c545a65a628b..38b9b389f7d9c3 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Single.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Single.cs @@ -177,8 +177,8 @@ public static bool IsFinite(float f) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsInfinity(float f) { - uint bits = BitConverter.SingleToUInt32Bits(f); - return (bits & ~SignMask) == PositiveInfinityBits; + uint bits = BitConverter.SingleToUInt32Bits(Abs(f)); + return bits == PositiveInfinityBits; } /// Determines whether the specified value is NaN. @@ -224,8 +224,8 @@ public static bool IsNegativeInfinity(float f) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsNormal(float f) { - uint bits = BitConverter.SingleToUInt32Bits(f); - return ((bits & ~SignMask) - SmallestNormalBits) < (PositiveInfinityBits - SmallestNormalBits); + uint bits = BitConverter.SingleToUInt32Bits(Abs(f)); + return (bits - SmallestNormalBits) < (PositiveInfinityBits - SmallestNormalBits); } /// Determines whether the specified value is positive infinity. @@ -242,8 +242,8 @@ public static bool IsPositiveInfinity(float f) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsSubnormal(float f) { - uint bits = BitConverter.SingleToUInt32Bits(f); - return ((bits & ~SignMask) - 1) < MaxTrailingSignificand; + uint bits = BitConverter.SingleToUInt32Bits(Abs(f)); + return (bits - 1) < MaxTrailingSignificand; } [NonVersionable] @@ -938,7 +938,24 @@ bool IFloatingPoint.TryWriteSignificandLittleEndian(Span destinatio // /// - public static float Clamp(float value, float min, float max) => Math.Clamp(value, min, max); + public static float Clamp(float value, float min, float max) + { + if (min > max) + { + Math.ThrowMinMaxException(min, max); + } + return Min(Max(value, min), max); + } + + /// + public static float ClampNative(float value, float min, float max) + { + if (min > max) + { + Math.ThrowMinMaxException(min, max); + } + return MinNative(MaxNative(value, min), max); + } /// public static float CopySign(float value, float sign) => MathF.CopySign(value, sign); @@ -947,6 +964,10 @@ bool IFloatingPoint.TryWriteSignificandLittleEndian(Span destinatio [Intrinsic] public static float Max(float x, float y) => MathF.Max(x, y); + /// + [Intrinsic] + public static float MaxNative(float x, float y) => (x > y) ? x : y; + /// [Intrinsic] public static float MaxNumber(float x, float y) @@ -974,6 +995,10 @@ public static float MaxNumber(float x, float y) [Intrinsic] public static float Min(float x, float y) => MathF.Min(x, y); + /// + [Intrinsic] + public static float MinNative(float x, float y) => (x < y) ? x : y; + /// [Intrinsic] public static float MinNumber(float x, float y) @@ -1081,7 +1106,27 @@ public static float CreateTruncating(TOther value) static bool INumberBase.IsComplexNumber(float value) => false; /// - public static bool IsEvenInteger(float value) => IsInteger(value) && (Abs(value % 2) == 0); + public static bool IsEvenInteger(float value) + { + uint bits = BitConverter.SingleToUInt32Bits(Abs(value)); + + if (bits < 0x3F80_0000) + { + return bits == 0; + } + + if (bits >= 0x4B80_0000) + { + return bits < 0x7F80_0000; + } + + uint exponent = ((bits >> 23) & 0xFF) - 127; + uint fractionalBits = 23 - exponent; + uint firstIntegerBit = 1u << (int)fractionalBits; + uint fractionalBitMask = firstIntegerBit - 1; + + return ((bits & fractionalBitMask) == 0) && ((bits & firstIntegerBit) == 0); + } /// static bool INumberBase.IsImaginaryNumber(float value) => false; diff --git a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.T.cs b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.T.cs index 0d61e3b662da7a..fb8e18ac2d16b8 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.T.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.T.cs @@ -2506,7 +2506,7 @@ static int SimdImpl(ref TValue searchSpace, TValue value, int length) TVector current; TVector values = TVector.Create(value); - int offset = length - TVector.Count; + int offset = length - TVector.ElementCount; // Loop until either we've finished all elements -or- there's one or less than a vector's-worth remaining. while (offset > 0) @@ -2515,10 +2515,10 @@ static int SimdImpl(ref TValue searchSpace, TValue value, int length) if (TNegator.HasMatch(values, current)) { - return offset + TVector.IndexOfLastMatch(TNegator.GetMatchMask(values, current)); + return offset + TVector.LastIndexOfWhereAllBitsSet(TNegator.GetMatchMask(values, current)); } - offset -= TVector.Count; + offset -= TVector.ElementCount; } // Process the first vector in the search space. @@ -2527,7 +2527,7 @@ static int SimdImpl(ref TValue searchSpace, TValue value, int length) if (TNegator.HasMatch(values, current)) { - return TVector.IndexOfLastMatch(TNegator.GetMatchMask(values, current)); + return TVector.LastIndexOfWhereAllBitsSet(TNegator.GetMatchMask(values, current)); } return -1; diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/Ascii.Utility.cs b/src/libraries/System.Private.CoreLib/src/System/Text/Ascii.Utility.cs index 580550467fe589..2d337d0fb41697 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/Ascii.Utility.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/Ascii.Utility.cs @@ -2167,14 +2167,14 @@ private static unsafe void WidenAsciiToUtf1_Vector(b // Calculating the destination address outside the loop results in significant // perf wins vs. relying on the JIT to fold memory addressing logic into the // write instructions. See: https://github.com/dotnet/runtime/issues/33002 - nuint finalOffsetWhereCanRunLoop = elementCount - (nuint)TVectorByte.Count; + nuint finalOffsetWhereCanRunLoop = elementCount - (nuint)TVectorByte.ElementCount; TVectorByte asciiVector = TVectorByte.Load(pAsciiBuffer + currentOffset); if (!HasMatch(asciiVector)) { (TVectorUInt16 utf16LowVector, TVectorUInt16 utf16HighVector) = Widen(asciiVector); utf16LowVector.Store(pCurrentWriteAddress); - utf16HighVector.Store(pCurrentWriteAddress + TVectorUInt16.Count); - pCurrentWriteAddress += (nuint)(TVectorUInt16.Count * 2); + utf16HighVector.Store(pCurrentWriteAddress + TVectorUInt16.ElementCount); + pCurrentWriteAddress += (nuint)(TVectorUInt16.ElementCount * 2); if (((nuint)pCurrentWriteAddress % sizeof(char)) == 0) { // Bump write buffer up to the next aligned boundary @@ -2185,7 +2185,7 @@ private static unsafe void WidenAsciiToUtf1_Vector(b else { // If input isn't char aligned, we won't be able to align it to a Vector - currentOffset += (nuint)TVectorByte.Count; + currentOffset += (nuint)TVectorByte.ElementCount; } while (currentOffset <= finalOffsetWhereCanRunLoop) { @@ -2196,10 +2196,10 @@ private static unsafe void WidenAsciiToUtf1_Vector(b } (utf16LowVector, utf16HighVector) = Widen(asciiVector); utf16LowVector.Store(pCurrentWriteAddress); - utf16HighVector.Store(pCurrentWriteAddress + TVectorUInt16.Count); + utf16HighVector.Store(pCurrentWriteAddress + TVectorUInt16.ElementCount); - currentOffset += (nuint)TVectorByte.Count; - pCurrentWriteAddress += (nuint)(TVectorUInt16.Count * 2); + currentOffset += (nuint)TVectorByte.ElementCount; + pCurrentWriteAddress += (nuint)(TVectorUInt16.ElementCount * 2); } } return; diff --git a/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs b/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs index bbca9ddf8ec3cf..4fa55777f5327c 100644 --- a/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs +++ b/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs @@ -1343,6 +1343,7 @@ public static void Free(void* ptr) { } public static System.Runtime.InteropServices.NFloat Cbrt(System.Runtime.InteropServices.NFloat x) { throw null; } public static System.Runtime.InteropServices.NFloat Ceiling(System.Runtime.InteropServices.NFloat x) { throw null; } public static System.Runtime.InteropServices.NFloat Clamp(System.Runtime.InteropServices.NFloat value, System.Runtime.InteropServices.NFloat min, System.Runtime.InteropServices.NFloat max) { throw null; } + public static System.Runtime.InteropServices.NFloat ClampNative(System.Runtime.InteropServices.NFloat value, System.Runtime.InteropServices.NFloat min, System.Runtime.InteropServices.NFloat max) { throw null; } public int CompareTo(object? obj) { throw null; } public int CompareTo(System.Runtime.InteropServices.NFloat other) { throw null; } public static TInteger ConvertToInteger(System.Runtime.InteropServices.NFloat value) where TInteger : System.Numerics.IBinaryInteger { throw null; } @@ -1394,10 +1395,12 @@ public static void Free(void* ptr) { } public static System.Runtime.InteropServices.NFloat Max(System.Runtime.InteropServices.NFloat x, System.Runtime.InteropServices.NFloat y) { throw null; } public static System.Runtime.InteropServices.NFloat MaxMagnitude(System.Runtime.InteropServices.NFloat x, System.Runtime.InteropServices.NFloat y) { throw null; } public static System.Runtime.InteropServices.NFloat MaxMagnitudeNumber(System.Runtime.InteropServices.NFloat x, System.Runtime.InteropServices.NFloat y) { throw null; } + public static System.Runtime.InteropServices.NFloat MaxNative(System.Runtime.InteropServices.NFloat x, System.Runtime.InteropServices.NFloat y) { throw null; } public static System.Runtime.InteropServices.NFloat MaxNumber(System.Runtime.InteropServices.NFloat x, System.Runtime.InteropServices.NFloat y) { throw null; } public static System.Runtime.InteropServices.NFloat Min(System.Runtime.InteropServices.NFloat x, System.Runtime.InteropServices.NFloat y) { throw null; } public static System.Runtime.InteropServices.NFloat MinMagnitude(System.Runtime.InteropServices.NFloat x, System.Runtime.InteropServices.NFloat y) { throw null; } public static System.Runtime.InteropServices.NFloat MinMagnitudeNumber(System.Runtime.InteropServices.NFloat x, System.Runtime.InteropServices.NFloat y) { throw null; } + public static System.Runtime.InteropServices.NFloat MinNative(System.Runtime.InteropServices.NFloat x, System.Runtime.InteropServices.NFloat y) { throw null; } public static System.Runtime.InteropServices.NFloat MinNumber(System.Runtime.InteropServices.NFloat x, System.Runtime.InteropServices.NFloat y) { throw null; } public static System.Runtime.InteropServices.NFloat MultiplyAddEstimate(System.Runtime.InteropServices.NFloat left, System.Runtime.InteropServices.NFloat right, System.Runtime.InteropServices.NFloat addend) { throw null; } public static System.Runtime.InteropServices.NFloat operator +(System.Runtime.InteropServices.NFloat left, System.Runtime.InteropServices.NFloat right) { throw null; } 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 20aae5b67f0e70..1da0bf8ed49588 100644 --- a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs +++ b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs @@ -13,7 +13,11 @@ public static partial class Vector128 public static bool IsHardwareAccelerated { get { throw null; } } public static System.Runtime.Intrinsics.Vector128 Abs(System.Runtime.Intrinsics.Vector128 vector) { throw null; } public static System.Runtime.Intrinsics.Vector128 Add(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static bool All(System.Runtime.Intrinsics.Vector128 vector, T value) { throw null; } + public static bool AllWhereAllBitsSet(System.Runtime.Intrinsics.Vector128 vector) { throw null; } public static System.Runtime.Intrinsics.Vector128 AndNot(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static bool Any(System.Runtime.Intrinsics.Vector128 vector, T value) { throw null; } + public static bool AnyWhereAllBitsSet(System.Runtime.Intrinsics.Vector128 vector) { throw null; } public static System.Runtime.Intrinsics.Vector128 AsByte(this System.Runtime.Intrinsics.Vector128 vector) { throw null; } public static System.Runtime.Intrinsics.Vector128 AsDouble(this System.Runtime.Intrinsics.Vector128 vector) { throw null; } public static System.Runtime.Intrinsics.Vector128 AsInt16(this System.Runtime.Intrinsics.Vector128 vector) { throw null; } @@ -73,6 +77,8 @@ public static void CopyTo(this System.Runtime.Intrinsics.Vector128 vector, public static void CopyTo(this System.Runtime.Intrinsics.Vector128 vector, T[] destination, int startIndex) { } public static System.Runtime.Intrinsics.Vector128 Cos(System.Runtime.Intrinsics.Vector128 vector) { throw null; } public static System.Runtime.Intrinsics.Vector128 Cos(System.Runtime.Intrinsics.Vector128 vector) { throw null; } + public static int Count(System.Runtime.Intrinsics.Vector128 vector, T value) { throw null; } + public static int CountWhereAllBitsSet(System.Runtime.Intrinsics.Vector128 vector) { throw null; } public static System.Runtime.Intrinsics.Vector128 Create(byte value) { throw null; } public static System.Runtime.Intrinsics.Vector128 Create(byte e0, byte e1, byte e2, byte e3, byte e4, byte e5, byte e6, byte e7, byte e8, byte e9, byte e10, byte e11, byte e12, byte e13, byte e14, byte e15) { throw null; } public static System.Runtime.Intrinsics.Vector128 Create(double value) { throw null; } @@ -191,11 +197,23 @@ public static void CopyTo(this System.Runtime.Intrinsics.Vector128 vector, public static System.Runtime.Intrinsics.Vector128 GreaterThan(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } public static System.Runtime.Intrinsics.Vector128 Hypot(System.Runtime.Intrinsics.Vector128 x, System.Runtime.Intrinsics.Vector128 y) { throw null; } public static System.Runtime.Intrinsics.Vector128 Hypot(System.Runtime.Intrinsics.Vector128 x, System.Runtime.Intrinsics.Vector128 y) { throw null; } + public static int IndexOf(System.Runtime.Intrinsics.Vector128 vector, T value) { throw null; } + public static int IndexOfWhereAllBitsSet(System.Runtime.Intrinsics.Vector128 vector) { throw null; } + public static System.Runtime.Intrinsics.Vector128 IsEvenInteger(System.Runtime.Intrinsics.Vector128 vector) { throw null; } + public static System.Runtime.Intrinsics.Vector128 IsFinite(System.Runtime.Intrinsics.Vector128 vector) { throw null; } + public static System.Runtime.Intrinsics.Vector128 IsInfinity(System.Runtime.Intrinsics.Vector128 vector) { throw null; } + public static System.Runtime.Intrinsics.Vector128 IsInteger(System.Runtime.Intrinsics.Vector128 vector) { throw null; } public static System.Runtime.Intrinsics.Vector128 IsNaN(System.Runtime.Intrinsics.Vector128 vector) { throw null; } public static System.Runtime.Intrinsics.Vector128 IsNegative(System.Runtime.Intrinsics.Vector128 vector) { throw null; } + public static System.Runtime.Intrinsics.Vector128 IsNegativeInfinity(System.Runtime.Intrinsics.Vector128 vector) { throw null; } + public static System.Runtime.Intrinsics.Vector128 IsNormal(System.Runtime.Intrinsics.Vector128 vector) { throw null; } + public static System.Runtime.Intrinsics.Vector128 IsOddInteger(System.Runtime.Intrinsics.Vector128 vector) { throw null; } public static System.Runtime.Intrinsics.Vector128 IsPositive(System.Runtime.Intrinsics.Vector128 vector) { throw null; } public static System.Runtime.Intrinsics.Vector128 IsPositiveInfinity(System.Runtime.Intrinsics.Vector128 vector) { throw null; } + public static System.Runtime.Intrinsics.Vector128 IsSubnormal(System.Runtime.Intrinsics.Vector128 vector) { throw null; } public static System.Runtime.Intrinsics.Vector128 IsZero(System.Runtime.Intrinsics.Vector128 vector) { throw null; } + public static int LastIndexOf(System.Runtime.Intrinsics.Vector128 vector, T value) { throw null; } + public static int LastIndexOfWhereAllBitsSet(System.Runtime.Intrinsics.Vector128 vector) { throw null; } public static System.Runtime.Intrinsics.Vector128 Lerp(System.Runtime.Intrinsics.Vector128 x, System.Runtime.Intrinsics.Vector128 y, System.Runtime.Intrinsics.Vector128 amount) { throw null; } public static System.Runtime.Intrinsics.Vector128 Lerp(System.Runtime.Intrinsics.Vector128 x, System.Runtime.Intrinsics.Vector128 y, System.Runtime.Intrinsics.Vector128 amount) { throw null; } public static bool LessThanAll(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } @@ -244,6 +262,8 @@ public static void CopyTo(this System.Runtime.Intrinsics.Vector128 vector, [System.CLSCompliantAttribute(false)] public static System.Runtime.Intrinsics.Vector128 Narrow(System.Runtime.Intrinsics.Vector128 lower, System.Runtime.Intrinsics.Vector128 upper) { throw null; } public static System.Runtime.Intrinsics.Vector128 Negate(System.Runtime.Intrinsics.Vector128 vector) { throw null; } + public static bool None(System.Runtime.Intrinsics.Vector128 vector, T value) { throw null; } + public static bool NoneWhereAllBitsSet(System.Runtime.Intrinsics.Vector128 vector) { throw null; } public static System.Runtime.Intrinsics.Vector128 OnesComplement(System.Runtime.Intrinsics.Vector128 vector) { throw null; } public static System.Runtime.Intrinsics.Vector128 RadiansToDegrees(System.Runtime.Intrinsics.Vector128 radians) { throw null; } public static System.Runtime.Intrinsics.Vector128 RadiansToDegrees(System.Runtime.Intrinsics.Vector128 radians) { throw null; } @@ -399,7 +419,11 @@ public static partial class Vector256 public static bool IsHardwareAccelerated { get { throw null; } } public static System.Runtime.Intrinsics.Vector256 Abs(System.Runtime.Intrinsics.Vector256 vector) { throw null; } public static System.Runtime.Intrinsics.Vector256 Add(System.Runtime.Intrinsics.Vector256 left, System.Runtime.Intrinsics.Vector256 right) { throw null; } + public static bool All(System.Runtime.Intrinsics.Vector256 vector, T value) { throw null; } + public static bool AllWhereAllBitsSet(System.Runtime.Intrinsics.Vector256 vector) { throw null; } public static System.Runtime.Intrinsics.Vector256 AndNot(System.Runtime.Intrinsics.Vector256 left, System.Runtime.Intrinsics.Vector256 right) { throw null; } + public static bool Any(System.Runtime.Intrinsics.Vector256 vector, T value) { throw null; } + public static bool AnyWhereAllBitsSet(System.Runtime.Intrinsics.Vector256 vector) { throw null; } public static System.Runtime.Intrinsics.Vector256 AsByte(this System.Runtime.Intrinsics.Vector256 vector) { throw null; } public static System.Runtime.Intrinsics.Vector256 AsDouble(this System.Runtime.Intrinsics.Vector256 vector) { throw null; } public static System.Runtime.Intrinsics.Vector256 AsInt16(this System.Runtime.Intrinsics.Vector256 vector) { throw null; } @@ -451,6 +475,8 @@ public static void CopyTo(this System.Runtime.Intrinsics.Vector256 vector, public static void CopyTo(this System.Runtime.Intrinsics.Vector256 vector, T[] destination, int startIndex) { } public static System.Runtime.Intrinsics.Vector256 Cos(System.Runtime.Intrinsics.Vector256 vector) { throw null; } public static System.Runtime.Intrinsics.Vector256 Cos(System.Runtime.Intrinsics.Vector256 vector) { throw null; } + public static int Count(System.Runtime.Intrinsics.Vector256 vector, T value) { throw null; } + public static int CountWhereAllBitsSet(System.Runtime.Intrinsics.Vector256 vector) { throw null; } public static System.Runtime.Intrinsics.Vector256 Create(byte value) { throw null; } public static System.Runtime.Intrinsics.Vector256 Create(byte e0, byte e1, byte e2, byte e3, byte e4, byte e5, byte e6, byte e7, byte e8, byte e9, byte e10, byte e11, byte e12, byte e13, byte e14, byte e15, byte e16, byte e17, byte e18, byte e19, byte e20, byte e21, byte e22, byte e23, byte e24, byte e25, byte e26, byte e27, byte e28, byte e29, byte e30, byte e31) { throw null; } public static System.Runtime.Intrinsics.Vector256 Create(double value) { throw null; } @@ -570,11 +596,23 @@ public static void CopyTo(this System.Runtime.Intrinsics.Vector256 vector, public static System.Runtime.Intrinsics.Vector256 GreaterThan(System.Runtime.Intrinsics.Vector256 left, System.Runtime.Intrinsics.Vector256 right) { throw null; } public static System.Runtime.Intrinsics.Vector256 Hypot(System.Runtime.Intrinsics.Vector256 x, System.Runtime.Intrinsics.Vector256 y) { throw null; } public static System.Runtime.Intrinsics.Vector256 Hypot(System.Runtime.Intrinsics.Vector256 x, System.Runtime.Intrinsics.Vector256 y) { throw null; } + public static int IndexOf(System.Runtime.Intrinsics.Vector256 vector, T value) { throw null; } + public static int IndexOfWhereAllBitsSet(System.Runtime.Intrinsics.Vector256 vector) { throw null; } + public static System.Runtime.Intrinsics.Vector256 IsEvenInteger(System.Runtime.Intrinsics.Vector256 vector) { throw null; } + public static System.Runtime.Intrinsics.Vector256 IsFinite(System.Runtime.Intrinsics.Vector256 vector) { throw null; } + public static System.Runtime.Intrinsics.Vector256 IsInfinity(System.Runtime.Intrinsics.Vector256 vector) { throw null; } + public static System.Runtime.Intrinsics.Vector256 IsInteger(System.Runtime.Intrinsics.Vector256 vector) { throw null; } public static System.Runtime.Intrinsics.Vector256 IsNaN(System.Runtime.Intrinsics.Vector256 vector) { throw null; } public static System.Runtime.Intrinsics.Vector256 IsNegative(System.Runtime.Intrinsics.Vector256 vector) { throw null; } + public static System.Runtime.Intrinsics.Vector256 IsNegativeInfinity(System.Runtime.Intrinsics.Vector256 vector) { throw null; } + public static System.Runtime.Intrinsics.Vector256 IsNormal(System.Runtime.Intrinsics.Vector256 vector) { throw null; } + public static System.Runtime.Intrinsics.Vector256 IsOddInteger(System.Runtime.Intrinsics.Vector256 vector) { throw null; } public static System.Runtime.Intrinsics.Vector256 IsPositive(System.Runtime.Intrinsics.Vector256 vector) { throw null; } public static System.Runtime.Intrinsics.Vector256 IsPositiveInfinity(System.Runtime.Intrinsics.Vector256 vector) { throw null; } + public static System.Runtime.Intrinsics.Vector256 IsSubnormal(System.Runtime.Intrinsics.Vector256 vector) { throw null; } public static System.Runtime.Intrinsics.Vector256 IsZero(System.Runtime.Intrinsics.Vector256 vector) { throw null; } + public static int LastIndexOf(System.Runtime.Intrinsics.Vector256 vector, T value) { throw null; } + public static int LastIndexOfWhereAllBitsSet(System.Runtime.Intrinsics.Vector256 vector) { throw null; } public static System.Runtime.Intrinsics.Vector256 Lerp(System.Runtime.Intrinsics.Vector256 x, System.Runtime.Intrinsics.Vector256 y, System.Runtime.Intrinsics.Vector256 amount) { throw null; } public static System.Runtime.Intrinsics.Vector256 Lerp(System.Runtime.Intrinsics.Vector256 x, System.Runtime.Intrinsics.Vector256 y, System.Runtime.Intrinsics.Vector256 amount) { throw null; } public static bool LessThanAll(System.Runtime.Intrinsics.Vector256 left, System.Runtime.Intrinsics.Vector256 right) { throw null; } @@ -623,6 +661,8 @@ public static void CopyTo(this System.Runtime.Intrinsics.Vector256 vector, [System.CLSCompliantAttribute(false)] public static System.Runtime.Intrinsics.Vector256 Narrow(System.Runtime.Intrinsics.Vector256 lower, System.Runtime.Intrinsics.Vector256 upper) { throw null; } public static System.Runtime.Intrinsics.Vector256 Negate(System.Runtime.Intrinsics.Vector256 vector) { throw null; } + public static bool None(System.Runtime.Intrinsics.Vector256 vector, T value) { throw null; } + public static bool NoneWhereAllBitsSet(System.Runtime.Intrinsics.Vector256 vector) { throw null; } public static System.Runtime.Intrinsics.Vector256 OnesComplement(System.Runtime.Intrinsics.Vector256 vector) { throw null; } public static System.Runtime.Intrinsics.Vector256 RadiansToDegrees(System.Runtime.Intrinsics.Vector256 radians) { throw null; } public static System.Runtime.Intrinsics.Vector256 RadiansToDegrees(System.Runtime.Intrinsics.Vector256 radians) { throw null; } @@ -778,7 +818,11 @@ public static partial class Vector512 public static bool IsHardwareAccelerated { get { throw null; } } public static System.Runtime.Intrinsics.Vector512 Abs(System.Runtime.Intrinsics.Vector512 vector) { throw null; } public static System.Runtime.Intrinsics.Vector512 Add(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } + public static bool All(System.Runtime.Intrinsics.Vector512 vector, T value) { throw null; } + public static bool AllWhereAllBitsSet(System.Runtime.Intrinsics.Vector512 vector) { throw null; } public static System.Runtime.Intrinsics.Vector512 AndNot(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } + public static bool Any(System.Runtime.Intrinsics.Vector512 vector, T value) { throw null; } + public static bool AnyWhereAllBitsSet(System.Runtime.Intrinsics.Vector512 vector) { throw null; } public static System.Runtime.Intrinsics.Vector512 AsByte(this System.Runtime.Intrinsics.Vector512 vector) { throw null; } public static System.Runtime.Intrinsics.Vector512 AsDouble(this System.Runtime.Intrinsics.Vector512 vector) { throw null; } public static System.Runtime.Intrinsics.Vector512 AsInt16(this System.Runtime.Intrinsics.Vector512 vector) { throw null; } @@ -830,6 +874,8 @@ public static void CopyTo(this System.Runtime.Intrinsics.Vector512 vector, public static void CopyTo(this System.Runtime.Intrinsics.Vector512 vector, T[] destination, int startIndex) { } public static System.Runtime.Intrinsics.Vector512 Cos(System.Runtime.Intrinsics.Vector512 vector) { throw null; } public static System.Runtime.Intrinsics.Vector512 Cos(System.Runtime.Intrinsics.Vector512 vector) { throw null; } + public static int Count(System.Runtime.Intrinsics.Vector512 vector, T value) { throw null; } + public static int CountWhereAllBitsSet(System.Runtime.Intrinsics.Vector512 vector) { throw null; } public static System.Runtime.Intrinsics.Vector512 Create(byte value) { throw null; } public static System.Runtime.Intrinsics.Vector512 Create(byte e0, byte e1, byte e2, byte e3, byte e4, byte e5, byte e6, byte e7, byte e8, byte e9, byte e10, byte e11, byte e12, byte e13, byte e14, byte e15, byte e16, byte e17, byte e18, byte e19, byte e20, byte e21, byte e22, byte e23, byte e24, byte e25, byte e26, byte e27, byte e28, byte e29, byte e30, byte e31, byte e32, byte e33, byte e34, byte e35, byte e36, byte e37, byte e38, byte e39, byte e40, byte e41, byte e42, byte e43, byte e44, byte e45, byte e46, byte e47, byte e48, byte e49, byte e50, byte e51, byte e52, byte e53, byte e54, byte e55, byte e56, byte e57, byte e58, byte e59, byte e60, byte e61, byte e62, byte e63) { throw null; } public static System.Runtime.Intrinsics.Vector512 Create(double value) { throw null; } @@ -950,11 +996,23 @@ public static void CopyTo(this System.Runtime.Intrinsics.Vector512 vector, public static System.Runtime.Intrinsics.Vector512 GreaterThan(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } public static System.Runtime.Intrinsics.Vector512 Hypot(System.Runtime.Intrinsics.Vector512 x, System.Runtime.Intrinsics.Vector512 y) { throw null; } public static System.Runtime.Intrinsics.Vector512 Hypot(System.Runtime.Intrinsics.Vector512 x, System.Runtime.Intrinsics.Vector512 y) { throw null; } + public static int IndexOf(System.Runtime.Intrinsics.Vector512 vector, T value) { throw null; } + public static int IndexOfWhereAllBitsSet(System.Runtime.Intrinsics.Vector512 vector) { throw null; } + public static System.Runtime.Intrinsics.Vector512 IsEvenInteger(System.Runtime.Intrinsics.Vector512 vector) { throw null; } + public static System.Runtime.Intrinsics.Vector512 IsFinite(System.Runtime.Intrinsics.Vector512 vector) { throw null; } + public static System.Runtime.Intrinsics.Vector512 IsInfinity(System.Runtime.Intrinsics.Vector512 vector) { throw null; } + public static System.Runtime.Intrinsics.Vector512 IsInteger(System.Runtime.Intrinsics.Vector512 vector) { throw null; } public static System.Runtime.Intrinsics.Vector512 IsNaN(System.Runtime.Intrinsics.Vector512 vector) { throw null; } public static System.Runtime.Intrinsics.Vector512 IsNegative(System.Runtime.Intrinsics.Vector512 vector) { throw null; } + public static System.Runtime.Intrinsics.Vector512 IsNegativeInfinity(System.Runtime.Intrinsics.Vector512 vector) { throw null; } + public static System.Runtime.Intrinsics.Vector512 IsNormal(System.Runtime.Intrinsics.Vector512 vector) { throw null; } + public static System.Runtime.Intrinsics.Vector512 IsOddInteger(System.Runtime.Intrinsics.Vector512 vector) { throw null; } public static System.Runtime.Intrinsics.Vector512 IsPositive(System.Runtime.Intrinsics.Vector512 vector) { throw null; } public static System.Runtime.Intrinsics.Vector512 IsPositiveInfinity(System.Runtime.Intrinsics.Vector512 vector) { throw null; } + public static System.Runtime.Intrinsics.Vector512 IsSubnormal(System.Runtime.Intrinsics.Vector512 vector) { throw null; } public static System.Runtime.Intrinsics.Vector512 IsZero(System.Runtime.Intrinsics.Vector512 vector) { throw null; } + public static int LastIndexOf(System.Runtime.Intrinsics.Vector512 vector, T value) { throw null; } + public static int LastIndexOfWhereAllBitsSet(System.Runtime.Intrinsics.Vector512 vector) { throw null; } public static System.Runtime.Intrinsics.Vector512 Lerp(System.Runtime.Intrinsics.Vector512 x, System.Runtime.Intrinsics.Vector512 y, System.Runtime.Intrinsics.Vector512 amount) { throw null; } public static System.Runtime.Intrinsics.Vector512 Lerp(System.Runtime.Intrinsics.Vector512 x, System.Runtime.Intrinsics.Vector512 y, System.Runtime.Intrinsics.Vector512 amount) { throw null; } public static bool LessThanAll(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } @@ -1003,6 +1061,8 @@ public static void CopyTo(this System.Runtime.Intrinsics.Vector512 vector, [System.CLSCompliantAttribute(false)] public static System.Runtime.Intrinsics.Vector512 Narrow(System.Runtime.Intrinsics.Vector512 lower, System.Runtime.Intrinsics.Vector512 upper) { throw null; } public static System.Runtime.Intrinsics.Vector512 Negate(System.Runtime.Intrinsics.Vector512 vector) { throw null; } + public static bool None(System.Runtime.Intrinsics.Vector512 vector, T value) { throw null; } + public static bool NoneWhereAllBitsSet(System.Runtime.Intrinsics.Vector512 vector) { throw null; } public static System.Runtime.Intrinsics.Vector512 OnesComplement(System.Runtime.Intrinsics.Vector512 vector) { throw null; } public static System.Runtime.Intrinsics.Vector512 RadiansToDegrees(System.Runtime.Intrinsics.Vector512 radians) { throw null; } public static System.Runtime.Intrinsics.Vector512 RadiansToDegrees(System.Runtime.Intrinsics.Vector512 radians) { throw null; } @@ -1156,7 +1216,11 @@ public static partial class Vector64 public static bool IsHardwareAccelerated { get { throw null; } } public static System.Runtime.Intrinsics.Vector64 Abs(System.Runtime.Intrinsics.Vector64 vector) { throw null; } public static System.Runtime.Intrinsics.Vector64 Add(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } + public static bool All(System.Runtime.Intrinsics.Vector64 vector, T value) { throw null; } + public static bool AllWhereAllBitsSet(System.Runtime.Intrinsics.Vector64 vector) { throw null; } public static System.Runtime.Intrinsics.Vector64 AndNot(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } + public static bool Any(System.Runtime.Intrinsics.Vector64 vector, T value) { throw null; } + public static bool AnyWhereAllBitsSet(System.Runtime.Intrinsics.Vector64 vector) { throw null; } public static System.Runtime.Intrinsics.Vector64 AsByte(this System.Runtime.Intrinsics.Vector64 vector) { throw null; } public static System.Runtime.Intrinsics.Vector64 AsDouble(this System.Runtime.Intrinsics.Vector64 vector) { throw null; } public static System.Runtime.Intrinsics.Vector64 AsInt16(this System.Runtime.Intrinsics.Vector64 vector) { throw null; } @@ -1206,6 +1270,8 @@ public static void CopyTo(this System.Runtime.Intrinsics.Vector64 vector, public static void CopyTo(this System.Runtime.Intrinsics.Vector64 vector, T[] destination, int startIndex) { } public static System.Runtime.Intrinsics.Vector64 Cos(System.Runtime.Intrinsics.Vector64 vector) { throw null; } public static System.Runtime.Intrinsics.Vector64 Cos(System.Runtime.Intrinsics.Vector64 vector) { throw null; } + public static int Count(System.Runtime.Intrinsics.Vector64 vector, T value) { throw null; } + public static int CountWhereAllBitsSet(System.Runtime.Intrinsics.Vector64 vector) { throw null; } public static System.Runtime.Intrinsics.Vector64 Create(byte value) { throw null; } public static System.Runtime.Intrinsics.Vector64 Create(byte e0, byte e1, byte e2, byte e3, byte e4, byte e5, byte e6, byte e7) { throw null; } public static System.Runtime.Intrinsics.Vector64 Create(double value) { throw null; } @@ -1299,11 +1365,23 @@ public static void CopyTo(this System.Runtime.Intrinsics.Vector64 vector, public static System.Runtime.Intrinsics.Vector64 GreaterThan(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } public static System.Runtime.Intrinsics.Vector64 Hypot(System.Runtime.Intrinsics.Vector64 x, System.Runtime.Intrinsics.Vector64 y) { throw null; } public static System.Runtime.Intrinsics.Vector64 Hypot(System.Runtime.Intrinsics.Vector64 x, System.Runtime.Intrinsics.Vector64 y) { throw null; } + public static int IndexOf(System.Runtime.Intrinsics.Vector64 vector, T value) { throw null; } + public static int IndexOfWhereAllBitsSet(System.Runtime.Intrinsics.Vector64 vector) { throw null; } + public static System.Runtime.Intrinsics.Vector64 IsEvenInteger(System.Runtime.Intrinsics.Vector64 vector) { throw null; } + public static System.Runtime.Intrinsics.Vector64 IsFinite(System.Runtime.Intrinsics.Vector64 vector) { throw null; } + public static System.Runtime.Intrinsics.Vector64 IsInfinity(System.Runtime.Intrinsics.Vector64 vector) { throw null; } + public static System.Runtime.Intrinsics.Vector64 IsInteger(System.Runtime.Intrinsics.Vector64 vector) { throw null; } public static System.Runtime.Intrinsics.Vector64 IsNaN(System.Runtime.Intrinsics.Vector64 vector) { throw null; } public static System.Runtime.Intrinsics.Vector64 IsNegative(System.Runtime.Intrinsics.Vector64 vector) { throw null; } + public static System.Runtime.Intrinsics.Vector64 IsNegativeInfinity(System.Runtime.Intrinsics.Vector64 vector) { throw null; } + public static System.Runtime.Intrinsics.Vector64 IsNormal(System.Runtime.Intrinsics.Vector64 vector) { throw null; } + public static System.Runtime.Intrinsics.Vector64 IsOddInteger(System.Runtime.Intrinsics.Vector64 vector) { throw null; } public static System.Runtime.Intrinsics.Vector64 IsPositive(System.Runtime.Intrinsics.Vector64 vector) { throw null; } public static System.Runtime.Intrinsics.Vector64 IsPositiveInfinity(System.Runtime.Intrinsics.Vector64 vector) { throw null; } + public static System.Runtime.Intrinsics.Vector64 IsSubnormal(System.Runtime.Intrinsics.Vector64 vector) { throw null; } public static System.Runtime.Intrinsics.Vector64 IsZero(System.Runtime.Intrinsics.Vector64 vector) { throw null; } + public static int LastIndexOf(System.Runtime.Intrinsics.Vector64 vector, T value) { throw null; } + public static int LastIndexOfWhereAllBitsSet(System.Runtime.Intrinsics.Vector64 vector) { throw null; } public static System.Runtime.Intrinsics.Vector64 Lerp(System.Runtime.Intrinsics.Vector64 x, System.Runtime.Intrinsics.Vector64 y, System.Runtime.Intrinsics.Vector64 amount) { throw null; } public static System.Runtime.Intrinsics.Vector64 Lerp(System.Runtime.Intrinsics.Vector64 x, System.Runtime.Intrinsics.Vector64 y, System.Runtime.Intrinsics.Vector64 amount) { throw null; } public static bool LessThanAll(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } @@ -1352,6 +1430,8 @@ public static void CopyTo(this System.Runtime.Intrinsics.Vector64 vector, [System.CLSCompliantAttribute(false)] public static System.Runtime.Intrinsics.Vector64 Narrow(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector64 upper) { throw null; } public static System.Runtime.Intrinsics.Vector64 Negate(System.Runtime.Intrinsics.Vector64 vector) { throw null; } + public static bool None(System.Runtime.Intrinsics.Vector64 vector, T value) { throw null; } + public static bool NoneWhereAllBitsSet(System.Runtime.Intrinsics.Vector64 vector) { throw null; } public static System.Runtime.Intrinsics.Vector64 OnesComplement(System.Runtime.Intrinsics.Vector64 vector) { throw null; } public static System.Runtime.Intrinsics.Vector64 RadiansToDegrees(System.Runtime.Intrinsics.Vector64 radians) { throw null; } public static System.Runtime.Intrinsics.Vector64 RadiansToDegrees(System.Runtime.Intrinsics.Vector64 radians) { throw null; } diff --git a/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector128Tests.cs b/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector128Tests.cs index 09153068d91439..7163c17c8f8c17 100644 --- a/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector128Tests.cs +++ b/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector128Tests.cs @@ -4,6 +4,7 @@ using System.Diagnostics.CodeAnalysis; using System.Numerics; using System.Reflection; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Tests; using Xunit; @@ -4505,9 +4506,9 @@ public void Vector128DoubleEqualsNonCanonicalNaNTest() }; // all Vector NaNs .Equals compare the same, but == compare as different - foreach(var i in nans) + foreach (var i in nans) { - foreach(var j in nans) + foreach (var j in nans) { Assert.True(Vector128.Create(i).Equals(Vector128.Create(j))); Assert.False(Vector128.Create(i) == Vector128.Create(j)); @@ -4529,9 +4530,9 @@ public void Vector128SingleEqualsNonCanonicalNaNTest() }; // all Vector NaNs .Equals compare the same, but == compare as different - foreach(var i in nans) + foreach (var i in nans) { - foreach(var j in nans) + foreach (var j in nans) { Assert.True(Vector128.Create(i).Equals(Vector128.Create(j))); Assert.False(Vector128.Create(i) == Vector128.Create(j)); @@ -5066,76 +5067,604 @@ public void HypotSingleTest(float x, float y, float expectedResult, float varian AssertEqual(Vector128.Create(expectedResult), Vector128.Hypot(Vector128.Create(+y), Vector128.Create(+x)), Vector128.Create(variance)); } + private void IsEvenInteger(T value) + where T : INumber + { + Assert.Equal(T.IsEvenInteger(value) ? Vector128.AllBitsSet : Vector128.Zero, Vector128.IsEvenInteger(Vector128.Create(value))); + } + [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsNaNDouble), MemberType = typeof(GenericMathTestMemberData))] - public void IsNaNDoubleTest(double value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerByteTest(byte value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerDoubleTest(double value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerInt16Test(short value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerInt32Test(int value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerInt64Test(long value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerSByteTest(sbyte value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerSingleTest(float value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerUInt16Test(ushort value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerUInt32Test(uint value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerUInt64Test(ulong value) => IsEvenInteger(value); + + private void IsFinite(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector128.AllBitsSet : Vector128.Zero, Vector128.IsNaN(Vector128.Create(value))); + Assert.Equal(T.IsFinite(value) ? Vector128.AllBitsSet : Vector128.Zero, Vector128.IsFinite(Vector128.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsNaNSingle), MemberType = typeof(GenericMathTestMemberData))] - public void IsNaNSingleTest(float value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteByteTest(byte value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteDoubleTest(double value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteInt16Test(short value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteInt32Test(int value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteInt64Test(long value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteSByteTest(sbyte value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteSingleTest(float value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteUInt16Test(ushort value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteUInt32Test(uint value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteUInt64Test(ulong value) => IsFinite(value); + + private void IsInfinity(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector128.AllBitsSet : Vector128.Zero, Vector128.IsNaN(Vector128.Create(value))); + Assert.Equal(T.IsInfinity(value) ? Vector128.AllBitsSet : Vector128.Zero, Vector128.IsInfinity(Vector128.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsNegativeDouble), MemberType = typeof(GenericMathTestMemberData))] - public void IsNegativeDoubleTest(double value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityByteTest(byte value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityDoubleTest(double value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityInt16Test(short value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityInt32Test(int value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityInt64Test(long value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinitySByteTest(sbyte value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinitySingleTest(float value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityUInt16Test(ushort value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityUInt32Test(uint value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityUInt64Test(ulong value) => IsInfinity(value); + + private void IsInteger(T value) + where T : INumber + { + Assert.Equal(T.IsInteger(value) ? Vector128.AllBitsSet : Vector128.Zero, Vector128.IsInteger(Vector128.Create(value))); + } + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerByteTest(byte value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerDoubleTest(double value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerInt16Test(short value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerInt32Test(int value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerInt64Test(long value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerSByteTest(sbyte value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerSingleTest(float value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerUInt16Test(ushort value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerUInt32Test(uint value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerUInt64Test(ulong value) => IsInteger(value); + + private void IsNaN(T value) + where T : INumber + { + Assert.Equal(T.IsNaN(value) ? Vector128.AllBitsSet : Vector128.Zero, Vector128.IsNaN(Vector128.Create(value))); + } + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNByteTest(byte value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNDoubleTest(double value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNInt16Test(short value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNInt32Test(int value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNInt64Test(long value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNSByteTest(sbyte value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNSingleTest(float value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNUInt16Test(ushort value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNUInt32Test(uint value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNUInt64Test(ulong value) => IsNaN(value); + + private void IsNegative(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector128.AllBitsSet : Vector128.Zero, Vector128.IsNegative(Vector128.Create(value))); + Assert.Equal(T.IsNegative(value) ? Vector128.AllBitsSet : Vector128.Zero, Vector128.IsNegative(Vector128.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsNegativeSingle), MemberType = typeof(GenericMathTestMemberData))] - public void IsNegativeSingleTest(float value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeByteTest(byte value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeDoubleTest(double value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInt16Test(short value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInt32Test(int value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInt64Test(long value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeSByteTest(sbyte value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeSingleTest(float value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeUInt16Test(ushort value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeUInt32Test(uint value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeUInt64Test(ulong value) => IsNegative(value); + + private void IsNegativeInfinity(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector128.AllBitsSet : Vector128.Zero, Vector128.IsNegative(Vector128.Create(value))); + Assert.Equal(T.IsNegativeInfinity(value) ? Vector128.AllBitsSet : Vector128.Zero, Vector128.IsNegativeInfinity(Vector128.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsPositiveDouble), MemberType = typeof(GenericMathTestMemberData))] - public void IsPositiveDoubleTest(double value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityByteTest(byte value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityDoubleTest(double value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityInt16Test(short value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityInt32Test(int value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityInt64Test(long value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinitySByteTest(sbyte value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinitySingleTest(float value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityUInt16Test(ushort value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityUInt32Test(uint value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityUInt64Test(ulong value) => IsNegativeInfinity(value); + + private void IsNormal(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector128.AllBitsSet : Vector128.Zero, Vector128.IsPositive(Vector128.Create(value))); + Assert.Equal(T.IsNormal(value) ? Vector128.AllBitsSet : Vector128.Zero, Vector128.IsNormal(Vector128.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsPositiveSingle), MemberType = typeof(GenericMathTestMemberData))] - public void IsPositiveSingleTest(float value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalByteTest(byte value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalDoubleTest(double value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalInt16Test(short value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalInt32Test(int value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalInt64Test(long value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalSByteTest(sbyte value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalSingleTest(float value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalUInt16Test(ushort value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalUInt32Test(uint value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalUInt64Test(ulong value) => IsNormal(value); + + private void IsOddInteger(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector128.AllBitsSet : Vector128.Zero, Vector128.IsPositive(Vector128.Create(value))); + Assert.Equal(T.IsOddInteger(value) ? Vector128.AllBitsSet : Vector128.Zero, Vector128.IsOddInteger(Vector128.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsPositiveInfinityDouble), MemberType = typeof(GenericMathTestMemberData))] - public void IsPositiveInfinityDoubleTest(double value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerByteTest(byte value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerDoubleTest(double value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerInt16Test(short value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerInt32Test(int value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerInt64Test(long value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerSByteTest(sbyte value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerSingleTest(float value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerUInt16Test(ushort value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerUInt32Test(uint value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerUInt64Test(ulong value) => IsOddInteger(value); + + private void IsPositive(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector128.AllBitsSet : Vector128.Zero, Vector128.IsPositiveInfinity(Vector128.Create(value))); + Assert.Equal(T.IsPositive(value) ? Vector128.AllBitsSet : Vector128.Zero, Vector128.IsPositive(Vector128.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsPositiveInfinitySingle), MemberType = typeof(GenericMathTestMemberData))] - public void IsPositiveInfinitySingleTest(float value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveByteTest(byte value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveDoubleTest(double value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInt16Test(short value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInt32Test(int value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInt64Test(long value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveSByteTest(sbyte value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveSingleTest(float value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveUInt16Test(ushort value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveUInt32Test(uint value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveUInt64Test(ulong value) => IsPositive(value); + + private void IsPositiveInfinity(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector128.AllBitsSet : Vector128.Zero, Vector128.IsPositiveInfinity(Vector128.Create(value))); + Assert.Equal(T.IsPositiveInfinity(value) ? Vector128.AllBitsSet : Vector128.Zero, Vector128.IsPositiveInfinity(Vector128.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsZeroDouble), MemberType = typeof(GenericMathTestMemberData))] - public void IsZeroDoubleTest(double value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityByteTest(byte value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityDoubleTest(double value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityInt16Test(short value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityInt32Test(int value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityInt64Test(long value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinitySByteTest(sbyte value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinitySingleTest(float value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityUInt16Test(ushort value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityUInt32Test(uint value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityUInt64Test(ulong value) => IsPositiveInfinity(value); + + private void IsSubnormal(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector128.AllBitsSet : Vector128.Zero, Vector128.IsZero(Vector128.Create(value))); + Assert.Equal(T.IsSubnormal(value) ? Vector128.AllBitsSet : Vector128.Zero, Vector128.IsSubnormal(Vector128.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsZeroSingle), MemberType = typeof(GenericMathTestMemberData))] - public void IsZeroSingleTest(float value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalByteTest(byte value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalDoubleTest(double value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalInt16Test(short value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalInt32Test(int value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalInt64Test(long value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalSByteTest(sbyte value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalSingleTest(float value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalUInt16Test(ushort value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalUInt32Test(uint value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalUInt64Test(ulong value) => IsSubnormal(value); + + private void IsZero(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector128.AllBitsSet : Vector128.Zero, Vector128.IsZero(Vector128.Create(value))); + Assert.Equal(T.IsZero(value) ? Vector128.AllBitsSet : Vector128.Zero, Vector128.IsZero(Vector128.Create(value))); } + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroByteTest(byte value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroDoubleTest(double value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroInt16Test(short value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroInt32Test(int value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroInt64Test(long value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroSByteTest(sbyte value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroSingleTest(float value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroUInt16Test(ushort value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroUInt32Test(uint value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroUInt64Test(ulong value) => IsZero(value); + [Theory] [MemberData(nameof(GenericMathTestMemberData.LerpDouble), MemberType = typeof(GenericMathTestMemberData))] public void LerpDoubleTest(double x, double y, double amount, double expectedResult) @@ -5393,5 +5922,275 @@ public void TruncateSingleTest(float value, float expectedResult) Vector128 actualResult = Vector128.Truncate(Vector128.Create(value)); AssertEqual(Vector128.Create(expectedResult), actualResult, Vector128.Zero); } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void AllAnyNoneTest(T value1, T value2) + where T : struct, INumber + { + var input1 = Vector128.Create(value1); + var input2 = Vector128.Create(value2); + + Assert.True(Vector128.All(input1, value1)); + Assert.True(Vector128.All(input2, value2)); + Assert.False(Vector128.All(input1.WithElement(0, value2), value1)); + Assert.False(Vector128.All(input2.WithElement(0, value1), value2)); + Assert.False(Vector128.All(input1, value2)); + Assert.False(Vector128.All(input2, value1)); + Assert.False(Vector128.All(input1.WithElement(0, value2), value2)); + Assert.False(Vector128.All(input2.WithElement(0, value1), value1)); + + Assert.True(Vector128.Any(input1, value1)); + Assert.True(Vector128.Any(input2, value2)); + Assert.True(Vector128.Any(input1.WithElement(0, value2), value1)); + Assert.True(Vector128.Any(input2.WithElement(0, value1), value2)); + Assert.False(Vector128.Any(input1, value2)); + Assert.False(Vector128.Any(input2, value1)); + Assert.True(Vector128.Any(input1.WithElement(0, value2), value2)); + Assert.True(Vector128.Any(input2.WithElement(0, value1), value1)); + + Assert.False(Vector128.None(input1, value1)); + Assert.False(Vector128.None(input2, value2)); + Assert.False(Vector128.None(input1.WithElement(0, value2), value1)); + Assert.False(Vector128.None(input2.WithElement(0, value1), value2)); + Assert.True(Vector128.None(input1, value2)); + Assert.True(Vector128.None(input2, value1)); + Assert.False(Vector128.None(input1.WithElement(0, value2), value2)); + Assert.False(Vector128.None(input2.WithElement(0, value1), value1)); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void AllAnyNoneTest_IFloatingPointIeee754(T value) + where T : struct, IFloatingPointIeee754 + { + var input = Vector128.Create(value); + + Assert.False(Vector128.All(input, value)); + Assert.False(Vector128.Any(input, value)); + Assert.True(Vector128.None(input, value)); + } + + [Fact] + public void AllAnyNoneByteTest() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneDoubleTest() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneDoubleTest_AllBitsSet() => AllAnyNoneTest_IFloatingPointIeee754(BitConverter.Int64BitsToDouble(-1)); + + [Fact] + public void AllAnyNoneInt16Test() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneInt32Test() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneInt64Test() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneSByteTest() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneSingleTest() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneSingleTest_AllBitsSet() => AllAnyNoneTest_IFloatingPointIeee754(BitConverter.Int32BitsToSingle(-1)); + + [Fact] + public void AllAnyNoneUInt16Test() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneUInt32Test() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneUInt64Test() => AllAnyNoneTest(3, 2); + + [MethodImpl(MethodImplOptions.NoInlining)] + private void AllAnyNoneWhereAllBitsSetTest(T allBitsSet, T value2) + where T : struct, INumber + { + var input1 = Vector128.Create(allBitsSet); + var input2 = Vector128.Create(value2); + + Assert.True(Vector128.AllWhereAllBitsSet(input1)); + Assert.False(Vector128.AllWhereAllBitsSet(input2)); + Assert.False(Vector128.AllWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.False(Vector128.AllWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + + Assert.True(Vector128.AnyWhereAllBitsSet(input1)); + Assert.False(Vector128.AnyWhereAllBitsSet(input2)); + Assert.True(Vector128.AnyWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.True(Vector128.AnyWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + + Assert.False(Vector128.NoneWhereAllBitsSet(input1)); + Assert.True(Vector128.NoneWhereAllBitsSet(input2)); + Assert.False(Vector128.NoneWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.False(Vector128.NoneWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + } + + [Fact] + public void AllAnyNoneWhereAllBitsSetByteTest() => AllAnyNoneWhereAllBitsSetTest(byte.MaxValue, 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetDoubleTest() => AllAnyNoneWhereAllBitsSetTest(BitConverter.Int64BitsToDouble(-1), 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetInt16Test() => AllAnyNoneWhereAllBitsSetTest(-1, 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetInt32Test() => AllAnyNoneWhereAllBitsSetTest(-1, 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetInt64Test() => AllAnyNoneWhereAllBitsSetTest(-1, 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetSByteTest() => AllAnyNoneWhereAllBitsSetTest(-1, 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetSingleTest() => AllAnyNoneWhereAllBitsSetTest(BitConverter.Int32BitsToSingle(-1), 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetUInt16Test() => AllAnyNoneWhereAllBitsSetTest(ushort.MaxValue, 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetUInt32Test() => AllAnyNoneWhereAllBitsSetTest(uint.MaxValue, 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetUInt64Test() => AllAnyNoneWhereAllBitsSetTest(ulong.MaxValue, 2); + + [MethodImpl(MethodImplOptions.NoInlining)] + private void CountIndexOfLastIndexOfTest(T value1, T value2) + where T : struct, INumber + { + var input1 = Vector128.Create(value1); + var input2 = Vector128.Create(value2); + + Assert.Equal(Vector128.Count, Vector128.Count(input1, value1)); + Assert.Equal(Vector128.Count, Vector128.Count(input2, value2)); + Assert.Equal(Vector128.Count - 1, Vector128.Count(input1.WithElement(0, value2), value1)); + Assert.Equal(Vector128.Count - 1, Vector128.Count(input2.WithElement(0, value1), value2)); + Assert.Equal(0, Vector128.Count(input1, value2)); + Assert.Equal(0, Vector128.Count(input2, value1)); + Assert.Equal(1, Vector128.Count(input1.WithElement(0, value2), value2)); + Assert.Equal(1, Vector128.Count(input2.WithElement(0, value1), value1)); + + Assert.Equal(0, Vector128.IndexOf(input1, value1)); + Assert.Equal(0, Vector128.IndexOf(input2, value2)); + Assert.Equal(1, Vector128.IndexOf(input1.WithElement(0, value2), value1)); + Assert.Equal(1, Vector128.IndexOf(input2.WithElement(0, value1), value2)); + Assert.Equal(-1, Vector128.IndexOf(input1, value2)); + Assert.Equal(-1, Vector128.IndexOf(input2, value1)); + Assert.Equal(0, Vector128.IndexOf(input1.WithElement(0, value2), value2)); + Assert.Equal(0, Vector128.IndexOf(input2.WithElement(0, value1), value1)); + + Assert.Equal(Vector128.Count - 1, Vector128.LastIndexOf(input1, value1)); + Assert.Equal(Vector128.Count - 1, Vector128.LastIndexOf(input2, value2)); + Assert.Equal(Vector128.Count - 1, Vector128.LastIndexOf(input1.WithElement(0, value2), value1)); + Assert.Equal(Vector128.Count - 1, Vector128.LastIndexOf(input2.WithElement(0, value1), value2)); + Assert.Equal(-1, Vector128.LastIndexOf(input1, value2)); + Assert.Equal(-1, Vector128.LastIndexOf(input2, value1)); + Assert.Equal(0, Vector128.LastIndexOf(input1.WithElement(0, value2), value2)); + Assert.Equal(0, Vector128.LastIndexOf(input2.WithElement(0, value1), value1)); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void CountIndexOfLastIndexOfTest_IFloatingPointIeee754(T value) + where T : struct, IFloatingPointIeee754 + { + var input = Vector128.Create(value); + + Assert.Equal(0, Vector128.Count(input, value)); + Assert.Equal(-1, Vector128.IndexOf(input, value)); + Assert.Equal(-1, Vector128.LastIndexOf(input, value)); + } + + [Fact] + public void CountIndexOfLastIndexOfByteTest() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfDoubleTest() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfDoubleTest_AllBitsSet() => CountIndexOfLastIndexOfTest_IFloatingPointIeee754(BitConverter.Int64BitsToDouble(-1)); + + [Fact] + public void CountIndexOfLastIndexOfInt16Test() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfInt32Test() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfInt64Test() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfSByteTest() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfSingleTest() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfSingleTest_AllBitsSet() => CountIndexOfLastIndexOfTest_IFloatingPointIeee754(BitConverter.Int32BitsToSingle(-1)); + + [Fact] + public void CountIndexOfLastIndexOfUInt16Test() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfUInt32Test() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfUInt64Test() => CountIndexOfLastIndexOfTest(3, 2); + + [MethodImpl(MethodImplOptions.NoInlining)] + private void CountIndexOfLastIndexOfWhereAllBitsSetTest(T allBitsSet, T value2) + where T : struct, INumber + { + var input1 = Vector128.Create(allBitsSet); + var input2 = Vector128.Create(value2); + + Assert.Equal(Vector128.Count, Vector128.CountWhereAllBitsSet(input1)); + Assert.Equal(0, Vector128.CountWhereAllBitsSet(input2)); + Assert.Equal(Vector128.Count - 1, Vector128.CountWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.Equal(1, Vector128.CountWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + + Assert.Equal(0, Vector128.IndexOfWhereAllBitsSet(input1)); + Assert.Equal(-1, Vector128.IndexOfWhereAllBitsSet(input2)); + Assert.Equal(1, Vector128.IndexOfWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.Equal(0, Vector128.IndexOfWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + + Assert.Equal(Vector128.Count - 1, Vector128.LastIndexOfWhereAllBitsSet(input1)); + Assert.Equal(-1, Vector128.LastIndexOfWhereAllBitsSet(input2)); + Assert.Equal(Vector128.Count - 1, Vector128.LastIndexOfWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.Equal(0, Vector128.LastIndexOfWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + } + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetByteTest() => CountIndexOfLastIndexOfWhereAllBitsSetTest(byte.MaxValue, 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetDoubleTest() => CountIndexOfLastIndexOfWhereAllBitsSetTest(BitConverter.Int64BitsToDouble(-1), 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetInt16Test() => CountIndexOfLastIndexOfWhereAllBitsSetTest(-1, 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetInt32Test() => CountIndexOfLastIndexOfWhereAllBitsSetTest(-1, 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetInt64Test() => CountIndexOfLastIndexOfWhereAllBitsSetTest(-1, 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetSByteTest() => CountIndexOfLastIndexOfWhereAllBitsSetTest(-1, 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetSingleTest() => CountIndexOfLastIndexOfWhereAllBitsSetTest(BitConverter.Int32BitsToSingle(-1), 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetUInt16Test() => CountIndexOfLastIndexOfWhereAllBitsSetTest(ushort.MaxValue, 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetUInt32Test() => CountIndexOfLastIndexOfWhereAllBitsSetTest(uint.MaxValue, 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetUInt64Test() => CountIndexOfLastIndexOfWhereAllBitsSetTest(ulong.MaxValue, 2); } } diff --git a/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector256Tests.cs b/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector256Tests.cs index d16e5eed481809..30c92e16c12b4c 100644 --- a/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector256Tests.cs +++ b/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector256Tests.cs @@ -3,8 +3,8 @@ using System.Numerics; using System.Reflection; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using System.Runtime.Intrinsics.X86; using System.Tests; using Xunit; @@ -5529,9 +5529,9 @@ public void Vector256DoubleEqualsNonCanonicalNaNTest() }; // all Vector NaNs .Equals compare the same, but == compare as different - foreach(var i in nans) + foreach (var i in nans) { - foreach(var j in nans) + foreach (var j in nans) { Assert.True(Vector256.Create(i).Equals(Vector256.Create(j))); Assert.False(Vector256.Create(i) == Vector256.Create(j)); @@ -5553,9 +5553,9 @@ public void Vector256SingleEqualsNonCanonicalNaNTest() }; // all Vector NaNs .Equals compare the same, but == compare as different - foreach(var i in nans) + foreach (var i in nans) { - foreach(var j in nans) + foreach (var j in nans) { Assert.True(Vector256.Create(i).Equals(Vector256.Create(j))); Assert.False(Vector256.Create(i) == Vector256.Create(j)); @@ -6083,76 +6083,604 @@ public void HypotSingleTest(float x, float y, float expectedResult, float varian AssertEqual(Vector256.Create(expectedResult), Vector256.Hypot(Vector256.Create(+y), Vector256.Create(+x)), Vector256.Create(variance)); } + private void IsEvenInteger(T value) + where T : INumber + { + Assert.Equal(T.IsEvenInteger(value) ? Vector256.AllBitsSet : Vector256.Zero, Vector256.IsEvenInteger(Vector256.Create(value))); + } + [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsNaNDouble), MemberType = typeof(GenericMathTestMemberData))] - public void IsNaNDoubleTest(double value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerByteTest(byte value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerDoubleTest(double value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerInt16Test(short value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerInt32Test(int value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerInt64Test(long value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerSByteTest(sbyte value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerSingleTest(float value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerUInt16Test(ushort value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerUInt32Test(uint value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerUInt64Test(ulong value) => IsEvenInteger(value); + + private void IsFinite(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector256.AllBitsSet : Vector256.Zero, Vector256.IsNaN(Vector256.Create(value))); + Assert.Equal(T.IsFinite(value) ? Vector256.AllBitsSet : Vector256.Zero, Vector256.IsFinite(Vector256.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsNaNSingle), MemberType = typeof(GenericMathTestMemberData))] - public void IsNaNSingleTest(float value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteByteTest(byte value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteDoubleTest(double value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteInt16Test(short value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteInt32Test(int value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteInt64Test(long value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteSByteTest(sbyte value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteSingleTest(float value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteUInt16Test(ushort value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteUInt32Test(uint value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteUInt64Test(ulong value) => IsFinite(value); + + private void IsInfinity(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector256.AllBitsSet : Vector256.Zero, Vector256.IsNaN(Vector256.Create(value))); + Assert.Equal(T.IsInfinity(value) ? Vector256.AllBitsSet : Vector256.Zero, Vector256.IsInfinity(Vector256.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsNegativeDouble), MemberType = typeof(GenericMathTestMemberData))] - public void IsNegativeDoubleTest(double value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityByteTest(byte value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityDoubleTest(double value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityInt16Test(short value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityInt32Test(int value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityInt64Test(long value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinitySByteTest(sbyte value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinitySingleTest(float value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityUInt16Test(ushort value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityUInt32Test(uint value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityUInt64Test(ulong value) => IsInfinity(value); + + private void IsInteger(T value) + where T : INumber + { + Assert.Equal(T.IsInteger(value) ? Vector256.AllBitsSet : Vector256.Zero, Vector256.IsInteger(Vector256.Create(value))); + } + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerByteTest(byte value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerDoubleTest(double value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerInt16Test(short value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerInt32Test(int value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerInt64Test(long value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerSByteTest(sbyte value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerSingleTest(float value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerUInt16Test(ushort value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerUInt32Test(uint value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerUInt64Test(ulong value) => IsInteger(value); + + private void IsNaN(T value) + where T : INumber + { + Assert.Equal(T.IsNaN(value) ? Vector256.AllBitsSet : Vector256.Zero, Vector256.IsNaN(Vector256.Create(value))); + } + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNByteTest(byte value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNDoubleTest(double value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNInt16Test(short value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNInt32Test(int value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNInt64Test(long value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNSByteTest(sbyte value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNSingleTest(float value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNUInt16Test(ushort value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNUInt32Test(uint value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNUInt64Test(ulong value) => IsNaN(value); + + private void IsNegative(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector256.AllBitsSet : Vector256.Zero, Vector256.IsNegative(Vector256.Create(value))); + Assert.Equal(T.IsNegative(value) ? Vector256.AllBitsSet : Vector256.Zero, Vector256.IsNegative(Vector256.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsNegativeSingle), MemberType = typeof(GenericMathTestMemberData))] - public void IsNegativeSingleTest(float value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeByteTest(byte value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeDoubleTest(double value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInt16Test(short value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInt32Test(int value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInt64Test(long value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeSByteTest(sbyte value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeSingleTest(float value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeUInt16Test(ushort value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeUInt32Test(uint value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeUInt64Test(ulong value) => IsNegative(value); + + private void IsNegativeInfinity(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector256.AllBitsSet : Vector256.Zero, Vector256.IsNegative(Vector256.Create(value))); + Assert.Equal(T.IsNegativeInfinity(value) ? Vector256.AllBitsSet : Vector256.Zero, Vector256.IsNegativeInfinity(Vector256.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsPositiveDouble), MemberType = typeof(GenericMathTestMemberData))] - public void IsPositiveDoubleTest(double value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityByteTest(byte value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityDoubleTest(double value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityInt16Test(short value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityInt32Test(int value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityInt64Test(long value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinitySByteTest(sbyte value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinitySingleTest(float value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityUInt16Test(ushort value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityUInt32Test(uint value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityUInt64Test(ulong value) => IsNegativeInfinity(value); + + private void IsNormal(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector256.AllBitsSet : Vector256.Zero, Vector256.IsPositive(Vector256.Create(value))); + Assert.Equal(T.IsNormal(value) ? Vector256.AllBitsSet : Vector256.Zero, Vector256.IsNormal(Vector256.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsPositiveSingle), MemberType = typeof(GenericMathTestMemberData))] - public void IsPositiveSingleTest(float value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalByteTest(byte value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalDoubleTest(double value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalInt16Test(short value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalInt32Test(int value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalInt64Test(long value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalSByteTest(sbyte value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalSingleTest(float value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalUInt16Test(ushort value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalUInt32Test(uint value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalUInt64Test(ulong value) => IsNormal(value); + + private void IsOddInteger(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector256.AllBitsSet : Vector256.Zero, Vector256.IsPositive(Vector256.Create(value))); + Assert.Equal(T.IsOddInteger(value) ? Vector256.AllBitsSet : Vector256.Zero, Vector256.IsOddInteger(Vector256.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsPositiveInfinityDouble), MemberType = typeof(GenericMathTestMemberData))] - public void IsPositiveInfinityDoubleTest(double value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerByteTest(byte value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerDoubleTest(double value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerInt16Test(short value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerInt32Test(int value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerInt64Test(long value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerSByteTest(sbyte value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerSingleTest(float value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerUInt16Test(ushort value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerUInt32Test(uint value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerUInt64Test(ulong value) => IsOddInteger(value); + + private void IsPositive(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector256.AllBitsSet : Vector256.Zero, Vector256.IsPositiveInfinity(Vector256.Create(value))); + Assert.Equal(T.IsPositive(value) ? Vector256.AllBitsSet : Vector256.Zero, Vector256.IsPositive(Vector256.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsPositiveInfinitySingle), MemberType = typeof(GenericMathTestMemberData))] - public void IsPositiveInfinitySingleTest(float value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveByteTest(byte value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveDoubleTest(double value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInt16Test(short value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInt32Test(int value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInt64Test(long value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveSByteTest(sbyte value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveSingleTest(float value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveUInt16Test(ushort value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveUInt32Test(uint value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveUInt64Test(ulong value) => IsPositive(value); + + private void IsPositiveInfinity(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector256.AllBitsSet : Vector256.Zero, Vector256.IsPositiveInfinity(Vector256.Create(value))); + Assert.Equal(T.IsPositiveInfinity(value) ? Vector256.AllBitsSet : Vector256.Zero, Vector256.IsPositiveInfinity(Vector256.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsZeroDouble), MemberType = typeof(GenericMathTestMemberData))] - public void IsZeroDoubleTest(double value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityByteTest(byte value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityDoubleTest(double value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityInt16Test(short value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityInt32Test(int value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityInt64Test(long value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinitySByteTest(sbyte value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinitySingleTest(float value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityUInt16Test(ushort value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityUInt32Test(uint value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityUInt64Test(ulong value) => IsPositiveInfinity(value); + + private void IsSubnormal(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector256.AllBitsSet : Vector256.Zero, Vector256.IsZero(Vector256.Create(value))); + Assert.Equal(T.IsSubnormal(value) ? Vector256.AllBitsSet : Vector256.Zero, Vector256.IsSubnormal(Vector256.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsZeroSingle), MemberType = typeof(GenericMathTestMemberData))] - public void IsZeroSingleTest(float value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalByteTest(byte value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalDoubleTest(double value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalInt16Test(short value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalInt32Test(int value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalInt64Test(long value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalSByteTest(sbyte value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalSingleTest(float value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalUInt16Test(ushort value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalUInt32Test(uint value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalUInt64Test(ulong value) => IsSubnormal(value); + + private void IsZero(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector256.AllBitsSet : Vector256.Zero, Vector256.IsZero(Vector256.Create(value))); + Assert.Equal(T.IsZero(value) ? Vector256.AllBitsSet : Vector256.Zero, Vector256.IsZero(Vector256.Create(value))); } + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroByteTest(byte value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroDoubleTest(double value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroInt16Test(short value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroInt32Test(int value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroInt64Test(long value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroSByteTest(sbyte value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroSingleTest(float value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroUInt16Test(ushort value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroUInt32Test(uint value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroUInt64Test(ulong value) => IsZero(value); + [Theory] [MemberData(nameof(GenericMathTestMemberData.LerpDouble), MemberType = typeof(GenericMathTestMemberData))] public void LerpDoubleTest(double x, double y, double amount, double expectedResult) @@ -6410,5 +6938,275 @@ public void TruncateSingleTest(float value, float expectedResult) Vector256 actualResult = Vector256.Truncate(Vector256.Create(value)); AssertEqual(Vector256.Create(expectedResult), actualResult, Vector256.Zero); } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void AllAnyNoneTest(T value1, T value2) + where T : struct, INumber + { + var input1 = Vector256.Create(value1); + var input2 = Vector256.Create(value2); + + Assert.True(Vector256.All(input1, value1)); + Assert.True(Vector256.All(input2, value2)); + Assert.False(Vector256.All(input1.WithElement(0, value2), value1)); + Assert.False(Vector256.All(input2.WithElement(0, value1), value2)); + Assert.False(Vector256.All(input1, value2)); + Assert.False(Vector256.All(input2, value1)); + Assert.False(Vector256.All(input1.WithElement(0, value2), value2)); + Assert.False(Vector256.All(input2.WithElement(0, value1), value1)); + + Assert.True(Vector256.Any(input1, value1)); + Assert.True(Vector256.Any(input2, value2)); + Assert.True(Vector256.Any(input1.WithElement(0, value2), value1)); + Assert.True(Vector256.Any(input2.WithElement(0, value1), value2)); + Assert.False(Vector256.Any(input1, value2)); + Assert.False(Vector256.Any(input2, value1)); + Assert.True(Vector256.Any(input1.WithElement(0, value2), value2)); + Assert.True(Vector256.Any(input2.WithElement(0, value1), value1)); + + Assert.False(Vector256.None(input1, value1)); + Assert.False(Vector256.None(input2, value2)); + Assert.False(Vector256.None(input1.WithElement(0, value2), value1)); + Assert.False(Vector256.None(input2.WithElement(0, value1), value2)); + Assert.True(Vector256.None(input1, value2)); + Assert.True(Vector256.None(input2, value1)); + Assert.False(Vector256.None(input1.WithElement(0, value2), value2)); + Assert.False(Vector256.None(input2.WithElement(0, value1), value1)); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void AllAnyNoneTest_IFloatingPointIeee754(T value) + where T : struct, IFloatingPointIeee754 + { + var input = Vector256.Create(value); + + Assert.False(Vector256.All(input, value)); + Assert.False(Vector256.Any(input, value)); + Assert.True(Vector256.None(input, value)); + } + + [Fact] + public void AllAnyNoneByteTest() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneDoubleTest() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneDoubleTest_AllBitsSet() => AllAnyNoneTest_IFloatingPointIeee754(BitConverter.Int64BitsToDouble(-1)); + + [Fact] + public void AllAnyNoneInt16Test() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneInt32Test() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneInt64Test() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneSByteTest() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneSingleTest() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneSingleTest_AllBitsSet() => AllAnyNoneTest_IFloatingPointIeee754(BitConverter.Int32BitsToSingle(-1)); + + [Fact] + public void AllAnyNoneUInt16Test() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneUInt32Test() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneUInt64Test() => AllAnyNoneTest(3, 2); + + [MethodImpl(MethodImplOptions.NoInlining)] + private void AllAnyNoneWhereAllBitsSetTest(T allBitsSet, T value2) + where T : struct, INumber + { + var input1 = Vector256.Create(allBitsSet); + var input2 = Vector256.Create(value2); + + Assert.True(Vector256.AllWhereAllBitsSet(input1)); + Assert.False(Vector256.AllWhereAllBitsSet(input2)); + Assert.False(Vector256.AllWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.False(Vector256.AllWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + + Assert.True(Vector256.AnyWhereAllBitsSet(input1)); + Assert.False(Vector256.AnyWhereAllBitsSet(input2)); + Assert.True(Vector256.AnyWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.True(Vector256.AnyWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + + Assert.False(Vector256.NoneWhereAllBitsSet(input1)); + Assert.True(Vector256.NoneWhereAllBitsSet(input2)); + Assert.False(Vector256.NoneWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.False(Vector256.NoneWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + } + + [Fact] + public void AllAnyNoneWhereAllBitsSetByteTest() => AllAnyNoneWhereAllBitsSetTest(byte.MaxValue, 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetDoubleTest() => AllAnyNoneWhereAllBitsSetTest(BitConverter.Int64BitsToDouble(-1), 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetInt16Test() => AllAnyNoneWhereAllBitsSetTest(-1, 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetInt32Test() => AllAnyNoneWhereAllBitsSetTest(-1, 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetInt64Test() => AllAnyNoneWhereAllBitsSetTest(-1, 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetSByteTest() => AllAnyNoneWhereAllBitsSetTest(-1, 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetSingleTest() => AllAnyNoneWhereAllBitsSetTest(BitConverter.Int32BitsToSingle(-1), 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetUInt16Test() => AllAnyNoneWhereAllBitsSetTest(ushort.MaxValue, 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetUInt32Test() => AllAnyNoneWhereAllBitsSetTest(uint.MaxValue, 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetUInt64Test() => AllAnyNoneWhereAllBitsSetTest(ulong.MaxValue, 2); + + [MethodImpl(MethodImplOptions.NoInlining)] + private void CountIndexOfLastIndexOfTest(T value1, T value2) + where T : struct, INumber + { + var input1 = Vector256.Create(value1); + var input2 = Vector256.Create(value2); + + Assert.Equal(Vector256.Count, Vector256.Count(input1, value1)); + Assert.Equal(Vector256.Count, Vector256.Count(input2, value2)); + Assert.Equal(Vector256.Count - 1, Vector256.Count(input1.WithElement(0, value2), value1)); + Assert.Equal(Vector256.Count - 1, Vector256.Count(input2.WithElement(0, value1), value2)); + Assert.Equal(0, Vector256.Count(input1, value2)); + Assert.Equal(0, Vector256.Count(input2, value1)); + Assert.Equal(1, Vector256.Count(input1.WithElement(0, value2), value2)); + Assert.Equal(1, Vector256.Count(input2.WithElement(0, value1), value1)); + + Assert.Equal(0, Vector256.IndexOf(input1, value1)); + Assert.Equal(0, Vector256.IndexOf(input2, value2)); + Assert.Equal(1, Vector256.IndexOf(input1.WithElement(0, value2), value1)); + Assert.Equal(1, Vector256.IndexOf(input2.WithElement(0, value1), value2)); + Assert.Equal(-1, Vector256.IndexOf(input1, value2)); + Assert.Equal(-1, Vector256.IndexOf(input2, value1)); + Assert.Equal(0, Vector256.IndexOf(input1.WithElement(0, value2), value2)); + Assert.Equal(0, Vector256.IndexOf(input2.WithElement(0, value1), value1)); + + Assert.Equal(Vector256.Count - 1, Vector256.LastIndexOf(input1, value1)); + Assert.Equal(Vector256.Count - 1, Vector256.LastIndexOf(input2, value2)); + Assert.Equal(Vector256.Count - 1, Vector256.LastIndexOf(input1.WithElement(0, value2), value1)); + Assert.Equal(Vector256.Count - 1, Vector256.LastIndexOf(input2.WithElement(0, value1), value2)); + Assert.Equal(-1, Vector256.LastIndexOf(input1, value2)); + Assert.Equal(-1, Vector256.LastIndexOf(input2, value1)); + Assert.Equal(0, Vector256.LastIndexOf(input1.WithElement(0, value2), value2)); + Assert.Equal(0, Vector256.LastIndexOf(input2.WithElement(0, value1), value1)); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void CountIndexOfLastIndexOfTest_IFloatingPointIeee754(T value) + where T : struct, IFloatingPointIeee754 + { + var input = Vector256.Create(value); + + Assert.Equal(0, Vector256.Count(input, value)); + Assert.Equal(-1, Vector256.IndexOf(input, value)); + Assert.Equal(-1, Vector256.LastIndexOf(input, value)); + } + + [Fact] + public void CountIndexOfLastIndexOfByteTest() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfDoubleTest() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfDoubleTest_AllBitsSet() => CountIndexOfLastIndexOfTest_IFloatingPointIeee754(BitConverter.Int64BitsToDouble(-1)); + + [Fact] + public void CountIndexOfLastIndexOfInt16Test() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfInt32Test() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfInt64Test() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfSByteTest() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfSingleTest() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfSingleTest_AllBitsSet() => CountIndexOfLastIndexOfTest_IFloatingPointIeee754(BitConverter.Int32BitsToSingle(-1)); + + [Fact] + public void CountIndexOfLastIndexOfUInt16Test() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfUInt32Test() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfUInt64Test() => CountIndexOfLastIndexOfTest(3, 2); + + [MethodImpl(MethodImplOptions.NoInlining)] + private void CountIndexOfLastIndexOfWhereAllBitsSetTest(T allBitsSet, T value2) + where T : struct, INumber + { + var input1 = Vector256.Create(allBitsSet); + var input2 = Vector256.Create(value2); + + Assert.Equal(Vector256.Count, Vector256.CountWhereAllBitsSet(input1)); + Assert.Equal(0, Vector256.CountWhereAllBitsSet(input2)); + Assert.Equal(Vector256.Count - 1, Vector256.CountWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.Equal(1, Vector256.CountWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + + Assert.Equal(0, Vector256.IndexOfWhereAllBitsSet(input1)); + Assert.Equal(-1, Vector256.IndexOfWhereAllBitsSet(input2)); + Assert.Equal(1, Vector256.IndexOfWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.Equal(0, Vector256.IndexOfWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + + Assert.Equal(Vector256.Count - 1, Vector256.LastIndexOfWhereAllBitsSet(input1)); + Assert.Equal(-1, Vector256.LastIndexOfWhereAllBitsSet(input2)); + Assert.Equal(Vector256.Count - 1, Vector256.LastIndexOfWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.Equal(0, Vector256.LastIndexOfWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + } + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetByteTest() => CountIndexOfLastIndexOfWhereAllBitsSetTest(byte.MaxValue, 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetDoubleTest() => CountIndexOfLastIndexOfWhereAllBitsSetTest(BitConverter.Int64BitsToDouble(-1), 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetInt16Test() => CountIndexOfLastIndexOfWhereAllBitsSetTest(-1, 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetInt32Test() => CountIndexOfLastIndexOfWhereAllBitsSetTest(-1, 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetInt64Test() => CountIndexOfLastIndexOfWhereAllBitsSetTest(-1, 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetSByteTest() => CountIndexOfLastIndexOfWhereAllBitsSetTest(-1, 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetSingleTest() => CountIndexOfLastIndexOfWhereAllBitsSetTest(BitConverter.Int32BitsToSingle(-1), 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetUInt16Test() => CountIndexOfLastIndexOfWhereAllBitsSetTest(ushort.MaxValue, 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetUInt32Test() => CountIndexOfLastIndexOfWhereAllBitsSetTest(uint.MaxValue, 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetUInt64Test() => CountIndexOfLastIndexOfWhereAllBitsSetTest(ulong.MaxValue, 2); } } diff --git a/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector512Tests.cs b/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector512Tests.cs index f996d82369615f..6016fc822a1cab 100644 --- a/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector512Tests.cs +++ b/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector512Tests.cs @@ -3,8 +3,8 @@ using System.Numerics; using System.Reflection; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using System.Runtime.Intrinsics.X86; using System.Tests; using Xunit; @@ -5007,9 +5007,9 @@ public void Vector512DoubleEqualsNonCanonicalNaNTest() }; // all Vector NaNs .Equals compare the same, but == compare as different - foreach(var i in nans) + foreach (var i in nans) { - foreach(var j in nans) + foreach (var j in nans) { Assert.True(Vector512.Create(i).Equals(Vector512.Create(j))); Assert.False(Vector512.Create(i) == Vector512.Create(j)); @@ -5031,9 +5031,9 @@ public void Vector512SingleEqualsNonCanonicalNaNTest() }; // all Vector NaNs .Equals compare the same, but == compare as different - foreach(var i in nans) + foreach (var i in nans) { - foreach(var j in nans) + foreach (var j in nans) { Assert.True(Vector512.Create(i).Equals(Vector512.Create(j))); Assert.False(Vector512.Create(i) == Vector512.Create(j)); @@ -5516,76 +5516,604 @@ public void HypotSingleTest(float x, float y, float expectedResult, float varian AssertEqual(Vector512.Create(expectedResult), Vector512.Hypot(Vector512.Create(+y), Vector512.Create(+x)), Vector512.Create(variance)); } + private void IsEvenInteger(T value) + where T : INumber + { + Assert.Equal(T.IsEvenInteger(value) ? Vector512.AllBitsSet : Vector512.Zero, Vector512.IsEvenInteger(Vector512.Create(value))); + } + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerByteTest(byte value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerDoubleTest(double value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerInt16Test(short value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerInt32Test(int value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerInt64Test(long value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerSByteTest(sbyte value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerSingleTest(float value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerUInt16Test(ushort value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerUInt32Test(uint value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerUInt64Test(ulong value) => IsEvenInteger(value); + + private void IsFinite(T value) + where T : INumber + { + Assert.Equal(T.IsFinite(value) ? Vector512.AllBitsSet : Vector512.Zero, Vector512.IsFinite(Vector512.Create(value))); + } + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteByteTest(byte value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteDoubleTest(double value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteInt16Test(short value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteInt32Test(int value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteInt64Test(long value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteSByteTest(sbyte value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteSingleTest(float value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteUInt16Test(ushort value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteUInt32Test(uint value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteUInt64Test(ulong value) => IsFinite(value); + + private void IsInfinity(T value) + where T : INumber + { + Assert.Equal(T.IsInfinity(value) ? Vector512.AllBitsSet : Vector512.Zero, Vector512.IsInfinity(Vector512.Create(value))); + } + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityByteTest(byte value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityDoubleTest(double value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityInt16Test(short value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityInt32Test(int value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityInt64Test(long value) => IsInfinity(value); + [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsNaNDouble), MemberType = typeof(GenericMathTestMemberData))] - public void IsNaNDoubleTest(double value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinitySByteTest(sbyte value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinitySingleTest(float value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityUInt16Test(ushort value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityUInt32Test(uint value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityUInt64Test(ulong value) => IsInfinity(value); + + private void IsInteger(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector512.AllBitsSet : Vector512.Zero, Vector512.IsNaN(Vector512.Create(value))); + Assert.Equal(T.IsInteger(value) ? Vector512.AllBitsSet : Vector512.Zero, Vector512.IsInteger(Vector512.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsNaNSingle), MemberType = typeof(GenericMathTestMemberData))] - public void IsNaNSingleTest(float value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerByteTest(byte value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerDoubleTest(double value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerInt16Test(short value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerInt32Test(int value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerInt64Test(long value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerSByteTest(sbyte value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerSingleTest(float value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerUInt16Test(ushort value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerUInt32Test(uint value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerUInt64Test(ulong value) => IsInteger(value); + + private void IsNaN(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector512.AllBitsSet : Vector512.Zero, Vector512.IsNaN(Vector512.Create(value))); + Assert.Equal(T.IsNaN(value) ? Vector512.AllBitsSet : Vector512.Zero, Vector512.IsNaN(Vector512.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsNegativeDouble), MemberType = typeof(GenericMathTestMemberData))] - public void IsNegativeDoubleTest(double value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNByteTest(byte value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNDoubleTest(double value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNInt16Test(short value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNInt32Test(int value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNInt64Test(long value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNSByteTest(sbyte value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNSingleTest(float value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNUInt16Test(ushort value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNUInt32Test(uint value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNUInt64Test(ulong value) => IsNaN(value); + + private void IsNegative(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector512.AllBitsSet : Vector512.Zero, Vector512.IsNegative(Vector512.Create(value))); + Assert.Equal(T.IsNegative(value) ? Vector512.AllBitsSet : Vector512.Zero, Vector512.IsNegative(Vector512.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsNegativeSingle), MemberType = typeof(GenericMathTestMemberData))] - public void IsNegativeSingleTest(float value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeByteTest(byte value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeDoubleTest(double value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInt16Test(short value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInt32Test(int value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInt64Test(long value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeSByteTest(sbyte value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeSingleTest(float value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeUInt16Test(ushort value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeUInt32Test(uint value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeUInt64Test(ulong value) => IsNegative(value); + + private void IsNegativeInfinity(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector512.AllBitsSet : Vector512.Zero, Vector512.IsNegative(Vector512.Create(value))); + Assert.Equal(T.IsNegativeInfinity(value) ? Vector512.AllBitsSet : Vector512.Zero, Vector512.IsNegativeInfinity(Vector512.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsPositiveDouble), MemberType = typeof(GenericMathTestMemberData))] - public void IsPositiveDoubleTest(double value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityByteTest(byte value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityDoubleTest(double value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityInt16Test(short value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityInt32Test(int value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityInt64Test(long value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinitySByteTest(sbyte value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinitySingleTest(float value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityUInt16Test(ushort value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityUInt32Test(uint value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityUInt64Test(ulong value) => IsNegativeInfinity(value); + + private void IsNormal(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector512.AllBitsSet : Vector512.Zero, Vector512.IsPositive(Vector512.Create(value))); + Assert.Equal(T.IsNormal(value) ? Vector512.AllBitsSet : Vector512.Zero, Vector512.IsNormal(Vector512.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsPositiveSingle), MemberType = typeof(GenericMathTestMemberData))] - public void IsPositiveSingleTest(float value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalByteTest(byte value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalDoubleTest(double value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalInt16Test(short value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalInt32Test(int value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalInt64Test(long value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalSByteTest(sbyte value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalSingleTest(float value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalUInt16Test(ushort value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalUInt32Test(uint value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalUInt64Test(ulong value) => IsNormal(value); + + private void IsOddInteger(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector512.AllBitsSet : Vector512.Zero, Vector512.IsPositive(Vector512.Create(value))); + Assert.Equal(T.IsOddInteger(value) ? Vector512.AllBitsSet : Vector512.Zero, Vector512.IsOddInteger(Vector512.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsPositiveInfinityDouble), MemberType = typeof(GenericMathTestMemberData))] - public void IsPositiveInfinityDoubleTest(double value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerByteTest(byte value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerDoubleTest(double value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerInt16Test(short value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerInt32Test(int value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerInt64Test(long value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerSByteTest(sbyte value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerSingleTest(float value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerUInt16Test(ushort value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerUInt32Test(uint value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerUInt64Test(ulong value) => IsOddInteger(value); + + private void IsPositive(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector512.AllBitsSet : Vector512.Zero, Vector512.IsPositiveInfinity(Vector512.Create(value))); + Assert.Equal(T.IsPositive(value) ? Vector512.AllBitsSet : Vector512.Zero, Vector512.IsPositive(Vector512.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsPositiveInfinitySingle), MemberType = typeof(GenericMathTestMemberData))] - public void IsPositiveInfinitySingleTest(float value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveByteTest(byte value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveDoubleTest(double value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInt16Test(short value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInt32Test(int value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInt64Test(long value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveSByteTest(sbyte value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveSingleTest(float value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveUInt16Test(ushort value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveUInt32Test(uint value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveUInt64Test(ulong value) => IsPositive(value); + + private void IsPositiveInfinity(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector512.AllBitsSet : Vector512.Zero, Vector512.IsPositiveInfinity(Vector512.Create(value))); + Assert.Equal(T.IsPositiveInfinity(value) ? Vector512.AllBitsSet : Vector512.Zero, Vector512.IsPositiveInfinity(Vector512.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsZeroDouble), MemberType = typeof(GenericMathTestMemberData))] - public void IsZeroDoubleTest(double value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityByteTest(byte value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityDoubleTest(double value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityInt16Test(short value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityInt32Test(int value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityInt64Test(long value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinitySByteTest(sbyte value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinitySingleTest(float value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityUInt16Test(ushort value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityUInt32Test(uint value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityUInt64Test(ulong value) => IsPositiveInfinity(value); + + private void IsSubnormal(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector512.AllBitsSet : Vector512.Zero, Vector512.IsZero(Vector512.Create(value))); + Assert.Equal(T.IsSubnormal(value) ? Vector512.AllBitsSet : Vector512.Zero, Vector512.IsSubnormal(Vector512.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsZeroSingle), MemberType = typeof(GenericMathTestMemberData))] - public void IsZeroSingleTest(float value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalByteTest(byte value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalDoubleTest(double value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalInt16Test(short value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalInt32Test(int value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalInt64Test(long value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalSByteTest(sbyte value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalSingleTest(float value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalUInt16Test(ushort value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalUInt32Test(uint value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalUInt64Test(ulong value) => IsSubnormal(value); + + private void IsZero(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector512.AllBitsSet : Vector512.Zero, Vector512.IsZero(Vector512.Create(value))); + Assert.Equal(T.IsZero(value) ? Vector512.AllBitsSet : Vector512.Zero, Vector512.IsZero(Vector512.Create(value))); } + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroByteTest(byte value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroDoubleTest(double value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroInt16Test(short value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroInt32Test(int value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroInt64Test(long value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroSByteTest(sbyte value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroSingleTest(float value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroUInt16Test(ushort value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroUInt32Test(uint value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroUInt64Test(ulong value) => IsZero(value); + [Theory] [MemberData(nameof(GenericMathTestMemberData.LerpDouble), MemberType = typeof(GenericMathTestMemberData))] public void LerpDoubleTest(double x, double y, double amount, double expectedResult) @@ -5843,5 +6371,275 @@ public void TruncateSingleTest(float value, float expectedResult) Vector512 actualResult = Vector512.Truncate(Vector512.Create(value)); AssertEqual(Vector512.Create(expectedResult), actualResult, Vector512.Zero); } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void AllAnyNoneTest(T value1, T value2) + where T : struct, INumber + { + var input1 = Vector512.Create(value1); + var input2 = Vector512.Create(value2); + + Assert.True(Vector512.All(input1, value1)); + Assert.True(Vector512.All(input2, value2)); + Assert.False(Vector512.All(input1.WithElement(0, value2), value1)); + Assert.False(Vector512.All(input2.WithElement(0, value1), value2)); + Assert.False(Vector512.All(input1, value2)); + Assert.False(Vector512.All(input2, value1)); + Assert.False(Vector512.All(input1.WithElement(0, value2), value2)); + Assert.False(Vector512.All(input2.WithElement(0, value1), value1)); + + Assert.True(Vector512.Any(input1, value1)); + Assert.True(Vector512.Any(input2, value2)); + Assert.True(Vector512.Any(input1.WithElement(0, value2), value1)); + Assert.True(Vector512.Any(input2.WithElement(0, value1), value2)); + Assert.False(Vector512.Any(input1, value2)); + Assert.False(Vector512.Any(input2, value1)); + Assert.True(Vector512.Any(input1.WithElement(0, value2), value2)); + Assert.True(Vector512.Any(input2.WithElement(0, value1), value1)); + + Assert.False(Vector512.None(input1, value1)); + Assert.False(Vector512.None(input2, value2)); + Assert.False(Vector512.None(input1.WithElement(0, value2), value1)); + Assert.False(Vector512.None(input2.WithElement(0, value1), value2)); + Assert.True(Vector512.None(input1, value2)); + Assert.True(Vector512.None(input2, value1)); + Assert.False(Vector512.None(input1.WithElement(0, value2), value2)); + Assert.False(Vector512.None(input2.WithElement(0, value1), value1)); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void AllAnyNoneTest_IFloatingPointIeee754(T value) + where T : struct, IFloatingPointIeee754 + { + var input = Vector512.Create(value); + + Assert.False(Vector512.All(input, value)); + Assert.False(Vector512.Any(input, value)); + Assert.True(Vector512.None(input, value)); + } + + [Fact] + public void AllAnyNoneByteTest() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneDoubleTest() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneDoubleTest_AllBitsSet() => AllAnyNoneTest_IFloatingPointIeee754(BitConverter.Int64BitsToDouble(-1)); + + [Fact] + public void AllAnyNoneInt16Test() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneInt32Test() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneInt64Test() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneSByteTest() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneSingleTest() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneSingleTest_AllBitsSet() => AllAnyNoneTest_IFloatingPointIeee754(BitConverter.Int32BitsToSingle(-1)); + + [Fact] + public void AllAnyNoneUInt16Test() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneUInt32Test() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneUInt64Test() => AllAnyNoneTest(3, 2); + + [MethodImpl(MethodImplOptions.NoInlining)] + private void AllAnyNoneWhereAllBitsSetTest(T allBitsSet, T value2) + where T : struct, INumber + { + var input1 = Vector512.Create(allBitsSet); + var input2 = Vector512.Create(value2); + + Assert.True(Vector512.AllWhereAllBitsSet(input1)); + Assert.False(Vector512.AllWhereAllBitsSet(input2)); + Assert.False(Vector512.AllWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.False(Vector512.AllWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + + Assert.True(Vector512.AnyWhereAllBitsSet(input1)); + Assert.False(Vector512.AnyWhereAllBitsSet(input2)); + Assert.True(Vector512.AnyWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.True(Vector512.AnyWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + + Assert.False(Vector512.NoneWhereAllBitsSet(input1)); + Assert.True(Vector512.NoneWhereAllBitsSet(input2)); + Assert.False(Vector512.NoneWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.False(Vector512.NoneWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + } + + [Fact] + public void AllAnyNoneWhereAllBitsSetByteTest() => AllAnyNoneWhereAllBitsSetTest(byte.MaxValue, 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetDoubleTest() => AllAnyNoneWhereAllBitsSetTest(BitConverter.Int64BitsToDouble(-1), 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetInt16Test() => AllAnyNoneWhereAllBitsSetTest(-1, 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetInt32Test() => AllAnyNoneWhereAllBitsSetTest(-1, 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetInt64Test() => AllAnyNoneWhereAllBitsSetTest(-1, 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetSByteTest() => AllAnyNoneWhereAllBitsSetTest(-1, 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetSingleTest() => AllAnyNoneWhereAllBitsSetTest(BitConverter.Int32BitsToSingle(-1), 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetUInt16Test() => AllAnyNoneWhereAllBitsSetTest(ushort.MaxValue, 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetUInt32Test() => AllAnyNoneWhereAllBitsSetTest(uint.MaxValue, 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetUInt64Test() => AllAnyNoneWhereAllBitsSetTest(ulong.MaxValue, 2); + + [MethodImpl(MethodImplOptions.NoInlining)] + private void CountIndexOfLastIndexOfTest(T value1, T value2) + where T : struct, INumber + { + var input1 = Vector512.Create(value1); + var input2 = Vector512.Create(value2); + + Assert.Equal(Vector512.Count, Vector512.Count(input1, value1)); + Assert.Equal(Vector512.Count, Vector512.Count(input2, value2)); + Assert.Equal(Vector512.Count - 1, Vector512.Count(input1.WithElement(0, value2), value1)); + Assert.Equal(Vector512.Count - 1, Vector512.Count(input2.WithElement(0, value1), value2)); + Assert.Equal(0, Vector512.Count(input1, value2)); + Assert.Equal(0, Vector512.Count(input2, value1)); + Assert.Equal(1, Vector512.Count(input1.WithElement(0, value2), value2)); + Assert.Equal(1, Vector512.Count(input2.WithElement(0, value1), value1)); + + Assert.Equal(0, Vector512.IndexOf(input1, value1)); + Assert.Equal(0, Vector512.IndexOf(input2, value2)); + Assert.Equal(1, Vector512.IndexOf(input1.WithElement(0, value2), value1)); + Assert.Equal(1, Vector512.IndexOf(input2.WithElement(0, value1), value2)); + Assert.Equal(-1, Vector512.IndexOf(input1, value2)); + Assert.Equal(-1, Vector512.IndexOf(input2, value1)); + Assert.Equal(0, Vector512.IndexOf(input1.WithElement(0, value2), value2)); + Assert.Equal(0, Vector512.IndexOf(input2.WithElement(0, value1), value1)); + + Assert.Equal(Vector512.Count - 1, Vector512.LastIndexOf(input1, value1)); + Assert.Equal(Vector512.Count - 1, Vector512.LastIndexOf(input2, value2)); + Assert.Equal(Vector512.Count - 1, Vector512.LastIndexOf(input1.WithElement(0, value2), value1)); + Assert.Equal(Vector512.Count - 1, Vector512.LastIndexOf(input2.WithElement(0, value1), value2)); + Assert.Equal(-1, Vector512.LastIndexOf(input1, value2)); + Assert.Equal(-1, Vector512.LastIndexOf(input2, value1)); + Assert.Equal(0, Vector512.LastIndexOf(input1.WithElement(0, value2), value2)); + Assert.Equal(0, Vector512.LastIndexOf(input2.WithElement(0, value1), value1)); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void CountIndexOfLastIndexOfTest_IFloatingPointIeee754(T value) + where T : struct, IFloatingPointIeee754 + { + var input = Vector512.Create(value); + + Assert.Equal(0, Vector512.Count(input, value)); + Assert.Equal(-1, Vector512.IndexOf(input, value)); + Assert.Equal(-1, Vector512.LastIndexOf(input, value)); + } + + [Fact] + public void CountIndexOfLastIndexOfByteTest() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfDoubleTest() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfDoubleTest_AllBitsSet() => CountIndexOfLastIndexOfTest_IFloatingPointIeee754(BitConverter.Int64BitsToDouble(-1)); + + [Fact] + public void CountIndexOfLastIndexOfInt16Test() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfInt32Test() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfInt64Test() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfSByteTest() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfSingleTest() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfSingleTest_AllBitsSet() => CountIndexOfLastIndexOfTest_IFloatingPointIeee754(BitConverter.Int32BitsToSingle(-1)); + + [Fact] + public void CountIndexOfLastIndexOfUInt16Test() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfUInt32Test() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfUInt64Test() => CountIndexOfLastIndexOfTest(3, 2); + + [MethodImpl(MethodImplOptions.NoInlining)] + private void CountIndexOfLastIndexOfWhereAllBitsSetTest(T allBitsSet, T value2) + where T : struct, INumber + { + var input1 = Vector512.Create(allBitsSet); + var input2 = Vector512.Create(value2); + + Assert.Equal(Vector512.Count, Vector512.CountWhereAllBitsSet(input1)); + Assert.Equal(0, Vector512.CountWhereAllBitsSet(input2)); + Assert.Equal(Vector512.Count - 1, Vector512.CountWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.Equal(1, Vector512.CountWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + + Assert.Equal(0, Vector512.IndexOfWhereAllBitsSet(input1)); + Assert.Equal(-1, Vector512.IndexOfWhereAllBitsSet(input2)); + Assert.Equal(1, Vector512.IndexOfWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.Equal(0, Vector512.IndexOfWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + + Assert.Equal(Vector512.Count - 1, Vector512.LastIndexOfWhereAllBitsSet(input1)); + Assert.Equal(-1, Vector512.LastIndexOfWhereAllBitsSet(input2)); + Assert.Equal(Vector512.Count - 1, Vector512.LastIndexOfWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.Equal(0, Vector512.LastIndexOfWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + } + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetByteTest() => CountIndexOfLastIndexOfWhereAllBitsSetTest(byte.MaxValue, 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetDoubleTest() => CountIndexOfLastIndexOfWhereAllBitsSetTest(BitConverter.Int64BitsToDouble(-1), 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetInt16Test() => CountIndexOfLastIndexOfWhereAllBitsSetTest(-1, 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetInt32Test() => CountIndexOfLastIndexOfWhereAllBitsSetTest(-1, 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetInt64Test() => CountIndexOfLastIndexOfWhereAllBitsSetTest(-1, 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetSByteTest() => CountIndexOfLastIndexOfWhereAllBitsSetTest(-1, 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetSingleTest() => CountIndexOfLastIndexOfWhereAllBitsSetTest(BitConverter.Int32BitsToSingle(-1), 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetUInt16Test() => CountIndexOfLastIndexOfWhereAllBitsSetTest(ushort.MaxValue, 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetUInt32Test() => CountIndexOfLastIndexOfWhereAllBitsSetTest(uint.MaxValue, 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetUInt64Test() => CountIndexOfLastIndexOfWhereAllBitsSetTest(ulong.MaxValue, 2); } } diff --git a/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector64Tests.cs b/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector64Tests.cs index c049c08515a083..9cdbc25be4a723 100644 --- a/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector64Tests.cs +++ b/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector64Tests.cs @@ -3,6 +3,7 @@ using System.Numerics; using System.Reflection; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Tests; using Xunit; @@ -3930,9 +3931,9 @@ public void Vector64DoubleEqualsNonCanonicalNaNTest() }; // all Vector NaNs .Equals compare the same, but == compare as different - foreach(var i in nans) + foreach (var i in nans) { - foreach(var j in nans) + foreach (var j in nans) { Assert.True(Vector64.Create(i).Equals(Vector64.Create(j))); Assert.False(Vector64.Create(i) == Vector64.Create(j)); @@ -3954,9 +3955,9 @@ public void Vector64SingleEqualsNonCanonicalNaNTest() }; // all Vector NaNs .Equals compare the same, but == compare as different - foreach(var i in nans) + foreach (var i in nans) { - foreach(var j in nans) + foreach (var j in nans) { Assert.True(Vector64.Create(i).Equals(Vector64.Create(j))); Assert.False(Vector64.Create(i) == Vector64.Create(j)); @@ -4474,76 +4475,604 @@ public void HypotSingleTest(float x, float y, float expectedResult, float varian AssertEqual(Vector64.Create(expectedResult), Vector64.Hypot(Vector64.Create(+y), Vector64.Create(+x)), Vector64.Create(variance)); } + private void IsEvenInteger(T value) + where T : INumber + { + Assert.Equal(T.IsEvenInteger(value) ? Vector64.AllBitsSet : Vector64.Zero, Vector64.IsEvenInteger(Vector64.Create(value))); + } + [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsNaNDouble), MemberType = typeof(GenericMathTestMemberData))] - public void IsNaNDoubleTest(double value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerByteTest(byte value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerDoubleTest(double value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerInt16Test(short value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerInt32Test(int value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerInt64Test(long value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerSByteTest(sbyte value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerSingleTest(float value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerUInt16Test(ushort value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerUInt32Test(uint value) => IsEvenInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsEvenIntegerUInt64Test(ulong value) => IsEvenInteger(value); + + private void IsFinite(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector64.AllBitsSet : Vector64.Zero, Vector64.IsNaN(Vector64.Create(value))); + Assert.Equal(T.IsFinite(value) ? Vector64.AllBitsSet : Vector64.Zero, Vector64.IsFinite(Vector64.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsNaNSingle), MemberType = typeof(GenericMathTestMemberData))] - public void IsNaNSingleTest(float value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteByteTest(byte value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteDoubleTest(double value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteInt16Test(short value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteInt32Test(int value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteInt64Test(long value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteSByteTest(sbyte value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteSingleTest(float value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteUInt16Test(ushort value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteUInt32Test(uint value) => IsFinite(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsFiniteUInt64Test(ulong value) => IsFinite(value); + + private void IsInfinity(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector64.AllBitsSet : Vector64.Zero, Vector64.IsNaN(Vector64.Create(value))); + Assert.Equal(T.IsInfinity(value) ? Vector64.AllBitsSet : Vector64.Zero, Vector64.IsInfinity(Vector64.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsNegativeDouble), MemberType = typeof(GenericMathTestMemberData))] - public void IsNegativeDoubleTest(double value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityByteTest(byte value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityDoubleTest(double value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityInt16Test(short value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityInt32Test(int value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityInt64Test(long value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinitySByteTest(sbyte value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinitySingleTest(float value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityUInt16Test(ushort value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityUInt32Test(uint value) => IsInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsInfinityUInt64Test(ulong value) => IsInfinity(value); + + private void IsInteger(T value) + where T : INumber + { + Assert.Equal(T.IsInteger(value) ? Vector64.AllBitsSet : Vector64.Zero, Vector64.IsInteger(Vector64.Create(value))); + } + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerByteTest(byte value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerDoubleTest(double value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerInt16Test(short value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerInt32Test(int value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerInt64Test(long value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerSByteTest(sbyte value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerSingleTest(float value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerUInt16Test(ushort value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerUInt32Test(uint value) => IsInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsIntegerUInt64Test(ulong value) => IsInteger(value); + + private void IsNaN(T value) + where T : INumber + { + Assert.Equal(T.IsNaN(value) ? Vector64.AllBitsSet : Vector64.Zero, Vector64.IsNaN(Vector64.Create(value))); + } + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNByteTest(byte value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNDoubleTest(double value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNInt16Test(short value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNInt32Test(int value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNInt64Test(long value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNSByteTest(sbyte value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNSingleTest(float value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNUInt16Test(ushort value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNUInt32Test(uint value) => IsNaN(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsNaNUInt64Test(ulong value) => IsNaN(value); + + private void IsNegative(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector64.AllBitsSet : Vector64.Zero, Vector64.IsNegative(Vector64.Create(value))); + Assert.Equal(T.IsNegative(value) ? Vector64.AllBitsSet : Vector64.Zero, Vector64.IsNegative(Vector64.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsNegativeSingle), MemberType = typeof(GenericMathTestMemberData))] - public void IsNegativeSingleTest(float value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeByteTest(byte value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeDoubleTest(double value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInt16Test(short value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInt32Test(int value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInt64Test(long value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeSByteTest(sbyte value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeSingleTest(float value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeUInt16Test(ushort value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeUInt32Test(uint value) => IsNegative(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeUInt64Test(ulong value) => IsNegative(value); + + private void IsNegativeInfinity(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector64.AllBitsSet : Vector64.Zero, Vector64.IsNegative(Vector64.Create(value))); + Assert.Equal(T.IsNegativeInfinity(value) ? Vector64.AllBitsSet : Vector64.Zero, Vector64.IsNegativeInfinity(Vector64.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsPositiveDouble), MemberType = typeof(GenericMathTestMemberData))] - public void IsPositiveDoubleTest(double value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityByteTest(byte value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityDoubleTest(double value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityInt16Test(short value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityInt32Test(int value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityInt64Test(long value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinitySByteTest(sbyte value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinitySingleTest(float value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityUInt16Test(ushort value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityUInt32Test(uint value) => IsNegativeInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsNegativeInfinityUInt64Test(ulong value) => IsNegativeInfinity(value); + + private void IsNormal(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector64.AllBitsSet : Vector64.Zero, Vector64.IsPositive(Vector64.Create(value))); + Assert.Equal(T.IsNormal(value) ? Vector64.AllBitsSet : Vector64.Zero, Vector64.IsNormal(Vector64.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsPositiveSingle), MemberType = typeof(GenericMathTestMemberData))] - public void IsPositiveSingleTest(float value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalByteTest(byte value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalDoubleTest(double value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalInt16Test(short value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalInt32Test(int value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalInt64Test(long value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalSByteTest(sbyte value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalSingleTest(float value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalUInt16Test(ushort value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalUInt32Test(uint value) => IsNormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsNormalUInt64Test(ulong value) => IsNormal(value); + + private void IsOddInteger(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector64.AllBitsSet : Vector64.Zero, Vector64.IsPositive(Vector64.Create(value))); + Assert.Equal(T.IsOddInteger(value) ? Vector64.AllBitsSet : Vector64.Zero, Vector64.IsOddInteger(Vector64.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsPositiveInfinityDouble), MemberType = typeof(GenericMathTestMemberData))] - public void IsPositiveInfinityDoubleTest(double value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerByteTest(byte value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerDoubleTest(double value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerInt16Test(short value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerInt32Test(int value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerInt64Test(long value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerSByteTest(sbyte value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerSingleTest(float value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerUInt16Test(ushort value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerUInt32Test(uint value) => IsOddInteger(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsOddIntegerUInt64Test(ulong value) => IsOddInteger(value); + + private void IsPositive(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector64.AllBitsSet : Vector64.Zero, Vector64.IsPositiveInfinity(Vector64.Create(value))); + Assert.Equal(T.IsPositive(value) ? Vector64.AllBitsSet : Vector64.Zero, Vector64.IsPositive(Vector64.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsPositiveInfinitySingle), MemberType = typeof(GenericMathTestMemberData))] - public void IsPositiveInfinitySingleTest(float value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveByteTest(byte value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveDoubleTest(double value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInt16Test(short value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInt32Test(int value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInt64Test(long value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveSByteTest(sbyte value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveSingleTest(float value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveUInt16Test(ushort value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveUInt32Test(uint value) => IsPositive(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveUInt64Test(ulong value) => IsPositive(value); + + private void IsPositiveInfinity(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector64.AllBitsSet : Vector64.Zero, Vector64.IsPositiveInfinity(Vector64.Create(value))); + Assert.Equal(T.IsPositiveInfinity(value) ? Vector64.AllBitsSet : Vector64.Zero, Vector64.IsPositiveInfinity(Vector64.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsZeroDouble), MemberType = typeof(GenericMathTestMemberData))] - public void IsZeroDoubleTest(double value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityByteTest(byte value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityDoubleTest(double value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityInt16Test(short value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityInt32Test(int value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityInt64Test(long value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinitySByteTest(sbyte value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinitySingleTest(float value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityUInt16Test(ushort value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityUInt32Test(uint value) => IsPositiveInfinity(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsPositiveInfinityUInt64Test(ulong value) => IsPositiveInfinity(value); + + private void IsSubnormal(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector64.AllBitsSet : Vector64.Zero, Vector64.IsZero(Vector64.Create(value))); + Assert.Equal(T.IsSubnormal(value) ? Vector64.AllBitsSet : Vector64.Zero, Vector64.IsSubnormal(Vector64.Create(value))); } [Theory] - [MemberData(nameof(GenericMathTestMemberData.IsZeroSingle), MemberType = typeof(GenericMathTestMemberData))] - public void IsZeroSingleTest(float value, bool expectedResult) + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalByteTest(byte value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalDoubleTest(double value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalInt16Test(short value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalInt32Test(int value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalInt64Test(long value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalSByteTest(sbyte value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalSingleTest(float value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalUInt16Test(ushort value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalUInt32Test(uint value) => IsSubnormal(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsSubnormalUInt64Test(ulong value) => IsSubnormal(value); + + private void IsZero(T value) + where T : INumber { - Assert.Equal(expectedResult ? Vector64.AllBitsSet : Vector64.Zero, Vector64.IsZero(Vector64.Create(value))); + Assert.Equal(T.IsZero(value) ? Vector64.AllBitsSet : Vector64.Zero, Vector64.IsZero(Vector64.Create(value))); } + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroByteTest(byte value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestDouble), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroDoubleTest(double value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroInt16Test(short value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroInt32Test(int value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroInt64Test(long value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSByte), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroSByteTest(sbyte value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestSingle), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroSingleTest(float value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt16), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroUInt16Test(ushort value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt32), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroUInt32Test(uint value) => IsZero(value); + + [Theory] + [MemberData(nameof(GenericMathTestMemberData.IsTestUInt64), MemberType = typeof(GenericMathTestMemberData))] + public void IsZeroUInt64Test(ulong value) => IsZero(value); + [Theory] [MemberData(nameof(GenericMathTestMemberData.LerpDouble), MemberType = typeof(GenericMathTestMemberData))] public void LerpDoubleTest(double x, double y, double amount, double expectedResult) @@ -4801,5 +5330,275 @@ public void TruncateSingleTest(float value, float expectedResult) Vector64 actualResult = Vector64.Truncate(Vector64.Create(value)); AssertEqual(Vector64.Create(expectedResult), actualResult, Vector64.Zero); } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void AllAnyNoneTest(T value1, T value2) + where T : struct, INumber + { + var input1 = Vector64.Create(value1); + var input2 = Vector64.Create(value2); + + Assert.True(Vector64.All(input1, value1)); + Assert.True(Vector64.All(input2, value2)); + Assert.False(Vector64.All(input1.WithElement(0, value2), value1)); + Assert.False(Vector64.All(input2.WithElement(0, value1), value2)); + Assert.False(Vector64.All(input1, value2)); + Assert.False(Vector64.All(input2, value1)); + Assert.Equal(Vector64.Count == 1, Vector64.All(input1.WithElement(0, value2), value2)); + Assert.Equal(Vector64.Count == 1, Vector64.All(input2.WithElement(0, value1), value1)); + + Assert.True(Vector64.Any(input1, value1)); + Assert.True(Vector64.Any(input2, value2)); + Assert.Equal(Vector64.Count != 1, Vector64.Any(input1.WithElement(0, value2), value1)); + Assert.Equal(Vector64.Count != 1, Vector64.Any(input2.WithElement(0, value1), value2)); + Assert.False(Vector64.Any(input1, value2)); + Assert.False(Vector64.Any(input2, value1)); + Assert.True(Vector64.Any(input1.WithElement(0, value2), value2)); + Assert.True(Vector64.Any(input2.WithElement(0, value1), value1)); + + Assert.False(Vector64.None(input1, value1)); + Assert.False(Vector64.None(input2, value2)); + Assert.Equal(Vector64.Count == 1, Vector64.None(input1.WithElement(0, value2), value1)); + Assert.Equal(Vector64.Count == 1, Vector64.None(input2.WithElement(0, value1), value2)); + Assert.True(Vector64.None(input1, value2)); + Assert.True(Vector64.None(input2, value1)); + Assert.False(Vector64.None(input1.WithElement(0, value2), value2)); + Assert.False(Vector64.None(input2.WithElement(0, value1), value1)); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void AllAnyNoneTest_IFloatingPointIeee754(T value) + where T : struct, IFloatingPointIeee754 + { + var input = Vector64.Create(value); + + Assert.False(Vector64.All(input, value)); + Assert.False(Vector64.Any(input, value)); + Assert.True(Vector64.None(input, value)); + } + + [Fact] + public void AllAnyNoneByteTest() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneDoubleTest() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneDoubleTest_AllBitsSet() => AllAnyNoneTest_IFloatingPointIeee754(BitConverter.Int64BitsToDouble(-1)); + + [Fact] + public void AllAnyNoneInt16Test() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneInt32Test() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneInt64Test() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneSByteTest() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneSingleTest() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneSingleTest_AllBitsSet() => AllAnyNoneTest_IFloatingPointIeee754(BitConverter.Int32BitsToSingle(-1)); + + [Fact] + public void AllAnyNoneUInt16Test() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneUInt32Test() => AllAnyNoneTest(3, 2); + + [Fact] + public void AllAnyNoneUInt64Test() => AllAnyNoneTest(3, 2); + + [MethodImpl(MethodImplOptions.NoInlining)] + private void AllAnyNoneWhereAllBitsSetTest(T allBitsSet, T value2) + where T : struct, INumber + { + var input1 = Vector64.Create(allBitsSet); + var input2 = Vector64.Create(value2); + + Assert.True(Vector64.AllWhereAllBitsSet(input1)); + Assert.False(Vector64.AllWhereAllBitsSet(input2)); + Assert.False(Vector64.AllWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.Equal(Vector64.Count == 1, Vector64.AllWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + + Assert.True(Vector64.AnyWhereAllBitsSet(input1)); + Assert.False(Vector64.AnyWhereAllBitsSet(input2)); + Assert.Equal(Vector64.Count != 1, Vector64.AnyWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.True(Vector64.AnyWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + + Assert.False(Vector64.NoneWhereAllBitsSet(input1)); + Assert.True(Vector64.NoneWhereAllBitsSet(input2)); + Assert.Equal(Vector64.Count == 1, Vector64.NoneWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.False(Vector64.NoneWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + } + + [Fact] + public void AllAnyNoneWhereAllBitsSetByteTest() => AllAnyNoneWhereAllBitsSetTest(byte.MaxValue, 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetDoubleTest() => AllAnyNoneWhereAllBitsSetTest(BitConverter.Int64BitsToDouble(-1), 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetInt16Test() => AllAnyNoneWhereAllBitsSetTest(-1, 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetInt32Test() => AllAnyNoneWhereAllBitsSetTest(-1, 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetInt64Test() => AllAnyNoneWhereAllBitsSetTest(-1, 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetSByteTest() => AllAnyNoneWhereAllBitsSetTest(-1, 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetSingleTest() => AllAnyNoneWhereAllBitsSetTest(BitConverter.Int32BitsToSingle(-1), 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetUInt16Test() => AllAnyNoneWhereAllBitsSetTest(ushort.MaxValue, 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetUInt32Test() => AllAnyNoneWhereAllBitsSetTest(uint.MaxValue, 2); + + [Fact] + public void AllAnyNoneWhereAllBitsSetUInt64Test() => AllAnyNoneWhereAllBitsSetTest(ulong.MaxValue, 2); + + [MethodImpl(MethodImplOptions.NoInlining)] + private void CountIndexOfLastIndexOfTest(T value1, T value2) + where T : struct, INumber + { + var input1 = Vector64.Create(value1); + var input2 = Vector64.Create(value2); + + Assert.Equal(Vector64.Count, Vector64.Count(input1, value1)); + Assert.Equal(Vector64.Count, Vector64.Count(input2, value2)); + Assert.Equal(Vector64.Count - 1, Vector64.Count(input1.WithElement(0, value2), value1)); + Assert.Equal(Vector64.Count - 1, Vector64.Count(input2.WithElement(0, value1), value2)); + Assert.Equal(0, Vector64.Count(input1, value2)); + Assert.Equal(0, Vector64.Count(input2, value1)); + Assert.Equal(1, Vector64.Count(input1.WithElement(0, value2), value2)); + Assert.Equal(1, Vector64.Count(input2.WithElement(0, value1), value1)); + + Assert.Equal(0, Vector64.IndexOf(input1, value1)); + Assert.Equal(0, Vector64.IndexOf(input2, value2)); + Assert.Equal((Vector64.Count != 1) ? 1 : -1, Vector64.IndexOf(input1.WithElement(0, value2), value1)); + Assert.Equal((Vector64.Count != 1) ? 1 : -1, Vector64.IndexOf(input2.WithElement(0, value1), value2)); + Assert.Equal(-1, Vector64.IndexOf(input1, value2)); + Assert.Equal(-1, Vector64.IndexOf(input2, value1)); + Assert.Equal(0, Vector64.IndexOf(input1.WithElement(0, value2), value2)); + Assert.Equal(0, Vector64.IndexOf(input2.WithElement(0, value1), value1)); + + Assert.Equal(Vector64.Count - 1, Vector64.LastIndexOf(input1, value1)); + Assert.Equal(Vector64.Count - 1, Vector64.LastIndexOf(input2, value2)); + Assert.Equal((Vector64.Count != 1) ? Vector64.Count - 1 : -1, Vector64.LastIndexOf(input1.WithElement(0, value2), value1)); + Assert.Equal((Vector64.Count != 1) ? Vector64.Count - 1 : -1, Vector64.LastIndexOf(input2.WithElement(0, value1), value2)); + Assert.Equal(-1, Vector64.LastIndexOf(input1, value2)); + Assert.Equal(-1, Vector64.LastIndexOf(input2, value1)); + Assert.Equal(0, Vector64.LastIndexOf(input1.WithElement(0, value2), value2)); + Assert.Equal(0, Vector64.LastIndexOf(input2.WithElement(0, value1), value1)); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void CountIndexOfLastIndexOfTest_IFloatingPointIeee754(T value) + where T : struct, IFloatingPointIeee754 + { + var input = Vector64.Create(value); + + Assert.Equal(0, Vector64.Count(input, value)); + Assert.Equal(-1, Vector64.IndexOf(input, value)); + Assert.Equal(-1, Vector64.LastIndexOf(input, value)); + } + + [Fact] + public void CountIndexOfLastIndexOfByteTest() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfDoubleTest() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfDoubleTest_AllBitsSet() => CountIndexOfLastIndexOfTest_IFloatingPointIeee754(BitConverter.Int64BitsToDouble(-1)); + + [Fact] + public void CountIndexOfLastIndexOfInt16Test() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfInt32Test() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfInt64Test() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfSByteTest() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfSingleTest() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfSingleTest_AllBitsSet() => CountIndexOfLastIndexOfTest_IFloatingPointIeee754(BitConverter.Int32BitsToSingle(-1)); + + [Fact] + public void CountIndexOfLastIndexOfUInt16Test() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfUInt32Test() => CountIndexOfLastIndexOfTest(3, 2); + + [Fact] + public void CountIndexOfLastIndexOfUInt64Test() => CountIndexOfLastIndexOfTest(3, 2); + + [MethodImpl(MethodImplOptions.NoInlining)] + private void CountIndexOfLastIndexOfWhereAllBitsSetTest(T allBitsSet, T value2) + where T : struct, INumber + { + var input1 = Vector64.Create(allBitsSet); + var input2 = Vector64.Create(value2); + + Assert.Equal(Vector64.Count, Vector64.CountWhereAllBitsSet(input1)); + Assert.Equal(0, Vector64.CountWhereAllBitsSet(input2)); + Assert.Equal(Vector64.Count - 1, Vector64.CountWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.Equal(1, Vector64.CountWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + + Assert.Equal(0, Vector64.IndexOfWhereAllBitsSet(input1)); + Assert.Equal(-1, Vector64.IndexOfWhereAllBitsSet(input2)); + Assert.Equal((Vector64.Count != 1) ? 1 : -1, Vector64.IndexOfWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.Equal(0, Vector64.IndexOfWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + + Assert.Equal(Vector64.Count - 1, Vector64.LastIndexOfWhereAllBitsSet(input1)); + Assert.Equal(-1, Vector64.LastIndexOfWhereAllBitsSet(input2)); + Assert.Equal((Vector64.Count != 1) ? Vector64.Count - 1 : -1, Vector64.LastIndexOfWhereAllBitsSet(input1.WithElement(0, value2))); + Assert.Equal(0, Vector64.LastIndexOfWhereAllBitsSet(input2.WithElement(0, allBitsSet))); + } + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetByteTest() => CountIndexOfLastIndexOfWhereAllBitsSetTest(byte.MaxValue, 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetDoubleTest() => CountIndexOfLastIndexOfWhereAllBitsSetTest(BitConverter.Int64BitsToDouble(-1), 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetInt16Test() => CountIndexOfLastIndexOfWhereAllBitsSetTest(-1, 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetInt32Test() => CountIndexOfLastIndexOfWhereAllBitsSetTest(-1, 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetInt64Test() => CountIndexOfLastIndexOfWhereAllBitsSetTest(-1, 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetSByteTest() => CountIndexOfLastIndexOfWhereAllBitsSetTest(-1, 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetSingleTest() => CountIndexOfLastIndexOfWhereAllBitsSetTest(BitConverter.Int32BitsToSingle(-1), 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetUInt16Test() => CountIndexOfLastIndexOfWhereAllBitsSetTest(ushort.MaxValue, 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetUInt32Test() => CountIndexOfLastIndexOfWhereAllBitsSetTest(uint.MaxValue, 2); + + [Fact] + public void CountIndexOfLastIndexOfWhereAllBitsSetUInt64Test() => CountIndexOfLastIndexOfWhereAllBitsSetTest(ulong.MaxValue, 2); } } diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index af640b0339a443..a71de86ad971a0 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -2414,6 +2414,7 @@ public DivideByZeroException(string? message, System.Exception? innerException) public static double Cbrt(double x) { throw null; } public static double Ceiling(double x) { throw null; } public static double Clamp(double value, double min, double max) { throw null; } + public static double ClampNative(double value, double min, double max) { throw null; } public int CompareTo(double value) { throw null; } public int CompareTo(object? value) { throw null; } public static TInteger ConvertToIntegerNative(double value) where TInteger : System.Numerics.IBinaryInteger { throw null; } @@ -2466,10 +2467,12 @@ public DivideByZeroException(string? message, System.Exception? innerException) public static double Max(double x, double y) { throw null; } public static double MaxMagnitude(double x, double y) { throw null; } public static double MaxMagnitudeNumber(double x, double y) { throw null; } + public static double MaxNative(double x, double y) { throw null; } public static double MaxNumber(double x, double y) { throw null; } public static double Min(double x, double y) { throw null; } public static double MinMagnitude(double x, double y) { throw null; } public static double MinMagnitudeNumber(double x, double y) { throw null; } + public static double MinNative(double x, double y) { throw null; } public static double MinNumber(double x, double y) { throw null; } public static double MultiplyAddEstimate(double left, double right, double addend) { throw null; } public static bool operator ==(double left, double right) { throw null; } @@ -3226,6 +3229,7 @@ public enum GCNotificationStatus public static System.Half Cbrt(System.Half x) { throw null; } public static System.Half Ceiling(System.Half x) { throw null; } public static System.Half Clamp(System.Half value, System.Half min, System.Half max) { throw null; } + public static System.Half ClampNative(System.Half value, System.Half min, System.Half max) { throw null; } public int CompareTo(System.Half other) { throw null; } public int CompareTo(object? obj) { throw null; } public static TInteger ConvertToIntegerNative(System.Half value) where TInteger : System.Numerics.IBinaryInteger { throw null; } @@ -3277,10 +3281,12 @@ public enum GCNotificationStatus public static System.Half Max(System.Half x, System.Half y) { throw null; } public static System.Half MaxMagnitude(System.Half x, System.Half y) { throw null; } public static System.Half MaxMagnitudeNumber(System.Half x, System.Half y) { throw null; } + public static System.Half MaxNative(System.Half x, System.Half y) { throw null; } public static System.Half MaxNumber(System.Half x, System.Half y) { throw null; } public static System.Half Min(System.Half x, System.Half y) { throw null; } public static System.Half MinMagnitude(System.Half x, System.Half y) { throw null; } public static System.Half MinMagnitudeNumber(System.Half x, System.Half y) { throw null; } + public static System.Half MinNative(System.Half x, System.Half y) { throw null; } public static System.Half MinNumber(System.Half x, System.Half y) { throw null; } public static System.Half MultiplyAddEstimate(System.Half left, System.Half right, System.Half addend) { throw null; } public static System.Half operator +(System.Half left, System.Half right) { throw null; } @@ -5359,6 +5365,7 @@ public SerializableAttribute() { } public static float Cbrt(float x) { throw null; } public static float Ceiling(float x) { throw null; } public static float Clamp(float value, float min, float max) { throw null; } + public static float ClampNative(float value, float min, float max) { throw null; } public int CompareTo(object? value) { throw null; } public int CompareTo(float value) { throw null; } public static TInteger ConvertToIntegerNative(float value) where TInteger : System.Numerics.IBinaryInteger { throw null; } @@ -5411,10 +5418,12 @@ public SerializableAttribute() { } public static float Max(float x, float y) { throw null; } public static float MaxMagnitude(float x, float y) { throw null; } public static float MaxMagnitudeNumber(float x, float y) { throw null; } + public static float MaxNative(float x, float y) { throw null; } public static float MaxNumber(float x, float y) { throw null; } public static float Min(float x, float y) { throw null; } public static float MinMagnitude(float x, float y) { throw null; } public static float MinMagnitudeNumber(float x, float y) { throw null; } + public static float MinNative(float x, float y) { throw null; } public static float MinNumber(float x, float y) { throw null; } public static float MultiplyAddEstimate(float left, float right, float addend) { throw null; } public static bool operator ==(float left, float right) { throw null; } @@ -11459,10 +11468,13 @@ protected static abstract bool TryConvertToTruncating(TSelf value, [Syst public partial interface INumber : System.IComparable, System.IComparable, System.IEquatable, System.IFormattable, System.IParsable, System.ISpanFormattable, System.ISpanParsable, System.Numerics.IAdditionOperators, System.Numerics.IAdditiveIdentity, System.Numerics.IComparisonOperators, System.Numerics.IDecrementOperators, System.Numerics.IDivisionOperators, System.Numerics.IEqualityOperators, System.Numerics.IIncrementOperators, System.Numerics.IModulusOperators, System.Numerics.IMultiplicativeIdentity, System.Numerics.IMultiplyOperators, System.Numerics.INumberBase, System.Numerics.ISubtractionOperators, System.Numerics.IUnaryNegationOperators, System.Numerics.IUnaryPlusOperators where TSelf : System.Numerics.INumber? { static virtual TSelf Clamp(TSelf value, TSelf min, TSelf max) { throw null; } + static virtual TSelf ClampNative(TSelf value, TSelf min, TSelf max) { throw null; } static virtual TSelf CopySign(TSelf value, TSelf sign) { throw null; } static virtual TSelf Max(TSelf x, TSelf y) { throw null; } + static virtual TSelf MaxNative(TSelf x, TSelf y) { throw null; } static virtual TSelf MaxNumber(TSelf x, TSelf y) { throw null; } static virtual TSelf Min(TSelf x, TSelf y) { throw null; } + static virtual TSelf MinNative(TSelf x, TSelf y) { throw null; } static virtual TSelf MinNumber(TSelf x, TSelf y) { throw null; } static virtual int Sign(TSelf value) { throw null; } } diff --git a/src/mono/mono/mini/interp/transform-simd.c b/src/mono/mono/mini/interp/transform-simd.c index c1d6b81019d02f..a9c0a697e4ee9d 100644 --- a/src/mono/mono/mini/interp/transform-simd.c +++ b/src/mono/mono/mini/interp/transform-simd.c @@ -567,12 +567,13 @@ emit_sri_vector128 (TransformData *td, MonoMethod *cmethod, MonoMethodSignature if (atype == MONO_TYPE_U1) simd_intrins = INTERP_SIMD_INTRINSIC_V128_U1_NARROW; break; case SN_ShiftLeft: - g_assert (scalar_arg == 1); - simd_opcode = MINT_SIMD_INTRINS_P_PP; - if (arg_size == 1) simd_intrins = INTERP_SIMD_INTRINSIC_V128_I1_LEFT_SHIFT; - else if (arg_size == 2) simd_intrins = INTERP_SIMD_INTRINSIC_V128_I2_LEFT_SHIFT; - else if (arg_size == 4) simd_intrins = INTERP_SIMD_INTRINSIC_V128_I4_LEFT_SHIFT; - else if (arg_size == 8) simd_intrins = INTERP_SIMD_INTRINSIC_V128_I8_LEFT_SHIFT; + if (scalar_arg == 1) { + simd_opcode = MINT_SIMD_INTRINS_P_PP; + if (arg_size == 1) simd_intrins = INTERP_SIMD_INTRINSIC_V128_I1_LEFT_SHIFT; + else if (arg_size == 2) simd_intrins = INTERP_SIMD_INTRINSIC_V128_I2_LEFT_SHIFT; + else if (arg_size == 4) simd_intrins = INTERP_SIMD_INTRINSIC_V128_I4_LEFT_SHIFT; + else if (arg_size == 8) simd_intrins = INTERP_SIMD_INTRINSIC_V128_I8_LEFT_SHIFT; + } break; case SN_ShiftRightLogical: g_assert (scalar_arg == 1); diff --git a/src/mono/mono/mini/simd-intrinsics.c b/src/mono/mono/mini/simd-intrinsics.c index 7a706fa49d0929..04123b3fe531c8 100644 --- a/src/mono/mono/mini/simd-intrinsics.c +++ b/src/mono/mono/mini/simd-intrinsics.c @@ -1638,10 +1638,18 @@ static guint16 sri_vector_methods [] = { SN_GreaterThanOrEqual, SN_GreaterThanOrEqualAll, SN_GreaterThanOrEqualAny, + SN_IsEvenInteger, + SN_IsFinite, + SN_IsInfinity, + SN_IsInteger, SN_IsNaN, SN_IsNegative, + SN_IsNegativeInfinity, + SN_IsNormal, + SN_IsOddInteger, SN_IsPositive, SN_IsPositiveInfinity, + SN_IsSubnormal, SN_IsZero, SN_LessThan, SN_LessThanAll, @@ -2395,13 +2403,28 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi case SN_ExtractMostSignificantBits: { if (!is_element_type_primitive (fsig->params [0])) return NULL; + + MonoClass *arg_class = mono_class_from_mono_type_internal (fsig->params [0]); + + if (fsig->params [0]->type != MONO_TYPE_GENERICINST) { + // This exists to handle the static extension methods for Vector2/3/4, Quaternion, and Plane + // which live on System.Numerics.Vector + + arg0_type = MONO_TYPE_R4; + } + + int size = mono_class_value_size (arg_class, NULL); + + if (size != 16) { + // FIXME: Add support for Vector2/3 + return NULL; + } #ifdef TARGET_WASM if (type_enum_is_float (arg0_type)) return NULL; return emit_simd_ins_for_sig (cfg, klass, OP_WASM_SIMD_BITMASK, -1, -1, fsig, args); #elif defined(TARGET_ARM64) - MonoClass* arg_class; if (type_enum_is_float (arg0_type)) { MonoClass* cast_class; if (arg0_type == MONO_TYPE_R4) { @@ -2411,15 +2434,23 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi arg0_type = MONO_TYPE_I8; cast_class = mono_defaults.int64_class; } - arg_class = create_class_instance ("System.Runtime.Intrinsics", m_class_get_name (klass), m_class_get_byval_arg (cast_class)); + + const char *klass_name = m_class_get_name (klass); + + if (!strcmp (klass_name, "Vector4")) { + klass_name = "Vector128`1"; + } + arg_class = create_class_instance ("System.Runtime.Intrinsics", klass_name, m_class_get_byval_arg (cast_class)); } else { arg_class = mono_class_from_mono_type_internal (fsig->params [0]); } - // FIXME: Add support for Vector64 on arm64 https://github.com/dotnet/runtime/issues/90402 - int size = mono_class_value_size (arg_class, NULL); - if (size != 16) + size = mono_class_value_size (arg_class, NULL); + + if (size != 16) { + // FIXME: Add support for Vector64 on arm64 https://github.com/dotnet/runtime/issues/90402 return NULL; + } MonoInst* msb_mask_vec = emit_msb_vector_mask (cfg, arg_class, arg0_type); MonoInst* and_res_vec = emit_simd_ins_for_binary_op (cfg, arg_class, fsig, args, arg0_type, SN_BitwiseAnd); @@ -2459,7 +2490,7 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi return NULL; type = type_enum_is_unsigned (arg0_type) ? MONO_TYPE_U1 : MONO_TYPE_I1; - MonoClass* arg_class = mono_class_from_mono_type_internal (fsig->params [0]); + arg_class = mono_class_from_mono_type_internal (fsig->params [0]); guint64 shuffle_mask[2]; shuffle_mask[0] = 0x0F0D0B0907050301; // Place odd bytes in the lower half of vector @@ -2504,18 +2535,25 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi return NULL; MonoClass *arg_class = mono_class_from_mono_type_internal (fsig->params [0]); + int esize; if (fsig->params [0]->type == MONO_TYPE_GENERICINST) { MonoType *etype = mono_class_get_context (arg_class)->class_inst->type_argv [0]; - int size = mono_class_value_size (arg_class, NULL); - int esize = mono_class_value_size (mono_class_from_mono_type_internal (etype), NULL); - elems = size / esize; + esize = mono_class_value_size (mono_class_from_mono_type_internal (etype), NULL); } else { // This exists to handle the static extension methods for Vector2/3/4, Quaternion, and Plane // which live on System.Numerics.Vector arg0_type = MONO_TYPE_R4; - elems = 4; + esize = 4; + } + + int size = mono_class_value_size (arg_class, NULL); + elems = size / esize; + + if (size != 16) { + // FIXME: Add support for Vector2/3 + return NULL; } if (args [1]->opcode == OP_ICONST) { @@ -2642,6 +2680,61 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi return ret; } } + case SN_IsEvenInteger: + case SN_IsOddInteger: { + if (!is_element_type_primitive (fsig->params [0])) + return NULL; + if (type_enum_is_float(arg0_type)) + return NULL; + + // TODO: This requires a centralized way for get_One() + // + // IsEvenInteger: + // x = And(x, get_One()) + // return IntEqCmp(x, zero) + // + // IsOddInteger + // x = And(x, get_One()) + // return IntNeCmp(x, zero) + + return NULL; + } + case SN_IsFinite: { + if (!is_element_type_primitive (fsig->params [0])) + return NULL; + if (!type_enum_is_float(arg0_type)) + return emit_xones (cfg, klass); + + // TODO: This requires a centralized way for AndNot(x, y) + // + // x = AndNot(PositiveInfinityBits, x) + // return IntNeCmp(x, zero) + + return NULL; + } + case SN_IsInfinity: { + // TODO: This requires a centralized way for Abs(x) and IsPositiveInfinity(x) + // + // x = Abs(x) + // return IsPositiveInfinity(x) + + return NULL; + } + case SN_IsInteger: { + if (!is_element_type_primitive (fsig->params [0])) + return NULL; + if (!type_enum_is_float(arg0_type)) + return emit_xones (cfg, klass); + + // TODO: This requires a centralized way for IsFinite(x) and Trunc(c) + // + // tmp1 = IsFinite(x) + // tmp2 = Trunc(x) + // tmp2 = FltEqCmp(x, tmp2) + // return And(tmp1, tmp2) + + return NULL; + } case SN_IsNaN: { if (!is_element_type_primitive (fsig->params [0])) return NULL; @@ -2695,30 +2788,79 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi } return ins; } + case SN_IsNegativeInfinity: case SN_IsPositiveInfinity: { if (!is_element_type_primitive (fsig->params [0])) return NULL; if (arg0_type == MONO_TYPE_R4) { guint32 value[4]; - value [0] = 0x7F800000; - value [1] = 0x7F800000; - value [2] = 0x7F800000; - value [3] = 0x7F800000; + if (id == SN_IsNegativeInfinity) + { + value [0] = 0xFF800000; + value [1] = 0xFF800000; + value [2] = 0xFF800000; + value [3] = 0xFF800000; + } + else + { + value [0] = 0x7F800000; + value [1] = 0x7F800000; + value [2] = 0x7F800000; + value [3] = 0x7F800000; + } MonoInst *arg1 = emit_xconst_v128 (cfg, klass, (guint8*)value); return emit_xcompare (cfg, klass, arg0_type, args [0], arg1); } else if (arg0_type == MONO_TYPE_R8) { guint64 value[2]; - value [0] = 0x7FF0000000000000; - value [1] = 0x7FF0000000000000; + if (id == SN_IsNegativeInfinity) + { + value [0] = 0xFFF0000000000000; + value [1] = 0xFFF0000000000000; + } + else + { + value [0] = 0x7FF0000000000000; + value [1] = 0x7FF0000000000000; + } MonoInst *arg1 = emit_xconst_v128 (cfg, klass, (guint8*)value); return emit_xcompare (cfg, klass, arg0_type, args [0], arg1); } return emit_xzero (cfg, klass); } + case SN_IsNormal: { + if (!is_element_type_primitive (fsig->params [0])) + return NULL; + if (!type_enum_is_float(arg0_type)) + return emit_not_xequal (cfg, klass, arg0_type, args [0], emit_xzero (cfg, klass)); + + // TODO: This requires a centralized way for Abs(x) + // and retyping from float to the same sized unsigned integer + // + // x = FltAbs(x) + // x = UIntSub(x, SmallestNormalBits) + // return UIntLtCmp(x, PositiveInfinityBits - SmallestNormalBits) + + return NULL; + } + case SN_IsSubnormal: { + if (!is_element_type_primitive (fsig->params [0])) + return NULL; + if (!type_enum_is_float(arg0_type)) + return emit_xzero (cfg, klass); + + // TODO: This requires a centralized way for Abs(x) + // and retyping from float to the same sized unsigned integer + // + // x = FltAbs(x) + // x = UIntSub(x, 1) + // return UIntLtCmp(x, MaxTrailingSignificand) + + return NULL; + } case SN_IsZero: { if (!is_element_type_primitive (fsig->params [0])) return NULL; @@ -3026,6 +3168,23 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi case SN_ToScalar: { if (!is_element_type_primitive (fsig->params [0])) return NULL; + + MonoClass *arg_class = mono_class_from_mono_type_internal (fsig->params [0]); + + if (fsig->params [0]->type != MONO_TYPE_GENERICINST) { + // This exists to handle the static extension methods for Vector2/3/4, Quaternion, and Plane + // which live on System.Numerics.Vector + + arg0_type = MONO_TYPE_R4; + } + + int size = mono_class_value_size (arg_class, NULL); + + if (size != 16) { + // FIXME: Add support for Vector2/3 + return NULL; + } + int extract_op = type_to_extract_op (arg0_type); return emit_simd_ins_for_sig (cfg, klass, extract_op, 0, arg0_type, fsig, args); } @@ -3043,18 +3202,25 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi return NULL; MonoClass *arg_class = mono_class_from_mono_type_internal (fsig->params [0]); + int esize; if (fsig->params [0]->type == MONO_TYPE_GENERICINST) { MonoType *etype = mono_class_get_context (arg_class)->class_inst->type_argv [0]; - int size = mono_class_value_size (arg_class, NULL); - int esize = mono_class_value_size (mono_class_from_mono_type_internal (etype), NULL); - elems = size / esize; + esize = mono_class_value_size (mono_class_from_mono_type_internal (etype), NULL); } else { // This exists to handle the static extension methods for Vector2/3/4, Quaternion, and Plane // which live on System.Numerics.Vector arg0_type = MONO_TYPE_R4; - elems = 4; + esize = 4; + } + + int size = mono_class_value_size (arg_class, NULL); + elems = size / esize; + + if (size != 16) { + // FIXME: Add support for Vector2/3 + return NULL; } if (args [1]->opcode == OP_ICONST) { @@ -6525,6 +6691,7 @@ emit_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi MonoInst* mono_emit_simd_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args) { + // TODO: We shouldn't be processing any methods which aren't marked [Intrinsic] return emit_intrinsics (cfg, cmethod, fsig, args, emit_simd_intrinsics); } diff --git a/src/mono/mono/mini/simd-methods.h b/src/mono/mono/mini/simd-methods.h index fd7f56e4c72009..b696931ce51e92 100644 --- a/src/mono/mono/mini/simd-methods.h +++ b/src/mono/mono/mini/simd-methods.h @@ -12,10 +12,18 @@ METHOD(GreaterThanAny) METHOD(GreaterThanOrEqual) METHOD(GreaterThanOrEqualAll) METHOD(GreaterThanOrEqualAny) +METHOD(IsEvenInteger) +METHOD(IsFinite) +METHOD(IsInfinity) +METHOD(IsInteger) METHOD(IsNaN) METHOD(IsNegative) +METHOD(IsNegativeInfinity) +METHOD(IsNormal) +METHOD(IsOddInteger) METHOD(IsPositive) METHOD(IsPositiveInfinity) +METHOD(IsSubnormal) METHOD(IsZero) METHOD(LessThan) METHOD(LessThanAll)