diff --git a/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj b/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj
index 2b656cc1d3ee5..8eef4ed0de9c8 100644
--- a/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj
+++ b/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj
@@ -97,9 +97,11 @@
+
+
diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.Single.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.Single.cs
index ae6df0ed43f5c..a8d4c6815ca40 100644
--- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.Single.cs
+++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.Single.cs
@@ -440,7 +440,7 @@ public static float Max(ReadOnlySpan x) =>
///
///
public static void Max(ReadOnlySpan x, ReadOnlySpan y, Span destination) =>
- InvokeSpanSpanIntoSpan(x, y, destination);
+ InvokeSpanSpanIntoSpan(x, y, destination);
/// Searches for the single-precision floating-point number with the largest magnitude in the specified tensor.
/// The tensor, represented as a span.
@@ -476,7 +476,7 @@ public static float MaxMagnitude(ReadOnlySpan x) =>
///
///
public static void MaxMagnitude(ReadOnlySpan x, ReadOnlySpan y, Span destination) =>
- InvokeSpanSpanIntoSpan(x, y, destination);
+ InvokeSpanSpanIntoSpan(x, y, destination);
/// Searches for the smallest single-precision floating-point number in the specified tensor.
/// The tensor, represented as a span.
@@ -517,7 +517,7 @@ public static float Min(ReadOnlySpan x) =>
///
///
public static void Min(ReadOnlySpan x, ReadOnlySpan y, Span destination) =>
- InvokeSpanSpanIntoSpan(x, y, destination);
+ InvokeSpanSpanIntoSpan(x, y, destination);
/// Searches for the single-precision floating-point number with the smallest magnitude in the specified tensor.
/// The tensor, represented as a span.
@@ -558,7 +558,7 @@ public static float MinMagnitude(ReadOnlySpan x) =>
///
///
public static void MinMagnitude(ReadOnlySpan x, ReadOnlySpan y, Span destination) =>
- InvokeSpanSpanIntoSpan(x, y, destination);
+ InvokeSpanSpanIntoSpan(x, y, destination);
/// Computes the element-wise product of single-precision floating-point numbers in the specified tensors.
/// The first tensor, represented as a span.
diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.CopySign.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.CopySign.cs
index 0277c729a17aa..e914e271bd015 100644
--- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.CopySign.cs
+++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.CopySign.cs
@@ -47,6 +47,9 @@ public static void CopySign(ReadOnlySpan x, T sign, Span destination)
public static Vector128 Invoke(Vector128 x, Vector128 y)
{
+#if NET9_0_OR_GREATER
+ return Vector128.CopySign(x, y);
+#else
if (typeof(T) == typeof(float))
{
return Vector128.ConditionalSelect(Vector128.Create(-0.0f).As(), y, x);
@@ -71,10 +74,14 @@ public static Vector128 Invoke(Vector128 x, Vector128 y)
}
return x;
+#endif
}
public static Vector256 Invoke(Vector256 x, Vector256 y)
{
+#if NET9_0_OR_GREATER
+ return Vector256.CopySign(x, y);
+#else
if (typeof(T) == typeof(float))
{
return Vector256.ConditionalSelect(Vector256.Create(-0.0f).As(), y, x);
@@ -99,10 +106,14 @@ public static Vector256 Invoke(Vector256 x, Vector256 y)
}
return x;
+#endif
}
public static Vector512 Invoke(Vector512 x, Vector512 y)
{
+#if NET9_0_OR_GREATER
+ return Vector512.CopySign(x, y);
+#else
if (typeof(T) == typeof(float))
{
return Vector512.ConditionalSelect(Vector512.Create(-0.0f).As(), y, x);
@@ -127,6 +138,7 @@ public static Vector512 Invoke(Vector512 x, Vector512 y)
}
return x;
+#endif
}
}
}
diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.DegreesToRadians.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.DegreesToRadians.cs
index 27d11cf14ce72..bf21253c4436a 100644
--- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.DegreesToRadians.cs
+++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.DegreesToRadians.cs
@@ -1,6 +1,7 @@
// 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.Runtime.Intrinsics;
namespace System.Numerics.Tensors
@@ -25,10 +26,59 @@ public static void DegreesToRadians(ReadOnlySpan x, Span destination)
private readonly struct DegreesToRadiansOperator : IUnaryOperator where T : ITrigonometricFunctions
{
public static bool Vectorizable => true;
+
public static T Invoke(T x) => T.DegreesToRadians(x);
- public static Vector128 Invoke(Vector128 x) => (x * T.Pi) / T.CreateChecked(180);
- public static Vector256 Invoke(Vector256 x) => (x * T.Pi) / T.CreateChecked(180);
- public static Vector512 Invoke(Vector512 x) => (x * T.Pi) / T.CreateChecked(180);
+
+ public static Vector128 Invoke(Vector128 x)
+ {
+#if NET9_0_OR_GREATER
+ if (typeof(T) == typeof(double))
+ {
+ return Vector128.DegreesToRadians(x.AsDouble()).As();
+ }
+ else
+ {
+ Debug.Assert(typeof(T) == typeof(float));
+ return Vector128.DegreesToRadians(x.AsSingle()).As();
+ }
+#else
+ return (x * T.Pi) / T.CreateChecked(180);
+#endif
+ }
+
+ public static Vector256 Invoke(Vector256 x)
+ {
+#if NET9_0_OR_GREATER
+ if (typeof(T) == typeof(double))
+ {
+ return Vector256.DegreesToRadians(x.AsDouble()).As();
+ }
+ else
+ {
+ Debug.Assert(typeof(T) == typeof(float));
+ return Vector256.DegreesToRadians(x.AsSingle()).As();
+ }
+#else
+ return (x * T.Pi) / T.CreateChecked(180);
+#endif
+ }
+
+ public static Vector512 Invoke(Vector512 x)
+ {
+#if NET9_0_OR_GREATER
+ if (typeof(T) == typeof(double))
+ {
+ return Vector512.DegreesToRadians(x.AsDouble()).As();
+ }
+ else
+ {
+ Debug.Assert(typeof(T) == typeof(float));
+ return Vector512.DegreesToRadians(x.AsSingle()).As();
+ }
+#else
+ return (x * T.Pi) / T.CreateChecked(180);
+#endif
+ }
}
}
}
diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Hypot.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Hypot.cs
index f0c46347ac244..c806856672f90 100644
--- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Hypot.cs
+++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Hypot.cs
@@ -1,6 +1,7 @@
// 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.Runtime.Intrinsics;
namespace System.Numerics.Tensors
@@ -29,10 +30,59 @@ public static void Hypot(ReadOnlySpan x, ReadOnlySpan y, Span destin
where T : IRootFunctions
{
public static bool Vectorizable => true;
+
public static T Invoke(T x, T y) => T.Hypot(x, y);
- public static Vector128 Invoke(Vector128 x, Vector128 y) => Vector128.Sqrt((x * x) + (y * y));
- public static Vector256 Invoke(Vector256 x, Vector256 y) => Vector256.Sqrt((x * x) + (y * y));
- public static Vector512 Invoke(Vector512 x, Vector512 y) => Vector512.Sqrt((x * x) + (y * y));
+
+ public static Vector128 Invoke(Vector128 x, Vector128 y)
+ {
+#if NET9_0_OR_GREATER
+ if (typeof(T) == typeof(double))
+ {
+ return Vector128.Hypot(x.AsDouble(), y.AsDouble()).As();
+ }
+ else
+ {
+ Debug.Assert(typeof(T) == typeof(float));
+ return Vector128.Hypot(x.AsSingle(), y.AsSingle()).As();
+ }
+#else
+ return Vector128.Sqrt((x * x) + (y * y));
+#endif
+ }
+
+ public static Vector256 Invoke(Vector256 x, Vector256 y)
+ {
+#if NET9_0_OR_GREATER
+ if (typeof(T) == typeof(double))
+ {
+ return Vector256.Hypot(x.AsDouble(), y.AsDouble()).As();
+ }
+ else
+ {
+ Debug.Assert(typeof(T) == typeof(float));
+ return Vector256.Hypot(x.AsSingle(), y.AsSingle()).As();
+ }
+#else
+ return Vector256.Sqrt((x * x) + (y * y));
+#endif
+ }
+
+ public static Vector512 Invoke(Vector512 x, Vector512 y)
+ {
+#if NET9_0_OR_GREATER
+ if (typeof(T) == typeof(double))
+ {
+ return Vector512.Hypot(x.AsDouble(), y.AsDouble()).As();
+ }
+ else
+ {
+ Debug.Assert(typeof(T) == typeof(float));
+ return Vector512.Hypot(x.AsSingle(), y.AsSingle()).As();
+ }
+#else
+ return Vector512.Sqrt((x * x) + (y * y));
+#endif
+ }
}
}
}
diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Lerp.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Lerp.cs
index a605b62430d3f..f31b3e50f77d2 100644
--- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Lerp.cs
+++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Lerp.cs
@@ -1,6 +1,7 @@
// 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.Runtime.Intrinsics;
namespace System.Numerics.Tensors
@@ -75,9 +76,57 @@ public static void Lerp(ReadOnlySpan x, T y, ReadOnlySpan amount, Span<
private readonly struct LerpOperator : ITernaryOperator where T : IFloatingPointIeee754
{
public static T Invoke(T x, T y, T amount) => T.Lerp(x, y, amount);
- public static Vector128 Invoke(Vector128 x, Vector128 y, Vector128 amount) => (x * (Vector128.One - amount)) + (y * amount);
- public static Vector256 Invoke(Vector256 x, Vector256 y, Vector256 amount) => (x * (Vector256.One - amount)) + (y * amount);
- public static Vector512 Invoke(Vector512 x, Vector512 y, Vector512 amount) => (x * (Vector512.One - amount)) + (y * amount);
+
+ public static Vector128 Invoke(Vector128 x, Vector128 y, Vector128 amount)
+ {
+#if NET9_0_OR_GREATER
+ if (typeof(T) == typeof(double))
+ {
+ return Vector128.Lerp(x.AsDouble(), y.AsDouble(), amount.AsDouble()).As();
+ }
+ else
+ {
+ Debug.Assert(typeof(T) == typeof(float));
+ return Vector128.Lerp(x.AsSingle(), y.AsSingle(), amount.AsSingle()).As();
+ }
+#else
+ return (x * (Vector128.One - amount)) + (y * amount);
+#endif
+ }
+
+ public static Vector256 Invoke(Vector256 x, Vector256 y, Vector256 amount)
+ {
+#if NET9_0_OR_GREATER
+ if (typeof(T) == typeof(double))
+ {
+ return Vector256.Lerp(x.AsDouble(), y.AsDouble(), amount.AsDouble()).As();
+ }
+ else
+ {
+ Debug.Assert(typeof(T) == typeof(float));
+ return Vector256.Lerp(x.AsSingle(), y.AsSingle(), amount.AsSingle()).As();
+ }
+#else
+ return (x * (Vector256.One - amount)) + (y * amount);
+#endif
+ }
+
+ public static Vector512 Invoke(Vector512 x, Vector512 y, Vector512 amount)
+ {
+#if NET9_0_OR_GREATER
+ if (typeof(T) == typeof(double))
+ {
+ return Vector512.Lerp(x.AsDouble(), y.AsDouble(), amount.AsDouble()).As();
+ }
+ else
+ {
+ Debug.Assert(typeof(T) == typeof(float));
+ return Vector512.Lerp(x.AsSingle(), y.AsSingle(), amount.AsSingle()).As();
+ }
+#else
+ return (x * (Vector512.One - amount)) + (y * amount);
+#endif
+ }
}
}
}
diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Max.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Max.cs
index 2e760e30fb7c6..3a9c370e0078d 100644
--- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Max.cs
+++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Max.cs
@@ -1,6 +1,7 @@
// 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.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
@@ -51,7 +52,7 @@ public static T Max(ReadOnlySpan x)
///
public static void Max(ReadOnlySpan x, ReadOnlySpan y, Span destination)
where T : INumber =>
- InvokeSpanSpanIntoSpan>(x, y, destination);
+ InvokeSpanSpanIntoSpan>(x, y, destination);
/// Computes the element-wise maximum of the numbers in the specified tensors.
/// The first tensor, represented as a span.
@@ -74,45 +75,30 @@ public static void Max(ReadOnlySpan x, ReadOnlySpan y, Span destinat
///
public static void Max(ReadOnlySpan x, T y, Span destination)
where T : INumber =>
- InvokeSpanScalarIntoSpan>(x, y, destination);
+ InvokeSpanScalarIntoSpan>(x, y, destination);
- /// T.Max(x, y) (but NaNs may not be propagated)
- internal readonly struct MaxOperator : IAggregationOperator where T : INumber
+ /// Max(x, y)
+ internal readonly struct MaxOperator : IAggregationOperator
+ where T : INumber
{
public static bool Vectorizable => true;
- public static T Invoke(T x, T y)
- {
- if (typeof(T) == typeof(Half) || typeof(T) == typeof(float) || typeof(T) == typeof(double))
- {
- return x == y ?
- (IsNegative(x) ? y : x) :
- (y > x ? y : x);
- }
-
- return T.Max(x, y);
- }
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static T Invoke(T x, T y) => T.Max(x, y);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector128 Invoke(Vector128 x, Vector128 y)
{
- if (typeof(T) == typeof(float) || typeof(T) == typeof(double))
+#if !NET9_0_OR_GREATER
+ if ((typeof(T) == typeof(float)) || (typeof(T) == typeof(double)))
{
- if (AdvSimd.IsSupported && typeof(T) == typeof(float))
- {
- return AdvSimd.Max(x.AsSingle(), y.AsSingle()).As();
- }
-
- if (AdvSimd.Arm64.IsSupported && typeof(T) == typeof(double))
- {
- return AdvSimd.Arm64.Max(x.AsDouble(), y.AsDouble()).As();
- }
-
- return
- Vector128.ConditionalSelect(Vector128.Equals(x, y),
- Vector128.ConditionalSelect(IsNegative(x), y, x),
- Vector128.Max(x, y));
+ return Vector128.ConditionalSelect(
+ (Vector128.Equals(x, y) & IsNegative(y)) | IsNaN(x) | Vector128.LessThan(y, x),
+ x,
+ y
+ );
}
+#endif
return Vector128.Max(x, y);
}
@@ -120,13 +106,16 @@ public static Vector128 Invoke(Vector128 x, Vector128 y)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector256 Invoke(Vector256 x, Vector256 y)
{
- if (typeof(T) == typeof(float) || typeof(T) == typeof(double))
+#if !NET9_0_OR_GREATER
+ if ((typeof(T) == typeof(float)) || (typeof(T) == typeof(double)))
{
- return
- Vector256.ConditionalSelect(Vector256.Equals(x, y),
- Vector256.ConditionalSelect(IsNegative(x), y, x),
- Vector256.Max(x, y));
+ return Vector256.ConditionalSelect(
+ (Vector256.Equals(x, y) & IsNegative(y)) | ~Vector256.Equals(x, x) | Vector256.LessThan(y, x),
+ x,
+ y
+ );
}
+#endif
return Vector256.Max(x, y);
}
@@ -134,13 +123,16 @@ public static Vector256 Invoke(Vector256 x, Vector256 y)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector512 Invoke(Vector512 x, Vector512 y)
{
- if (typeof(T) == typeof(float) || typeof(T) == typeof(double))
+#if !NET9_0_OR_GREATER
+ if ((typeof(T) == typeof(float)) || (typeof(T) == typeof(double)))
{
- return
- Vector512.ConditionalSelect(Vector512.Equals(x, y),
- Vector512.ConditionalSelect(IsNegative(x), y, x),
- Vector512.Max(x, y));
+ return Vector512.ConditionalSelect(
+ (Vector512.Equals(x, y) & IsNegative(y)) | ~Vector512.Equals(x, x) | Vector512.LessThan(y, x),
+ x,
+ y
+ );
}
+#endif
return Vector512.Max(x, y);
}
@@ -150,84 +142,65 @@ public static Vector512 Invoke(Vector512 x, Vector512 y)
public static T Invoke(Vector512 x) => HorizontalAggregate>(x);
}
- /// Max(x, y)
- internal readonly struct MaxPropagateNaNOperator : IBinaryOperator
- where T : INumber
+ /// Gets whether each specified is NaN.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private static Vector128 IsNaN(Vector128 vector)
{
- public static bool Vectorizable => true;
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static T Invoke(T x, T y) => T.Max(x, y);
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector128 Invoke(Vector128 x, Vector128 y)
+#if NET9_0_OR_GREATER
+ return Vector128.IsNaN(vector);
+#else
+ if ((typeof(T) == typeof(float)) || (typeof(T) == typeof(double)))
{
- if (typeof(T) == typeof(float) || typeof(T) == typeof(double))
- {
- if (AdvSimd.IsSupported && typeof(T) == typeof(float))
- {
- return AdvSimd.Max(x.AsSingle(), y.AsSingle()).As();
- }
-
- if (AdvSimd.Arm64.IsSupported && typeof(T) == typeof(double))
- {
- return AdvSimd.Arm64.Max(x.AsDouble(), y.AsDouble()).As();
- }
-
- return
- Vector128.ConditionalSelect(Vector128.Equals(x, x),
- Vector128.ConditionalSelect(Vector128.Equals(y, y),
- Vector128.ConditionalSelect(Vector128.Equals(x, y),
- Vector128.ConditionalSelect(IsNegative(x), y, x),
- Vector128.Max(x, y)),
- y),
- x);
- }
-
- return Vector128.Max(x, y);
+ return ~Vector128.Equals(vector, vector);
}
+ return Vector128.Zero;
+#endif
+ }
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector256 Invoke(Vector256 x, Vector256 y)
+ /// Gets whether each specified is NaN.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private static Vector256 IsNaN(Vector256 vector)
+ {
+#if NET9_0_OR_GREATER
+ return Vector256.IsNaN(vector);
+#else
+ if ((typeof(T) == typeof(float)) || (typeof(T) == typeof(double)))
{
- if (typeof(T) == typeof(float) || typeof(T) == typeof(double))
- {
- return
- Vector256.ConditionalSelect(Vector256.Equals(x, x),
- Vector256.ConditionalSelect(Vector256.Equals(y, y),
- Vector256.ConditionalSelect(Vector256.Equals(x, y),
- Vector256.ConditionalSelect(IsNegative(x), y, x),
- Vector256.Max(x, y)),
- y),
- x);
- }
-
- return Vector256.Max(x, y);
+ return ~Vector256.Equals(vector, vector);
}
+ return Vector256.Zero;
+#endif
+ }
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector512 Invoke(Vector512 x, Vector512 y)
+ /// Gets whether each specified is NaN.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private static Vector512 IsNaN(Vector512 vector)
+ {
+#if NET9_0_OR_GREATER
+ return Vector512.IsNaN(vector);
+#else
+ if ((typeof(T) == typeof(float)) || (typeof(T) == typeof(double)))
{
- if (typeof(T) == typeof(float) || typeof(T) == typeof(double))
- {
- return
- Vector512.ConditionalSelect(Vector512.Equals(x, x),
- Vector512.ConditionalSelect(Vector512.Equals(y, y),
- Vector512.ConditionalSelect(Vector512.Equals(x, y),
- Vector512.ConditionalSelect(IsNegative(x), y, x),
- Vector512.Max(x, y)),
- y),
- x);
- }
-
- return Vector512.Max(x, y);
+ return ~Vector512.Equals(vector, vector);
}
+ return Vector512.Zero;
+#endif
}
+#if !NET9_0_OR_GREATER
/// Gets whether each specified is negative.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Vector128 IsNegative(Vector128 vector)
{
+ if ((typeof(T) == typeof(byte))
+ || (typeof(T) == typeof(ushort))
+ || (typeof(T) == typeof(uint))
+ || (typeof(T) == typeof(ulong))
+ || (typeof(T) == typeof(nuint)))
+ {
+ return Vector128.Zero;
+ }
+
if (typeof(T) == typeof(float))
{
return Vector128.LessThan(vector.AsInt32(), Vector128.Zero).As();
@@ -245,6 +218,15 @@ private static Vector128 IsNegative(Vector128 vector)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Vector256 IsNegative(Vector256 vector)
{
+ if ((typeof(T) == typeof(byte))
+ || (typeof(T) == typeof(ushort))
+ || (typeof(T) == typeof(uint))
+ || (typeof(T) == typeof(ulong))
+ || (typeof(T) == typeof(nuint)))
+ {
+ return Vector256.Zero;
+ }
+
if (typeof(T) == typeof(float))
{
return Vector256.LessThan(vector.AsInt32(), Vector256.Zero).As();
@@ -262,6 +244,15 @@ private static Vector256 IsNegative(Vector256 vector)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Vector512 IsNegative(Vector512 vector)
{
+ if ((typeof(T) == typeof(byte))
+ || (typeof(T) == typeof(ushort))
+ || (typeof(T) == typeof(uint))
+ || (typeof(T) == typeof(ulong))
+ || (typeof(T) == typeof(nuint)))
+ {
+ return Vector512.Zero;
+ }
+
if (typeof(T) == typeof(float))
{
return Vector512.LessThan(vector.AsInt32(), Vector512.Zero).As();
@@ -275,6 +266,85 @@ private static Vector512 IsNegative(Vector512 vector)
return Vector512.LessThan(vector, Vector512.Zero);
}
+ /// Gets whether each specified is positive.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private static Vector128 IsPositive(Vector128 vector)
+ {
+ if ((typeof(T) == typeof(byte))
+ || (typeof(T) == typeof(ushort))
+ || (typeof(T) == typeof(uint))
+ || (typeof(T) == typeof(ulong))
+ || (typeof(T) == typeof(nuint)))
+ {
+ return Vector128.AllBitsSet;
+ }
+
+ if (typeof(T) == typeof(float))
+ {
+ return Vector128.GreaterThanOrEqual(vector.AsInt32(), Vector128.Zero).As();
+ }
+
+ if (typeof(T) == typeof(double))
+ {
+ return Vector128.GreaterThanOrEqual(vector.AsInt64(), Vector128.Zero).As();
+ }
+
+ return Vector128.GreaterThanOrEqual(vector, Vector128.Zero);
+ }
+
+ /// Gets whether each specified