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 e0b71116746dd..2938d63460775 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 @@ -5,6 +5,7 @@ using System.Diagnostics; using System.Numerics; using System.Runtime.CompilerServices; +using System.Runtime.Intrinsics.Arm; using System.Runtime.Intrinsics.X86; using Internal.Runtime.CompilerServices; @@ -1369,6 +1370,11 @@ public static unsafe Vector128 Create(Vector64 lower, Vector64 CreateScalar(byte value) { + if (AdvSimd.IsSupported) + { + return AdvSimd.Insert(Vector128.Zero, 0, value); + } + if (Sse2.IsSupported) { // ConvertScalarToVector128 only deals with 32/64-bit inputs and we need to ensure all upper-bits are zeroed, so we call @@ -1392,6 +1398,11 @@ static Vector128 SoftwareFallback(byte value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe Vector128 CreateScalar(double value) { + if (AdvSimd.IsSupported) + { + return AdvSimd.Insert(Vector128.Zero, 0, value); + } + if (Sse2.IsSupported) { return Sse2.MoveScalar(Vector128.Zero, CreateScalarUnsafe(value)); @@ -1413,6 +1424,11 @@ static Vector128 SoftwareFallback(double value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe Vector128 CreateScalar(short value) { + if (AdvSimd.IsSupported) + { + return AdvSimd.Insert(Vector128.Zero, 0, value); + } + if (Sse2.IsSupported) { // ConvertScalarToVector128 only deals with 32/64-bit inputs and we need to ensure all upper-bits are zeroed, so we cast @@ -1436,6 +1452,11 @@ static Vector128 SoftwareFallback(short value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe Vector128 CreateScalar(int value) { + if (AdvSimd.IsSupported) + { + return AdvSimd.Insert(Vector128.Zero, 0, value); + } + if (Sse2.IsSupported) { return Sse2.ConvertScalarToVector128Int32(value); @@ -1456,6 +1477,11 @@ static Vector128 SoftwareFallback(int value) /// A new instance with the first element initialized to and the remaining elements initialized to zero. public static unsafe Vector128 CreateScalar(long value) { + if (AdvSimd.IsSupported) + { + return AdvSimd.Insert(Vector128.Zero, 0, value); + } + if (Sse2.X64.IsSupported) { return Sse2.X64.ConvertScalarToVector128Int64(value); @@ -1478,6 +1504,11 @@ static Vector128 SoftwareFallback(long value) [CLSCompliant(false)] public static unsafe Vector128 CreateScalar(sbyte value) { + if (AdvSimd.IsSupported) + { + return AdvSimd.Insert(Vector128.Zero, 0, value); + } + if (Sse2.IsSupported) { // ConvertScalarToVector128 only deals with 32/64-bit inputs and we need to ensure all upper-bits are zeroed, so we cast @@ -1501,6 +1532,11 @@ static Vector128 SoftwareFallback(sbyte value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe Vector128 CreateScalar(float value) { + if (AdvSimd.IsSupported) + { + return AdvSimd.Insert(Vector128.Zero, 0, value); + } + if (Sse.IsSupported) { return Sse.MoveScalar(Vector128.Zero, CreateScalarUnsafe(value)); @@ -1523,6 +1559,11 @@ static Vector128 SoftwareFallback(float value) [CLSCompliant(false)] public static unsafe Vector128 CreateScalar(ushort value) { + if (AdvSimd.IsSupported) + { + return AdvSimd.Insert(Vector128.Zero, 0, value); + } + if (Sse2.IsSupported) { // ConvertScalarToVector128 only deals with 32/64-bit inputs and we need to ensure all upper-bits are zeroed, so we call @@ -1547,6 +1588,11 @@ static Vector128 SoftwareFallback(ushort value) [CLSCompliant(false)] public static unsafe Vector128 CreateScalar(uint value) { + if (AdvSimd.IsSupported) + { + return AdvSimd.Insert(Vector128.Zero, 0, value); + } + if (Sse2.IsSupported) { return Sse2.ConvertScalarToVector128UInt32(value); @@ -1569,6 +1615,11 @@ static Vector128 SoftwareFallback(uint value) [CLSCompliant(false)] public static unsafe Vector128 CreateScalar(ulong value) { + if (AdvSimd.IsSupported) + { + return AdvSimd.Insert(Vector128.Zero, 0, value); + } + if (Sse2.X64.IsSupported) { return Sse2.X64.ConvertScalarToVector128UInt64(value); 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 a4f3fae98cb12..089a0b5a4ed48 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 @@ -4,6 +4,7 @@ using System.Runtime.CompilerServices; using Internal.Runtime.CompilerServices; +using System.Runtime.Intrinsics.Arm; namespace System.Runtime.Intrinsics { @@ -451,9 +452,19 @@ public static unsafe Vector64 Create(uint e0, uint e1) /// A new instance with the first element initialized to and the remaining elements initialized to zero. public static unsafe Vector64 CreateScalar(byte value) { - var result = Vector64.Zero; - Unsafe.WriteUnaligned(ref Unsafe.As, byte>(ref result), value); - return result; + if (AdvSimd.IsSupported) + { + return AdvSimd.Insert(Vector64.Zero, 0, value); + } + + return SoftwareFallback(value); + + static Vector64 SoftwareFallback(byte value) + { + var result = Vector64.Zero; + Unsafe.WriteUnaligned(ref Unsafe.As, byte>(ref result), value); + return result; + } } /// Creates a new instance with the first element initialized to the specified value and the remaining elements initialized to zero. @@ -461,9 +472,19 @@ public static unsafe Vector64 CreateScalar(byte value) /// A new instance with the first element initialized to and the remaining elements initialized to zero. public static unsafe Vector64 CreateScalar(short value) { - var result = Vector64.Zero; - Unsafe.WriteUnaligned(ref Unsafe.As, byte>(ref result), value); - return result; + if (AdvSimd.IsSupported) + { + return AdvSimd.Insert(Vector64.Zero, 0, value); + } + + return SoftwareFallback(value); + + static Vector64 SoftwareFallback(short value) + { + var result = Vector64.Zero; + Unsafe.WriteUnaligned(ref Unsafe.As, byte>(ref result), value); + return result; + } } /// Creates a new instance with the first element initialized to the specified value and the remaining elements initialized to zero. @@ -471,9 +492,19 @@ public static unsafe Vector64 CreateScalar(short value) /// A new instance with the first element initialized to and the remaining elements initialized to zero. public static unsafe Vector64 CreateScalar(int value) { - var result = Vector64.Zero; - Unsafe.WriteUnaligned(ref Unsafe.As, byte>(ref result), value); - return result; + if (AdvSimd.IsSupported) + { + return AdvSimd.Insert(Vector64.Zero, 0, value); + } + + return SoftwareFallback(value); + + static Vector64 SoftwareFallback(int value) + { + var result = Vector64.Zero; + Unsafe.WriteUnaligned(ref Unsafe.As, byte>(ref result), value); + return result; + } } /// Creates a new instance with the first element initialized to the specified value and the remaining elements initialized to zero. @@ -482,9 +513,19 @@ public static unsafe Vector64 CreateScalar(int value) [CLSCompliant(false)] public static unsafe Vector64 CreateScalar(sbyte value) { - var result = Vector64.Zero; - Unsafe.WriteUnaligned(ref Unsafe.As, byte>(ref result), value); - return result; + if (AdvSimd.IsSupported) + { + return AdvSimd.Insert(Vector64.Zero, 0, value); + } + + return SoftwareFallback(value); + + static Vector64 SoftwareFallback(sbyte value) + { + var result = Vector64.Zero; + Unsafe.WriteUnaligned(ref Unsafe.As, byte>(ref result), value); + return result; + } } /// Creates a new instance with the first element initialized to the specified value and the remaining elements initialized to zero. @@ -492,9 +533,19 @@ public static unsafe Vector64 CreateScalar(sbyte value) /// A new instance with the first element initialized to and the remaining elements initialized to zero. public static unsafe Vector64 CreateScalar(float value) { - var result = Vector64.Zero; - Unsafe.WriteUnaligned(ref Unsafe.As, byte>(ref result), value); - return result; + if (AdvSimd.IsSupported) + { + return AdvSimd.Insert(Vector64.Zero, 0, value); + } + + return SoftwareFallback(value); + + static Vector64 SoftwareFallback(float value) + { + var result = Vector64.Zero; + Unsafe.WriteUnaligned(ref Unsafe.As, byte>(ref result), value); + return result; + } } /// Creates a new instance with the first element initialized to the specified value and the remaining elements initialized to zero. @@ -503,9 +554,19 @@ public static unsafe Vector64 CreateScalar(float value) [CLSCompliant(false)] public static unsafe Vector64 CreateScalar(ushort value) { - var result = Vector64.Zero; - Unsafe.WriteUnaligned(ref Unsafe.As, byte>(ref result), value); - return result; + if (AdvSimd.IsSupported) + { + return AdvSimd.Insert(Vector64.Zero, 0, value); + } + + return SoftwareFallback(value); + + static Vector64 SoftwareFallback(ushort value) + { + var result = Vector64.Zero; + Unsafe.WriteUnaligned(ref Unsafe.As, byte>(ref result), value); + return result; + } } /// Creates a new instance with the first element initialized to the specified value and the remaining elements initialized to zero. @@ -514,9 +575,19 @@ public static unsafe Vector64 CreateScalar(ushort value) [CLSCompliant(false)] public static unsafe Vector64 CreateScalar(uint value) { - var result = Vector64.Zero; - Unsafe.WriteUnaligned(ref Unsafe.As, byte>(ref result), value); - return result; + if (AdvSimd.IsSupported) + { + return AdvSimd.Insert(Vector64.Zero, 0, value); + } + + return SoftwareFallback(value); + + static Vector64 SoftwareFallback(uint value) + { + var result = Vector64.Zero; + Unsafe.WriteUnaligned(ref Unsafe.As, byte>(ref result), value); + return result; + } } /// Creates a new instance with the first element initialized to the specified value and the remaining elements left uninitialized.