diff --git a/src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems b/src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems
index 078444fb8f48..c3ef9a3211f1 100644
--- a/src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems
+++ b/src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems
@@ -517,11 +517,14 @@
-
+
+
-
+
+
-
+
+
diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector128.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector128.cs
index b2e72ddf8933..f8eefb7dc092 100644
--- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector128.cs
+++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector128.cs
@@ -2,43 +2,840 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using System.Diagnostics;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
using Internal.Runtime.CompilerServices;
namespace System.Runtime.Intrinsics
{
- [Intrinsic]
- [DebuggerDisplay("{DisplayString,nq}")]
- [DebuggerTypeProxy(typeof(Vector128DebugView<>))]
- [StructLayout(LayoutKind.Sequential, Size = 16)]
- public readonly struct Vector128 where T : struct
+ public static class Vector128
{
- // These fields exist to ensure the alignment is 8, rather than 1.
- // This also allows the debug view to work https://github.com/dotnet/coreclr/issues/15694)
- private readonly ulong _00;
- private readonly ulong _01;
-
- private unsafe string DisplayString
- {
- get
- {
- // The IsPrimitive check ends up working for `bool`, `char`, `IntPtr`, and `UIntPtr`
- // which are not actually supported by any current architecture. This shouldn't be
- // an issue however and greatly simplifies the check
-
- if (typeof(T).IsPrimitive)
- {
- var items = new T[16 / Unsafe.SizeOf()];
- Unsafe.WriteUnaligned(ref Unsafe.As(ref items[0]), this);
- return $"({string.Join(", ", items)})";
- }
- else
- {
- return SR.NotSupported_Type;
- }
- }
+ internal const int Size = 16;
+
+ /// Creates a new instance with all elements initialized to the specified value.
+ /// The value that all elements will be initialized to.
+ /// A new with all elements initialized to .
+ public static unsafe Vector128 Create(byte value)
+ {
+ var pResult = stackalloc byte[16]
+ {
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ };
+
+ return Unsafe.AsRef>(pResult);
+ }
+
+ /// Creates a new instance with all elements initialized to the specified value.
+ /// The value that all elements will be initialized to.
+ /// A new with all elements initialized to .
+ public static unsafe Vector128 Create(double value)
+ {
+ var pResult = stackalloc double[2]
+ {
+ value,
+ value,
+ };
+
+ return Unsafe.AsRef>(pResult);
+ }
+
+ /// Creates a new instance with all elements initialized to the specified value.
+ /// The value that all elements will be initialized to.
+ /// A new with all elements initialized to .
+ public static unsafe Vector128 Create(short value)
+ {
+ var pResult = stackalloc short[8]
+ {
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ };
+
+ return Unsafe.AsRef>(pResult);
+ }
+
+ /// Creates a new instance with all elements initialized to the specified value.
+ /// The value that all elements will be initialized to.
+ /// A new with all elements initialized to .
+ public static unsafe Vector128 Create(int value)
+ {
+ var pResult = stackalloc int[4]
+ {
+ value,
+ value,
+ value,
+ value,
+ };
+
+ return Unsafe.AsRef>(pResult);
+ }
+
+ /// Creates a new instance with all elements initialized to the specified value.
+ /// The value that all elements will be initialized to.
+ /// A new with all elements initialized to .
+ public static unsafe Vector128 Create(long value)
+ {
+ var pResult = stackalloc long[2]
+ {
+ value,
+ value,
+ };
+
+ return Unsafe.AsRef>(pResult);
+ }
+
+ /// Creates a new instance with all elements initialized to the specified value.
+ /// The value that all elements will be initialized to.
+ /// A new with all elements initialized to .
+ [CLSCompliant(false)]
+ public static unsafe Vector128 Create(sbyte value)
+ {
+ var pResult = stackalloc sbyte[16]
+ {
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ };
+
+ return Unsafe.AsRef>(pResult);
+ }
+
+ /// Creates a new instance with all elements initialized to the specified value.
+ /// The value that all elements will be initialized to.
+ /// A new with all elements initialized to .
+ public static unsafe Vector128 Create(float value)
+ {
+ var pResult = stackalloc float[4]
+ {
+ value,
+ value,
+ value,
+ value,
+ };
+
+ return Unsafe.AsRef>(pResult);
+ }
+
+ /// Creates a new instance with all elements initialized to the specified value.
+ /// The value that all elements will be initialized to.
+ /// A new with all elements initialized to .
+ [CLSCompliant(false)]
+ public static unsafe Vector128 Create(ushort value)
+ {
+ var pResult = stackalloc ushort[8]
+ {
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ };
+
+ return Unsafe.AsRef>(pResult);
+ }
+
+ /// Creates a new instance with all elements initialized to the specified value.
+ /// The value that all elements will be initialized to.
+ /// A new with all elements initialized to .
+ [CLSCompliant(false)]
+ public static unsafe Vector128 Create(uint value)
+ {
+ var pResult = stackalloc uint[4]
+ {
+ value,
+ value,
+ value,
+ value,
+ };
+
+ return Unsafe.AsRef>(pResult);
+ }
+
+ /// Creates a new instance with all elements initialized to the specified value.
+ /// The value that all elements will be initialized to.
+ /// A new with all elements initialized to .
+ [CLSCompliant(false)]
+ public static unsafe Vector128 Create(ulong value)
+ {
+ var pResult = stackalloc ulong[2]
+ {
+ value,
+ value,
+ };
+
+ return Unsafe.AsRef>(pResult);
+ }
+
+ /// Creates a new instance with each element initialized to the corresponding specified value.
+ /// The value that element 0 will be initialized to.
+ /// The value that element 1 will be initialized to.
+ /// The value that element 2 will be initialized to.
+ /// The value that element 3 will be initialized to.
+ /// The value that element 4 will be initialized to.
+ /// The value that element 5 will be initialized to.
+ /// The value that element 6 will be initialized to.
+ /// The value that element 7 will be initialized to.
+ /// The value that element 8 will be initialized to.
+ /// The value that element 9 will be initialized to.
+ /// The value that element 10 will be initialized to.
+ /// The value that element 11 will be initialized to.
+ /// The value that element 12 will be initialized to.
+ /// The value that element 13 will be initialized to.
+ /// The value that element 14 will be initialized to.
+ /// The value that element 15 will be initialized to.
+ /// A new with each element initialized to corresponding specified value.
+ public static unsafe 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)
+ {
+ var pResult = stackalloc byte[16]
+ {
+ e0,
+ e1,
+ e2,
+ e3,
+ e4,
+ e5,
+ e6,
+ e7,
+ e8,
+ e9,
+ e10,
+ e11,
+ e12,
+ e13,
+ e14,
+ e15,
+ };
+
+ return Unsafe.AsRef>(pResult);
+ }
+
+ /// Creates a new instance with each element initialized to the corresponding specified value.
+ /// The value that element 0 will be initialized to.
+ /// The value that element 1 will be initialized to.
+ /// A new with each element initialized to corresponding specified value.
+ public static unsafe Vector128 Create(double e0, double e1)
+ {
+ var pResult = stackalloc double[2]
+ {
+ e0,
+ e1,
+ };
+
+ return Unsafe.AsRef>(pResult);
+ }
+
+ /// Creates a new instance with each element initialized to the corresponding specified value.
+ /// The value that element 0 will be initialized to.
+ /// The value that element 1 will be initialized to.
+ /// The value that element 2 will be initialized to.
+ /// The value that element 3 will be initialized to.
+ /// The value that element 4 will be initialized to.
+ /// The value that element 5 will be initialized to.
+ /// The value that element 6 will be initialized to.
+ /// The value that element 7 will be initialized to.
+ /// A new with each element initialized to corresponding specified value.
+ public static unsafe Vector128 Create(short e0, short e1, short e2, short e3, short e4, short e5, short e6, short e7)
+ {
+ var pResult = stackalloc short[8]
+ {
+ e0,
+ e1,
+ e2,
+ e3,
+ e4,
+ e5,
+ e6,
+ e7,
+ };
+
+ return Unsafe.AsRef>(pResult);
+ }
+
+ /// Creates a new instance with each element initialized to the corresponding specified value.
+ /// The value that element 0 will be initialized to.
+ /// The value that element 1 will be initialized to.
+ /// The value that element 2 will be initialized to.
+ /// The value that element 3 will be initialized to.
+ /// A new with each element initialized to corresponding specified value.
+ public static unsafe Vector128 Create(int e0, int e1, int e2, int e3)
+ {
+ var pResult = stackalloc int[4]
+ {
+ e0,
+ e1,
+ e2,
+ e3,
+ };
+
+ return Unsafe.AsRef>(pResult);
+ }
+
+ /// Creates a new instance with each element initialized to the corresponding specified value.
+ /// The value that element 0 will be initialized to.
+ /// The value that element 1 will be initialized to.
+ /// A new with each element initialized to corresponding specified value.
+ public static unsafe Vector128 Create(long e0, long e1)
+ {
+ var pResult = stackalloc long[2]
+ {
+ e0,
+ e1,
+ };
+
+ return Unsafe.AsRef>(pResult);
+ }
+
+ /// Creates a new instance with each element initialized to the corresponding specified value.
+ /// The value that element 0 will be initialized to.
+ /// The value that element 1 will be initialized to.
+ /// The value that element 2 will be initialized to.
+ /// The value that element 3 will be initialized to.
+ /// The value that element 4 will be initialized to.
+ /// The value that element 5 will be initialized to.
+ /// The value that element 6 will be initialized to.
+ /// The value that element 7 will be initialized to.
+ /// The value that element 8 will be initialized to.
+ /// The value that element 9 will be initialized to.
+ /// The value that element 10 will be initialized to.
+ /// The value that element 11 will be initialized to.
+ /// The value that element 12 will be initialized to.
+ /// The value that element 13 will be initialized to.
+ /// The value that element 14 will be initialized to.
+ /// The value that element 15 will be initialized to.
+ /// A new with each element initialized to corresponding specified value.
+ [CLSCompliant(false)]
+ public static unsafe Vector128 Create(sbyte e0, sbyte e1, sbyte e2, sbyte e3, sbyte e4, sbyte e5, sbyte e6, sbyte e7, sbyte e8, sbyte e9, sbyte e10, sbyte e11, sbyte e12, sbyte e13, sbyte e14, sbyte e15)
+ {
+ var pResult = stackalloc sbyte[16]
+ {
+ e0,
+ e1,
+ e2,
+ e3,
+ e4,
+ e5,
+ e6,
+ e7,
+ e8,
+ e9,
+ e10,
+ e11,
+ e12,
+ e13,
+ e14,
+ e15,
+ };
+
+ return Unsafe.AsRef>(pResult);
+ }
+
+ /// Creates a new instance with each element initialized to the corresponding specified value.
+ /// The value that element 0 will be initialized to.
+ /// The value that element 1 will be initialized to.
+ /// The value that element 2 will be initialized to.
+ /// The value that element 3 will be initialized to.
+ /// A new with each element initialized to corresponding specified value.
+ public static unsafe Vector128 Create(float e0, float e1, float e2, float e3)
+ {
+ var pResult = stackalloc float[4]
+ {
+ e0,
+ e1,
+ e2,
+ e3,
+ };
+
+ return Unsafe.AsRef>(pResult);
+ }
+
+ /// Creates a new instance with each element initialized to the corresponding specified value.
+ /// The value that element 0 will be initialized to.
+ /// The value that element 1 will be initialized to.
+ /// The value that element 2 will be initialized to.
+ /// The value that element 3 will be initialized to.
+ /// The value that element 4 will be initialized to.
+ /// The value that element 5 will be initialized to.
+ /// The value that element 6 will be initialized to.
+ /// The value that element 7 will be initialized to.
+ /// A new with each element initialized to corresponding specified value.
+ [CLSCompliant(false)]
+ public static unsafe Vector128 Create(ushort e0, ushort e1, ushort e2, ushort e3, ushort e4, ushort e5, ushort e6, ushort e7)
+ {
+ var pResult = stackalloc ushort[8]
+ {
+ e0,
+ e1,
+ e2,
+ e3,
+ e4,
+ e5,
+ e6,
+ e7,
+ };
+
+ return Unsafe.AsRef>(pResult);
+ }
+
+ /// Creates a new instance with each element initialized to the corresponding specified value.
+ /// The value that element 0 will be initialized to.
+ /// The value that element 1 will be initialized to.
+ /// The value that element 2 will be initialized to.
+ /// The value that element 3 will be initialized to.
+ /// A new with each element initialized to corresponding specified value.
+ [CLSCompliant(false)]
+ public static unsafe Vector128 Create(uint e0, uint e1, uint e2, uint e3)
+ {
+ var pResult = stackalloc uint[4]
+ {
+ e0,
+ e1,
+ e2,
+ e3,
+ };
+
+ return Unsafe.AsRef>(pResult);
+ }
+
+ /// Creates a new instance with each element initialized to the corresponding specified value.
+ /// The value that element 0 will be initialized to.
+ /// The value that element 1 will be initialized to.
+ /// A new with each element initialized to corresponding specified value.
+ [CLSCompliant(false)]
+ public static unsafe Vector128 Create(ulong e0, ulong e1)
+ {
+ var pResult = stackalloc ulong[2]
+ {
+ e0,
+ e1,
+ };
+
+ return Unsafe.AsRef>(pResult);
+ }
+
+ /// Creates a new instance from two instances.
+ /// The value that the lower 64-bits will be initialized to.
+ /// The value that the upper 64-bits will be initialized to.
+ /// A new initialized from and .
+ public static unsafe Vector128 Create(Vector64 lower, Vector64 upper)
+ {
+ Vector128 result128 = Vector128.Zero;
+
+ ref Vector64 result64 = ref Unsafe.As, Vector64>(ref result128);
+ result64 = lower;
+ Unsafe.Add(ref result64, 1) = upper;
+
+ return result128;
+ }
+
+ /// Creates a new instance from two instances.
+ /// The value that the lower 64-bits will be initialized to.
+ /// The value that the upper 64-bits will be initialized to.
+ /// A new initialized from and .
+ public static unsafe Vector128 Create(Vector64 lower, Vector64 upper)
+ {
+ Vector128 result128 = Vector128.Zero;
+
+ ref Vector64 result64 = ref Unsafe.As, Vector64>(ref result128);
+ result64 = lower;
+ Unsafe.Add(ref result64, 1) = upper;
+
+ return result128;
+ }
+
+ /// Creates a new instance from two instances.
+ /// The value that the lower 64-bits will be initialized to.
+ /// The value that the upper 64-bits will be initialized to.
+ /// A new initialized from and .
+ public static unsafe Vector128 Create(Vector64 lower, Vector64 upper)
+ {
+ Vector128 result128 = Vector128.Zero;
+
+ ref Vector64 result64 = ref Unsafe.As, Vector64>(ref result128);
+ result64 = lower;
+ Unsafe.Add(ref result64, 1) = upper;
+
+ return result128;
+ }
+
+ /// Creates a new instance from two instances.
+ /// The value that the lower 64-bits will be initialized to.
+ /// The value that the upper 64-bits will be initialized to.
+ /// A new initialized from and .
+ public static unsafe Vector128 Create(Vector64 lower, Vector64 upper)
+ {
+ Vector128 result128 = Vector128.Zero;
+
+ ref Vector64 result64 = ref Unsafe.As, Vector64>(ref result128);
+ result64 = lower;
+ Unsafe.Add(ref result64, 1) = upper;
+
+ return result128;
+ }
+
+ /// Creates a new instance from two instances.
+ /// The value that the lower 64-bits will be initialized to.
+ /// The value that the upper 64-bits will be initialized to.
+ /// A new initialized from and .
+ public static unsafe Vector128 Create(Vector64 lower, Vector64 upper)
+ {
+ Vector128 result128 = Vector128.Zero;
+
+ ref Vector64 result64 = ref Unsafe.As, Vector64>(ref result128);
+ result64 = lower;
+ Unsafe.Add(ref result64, 1) = upper;
+
+ return result128;
+ }
+
+ /// Creates a new instance from two instances.
+ /// The value that the lower 64-bits will be initialized to.
+ /// The value that the upper 64-bits will be initialized to.
+ /// A new initialized from and .
+ [CLSCompliant(false)]
+ public static unsafe Vector128 Create(Vector64 lower, Vector64 upper)
+ {
+ Vector128 result128 = Vector128.Zero;
+
+ ref Vector64 result64 = ref Unsafe.As, Vector64>(ref result128);
+ result64 = lower;
+ Unsafe.Add(ref result64, 1) = upper;
+
+ return result128;
+ }
+
+ /// Creates a new instance from two instances.
+ /// The value that the lower 64-bits will be initialized to.
+ /// The value that the upper 64-bits will be initialized to.
+ /// A new initialized from and .
+ public static unsafe Vector128 Create(Vector64 lower, Vector64 upper)
+ {
+ Vector128 result128 = Vector128.Zero;
+
+ ref Vector64 result64 = ref Unsafe.As, Vector64>(ref result128);
+ result64 = lower;
+ Unsafe.Add(ref result64, 1) = upper;
+
+ return result128;
+ }
+
+ /// Creates a new instance from two instances.
+ /// The value that the lower 64-bits will be initialized to.
+ /// The value that the upper 64-bits will be initialized to.
+ /// A new initialized from and .
+ [CLSCompliant(false)]
+ public static unsafe Vector128 Create(Vector64 lower, Vector64 upper)
+ {
+ Vector128 result128 = Vector128.Zero;
+
+ ref Vector64 result64 = ref Unsafe.As, Vector64>(ref result128);
+ result64 = lower;
+ Unsafe.Add(ref result64, 1) = upper;
+
+ return result128;
+ }
+
+ /// Creates a new instance from two instances.
+ /// The value that the lower 64-bits will be initialized to.
+ /// The value that the upper 64-bits will be initialized to.
+ /// A new initialized from and .
+ [CLSCompliant(false)]
+ public static unsafe Vector128 Create(Vector64 lower, Vector64 upper)
+ {
+ Vector128 result128 = Vector128.Zero;
+
+ ref Vector64 result64 = ref Unsafe.As, Vector64>(ref result128);
+ result64 = lower;
+ Unsafe.Add(ref result64, 1) = upper;
+
+ return result128;
+ }
+
+ /// Creates a new instance from two instances.
+ /// The value that the lower 64-bits will be initialized to.
+ /// The value that the upper 64-bits will be initialized to.
+ /// A new initialized from and .
+ [CLSCompliant(false)]
+ public static unsafe Vector128 Create(Vector64 lower, Vector64 upper)
+ {
+ Vector128 result128 = Vector128.Zero;
+
+ ref Vector64 result64 = ref Unsafe.As, Vector64>(ref result128);
+ result64 = lower;
+ Unsafe.Add(ref result64, 1) = upper;
+
+ return result128;
+ }
+
+ /// Creates a new instance with the first element initialized to the specified value and the remaining elements initialized to zero.
+ /// The value that element 0 will be initialized to.
+ /// A new instance with the first element initialized to and the remaining elements initialized to zero.
+ public static unsafe Vector128 CreateScalar(byte value)
+ {
+ var result = Vector128.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.
+ /// The value that element 0 will be initialized to.
+ /// A new instance with the first element initialized to and the remaining elements initialized to zero.
+ public static unsafe Vector128 CreateScalar(double value)
+ {
+ var result = Vector128.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.
+ /// The value that element 0 will be initialized to.
+ /// A new instance with the first element initialized to and the remaining elements initialized to zero.
+ public static unsafe Vector128 CreateScalar(short value)
+ {
+ var result = Vector128.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.
+ /// The value that element 0 will be initialized to.
+ /// A new instance with the first element initialized to and the remaining elements initialized to zero.
+ public static unsafe Vector128 CreateScalar(int value)
+ {
+ var result = Vector128.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.
+ /// The value that element 0 will be initialized to.
+ /// A new instance with the first element initialized to and the remaining elements initialized to zero.
+ public static unsafe Vector128 CreateScalar(long value)
+ {
+ var result = Vector128.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.
+ /// The value that element 0 will be initialized to.
+ /// A new instance with the first element initialized to and the remaining elements initialized to zero.
+ [CLSCompliant(false)]
+ public static unsafe Vector128 CreateScalar(sbyte value)
+ {
+ var result = Vector128.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.
+ /// The value that element 0 will be initialized to.
+ /// A new instance with the first element initialized to and the remaining elements initialized to zero.
+ public static unsafe Vector128 CreateScalar(float value)
+ {
+ var result = Vector128.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.
+ /// The value that element 0 will be initialized to.
+ /// A new instance with the first element initialized to and the remaining elements initialized to zero.
+ [CLSCompliant(false)]
+ public static unsafe Vector128 CreateScalar(ushort value)
+ {
+ var result = Vector128.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.
+ /// The value that element 0 will be initialized to.
+ /// A new instance with the first element initialized to and the remaining elements initialized to zero.
+ [CLSCompliant(false)]
+ public static unsafe Vector128 CreateScalar(uint value)
+ {
+ var result = Vector128.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.
+ /// The value that element 0 will be initialized to.
+ /// A new instance with the first element initialized to and the remaining elements initialized to zero.
+ [CLSCompliant(false)]
+ public static unsafe Vector128 CreateScalar(ulong value)
+ {
+ var result = Vector128.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.
+ /// The value that element 0 will be initialized to.
+ /// A new instance with the first element initialized to and the remaining elements left uninitialized.
+ public static unsafe Vector128 CreateScalarUnsafe(byte value)
+ {
+ // This relies on us stripping the "init" flag from the ".locals"
+ // declaration to let the upper bits be uninitialized.
+
+ var pResult = stackalloc byte[16];
+ pResult[0] = value;
+ return Unsafe.AsRef>(pResult);
+ }
+
+ /// Creates a new instance with the first element initialized to the specified value and the remaining elements left uninitialized.
+ /// The value that element 0 will be initialized to.
+ /// A new instance with the first element initialized to and the remaining elements left uninitialized.
+ public static unsafe Vector128 CreateScalarUnsafe(double value)
+ {
+ // This relies on us stripping the "init" flag from the ".locals"
+ // declaration to let the upper bits be uninitialized.
+
+ var pResult = stackalloc double[2];
+ pResult[0] = value;
+ return Unsafe.AsRef>(pResult);
+ }
+
+ /// Creates a new instance with the first element initialized to the specified value and the remaining elements left uninitialized.
+ /// The value that element 0 will be initialized to.
+ /// A new instance with the first element initialized to and the remaining elements left uninitialized.
+ public static unsafe Vector128 CreateScalarUnsafe(short value)
+ {
+ // This relies on us stripping the "init" flag from the ".locals"
+ // declaration to let the upper bits be uninitialized.
+
+ var pResult = stackalloc short[8];
+ pResult[0] = value;
+ return Unsafe.AsRef>(pResult);
+ }
+
+ /// Creates a new instance with the first element initialized to the specified value and the remaining elements left uninitialized.
+ /// The value that element 0 will be initialized to.
+ /// A new instance with the first element initialized to and the remaining elements left uninitialized.
+ public static unsafe Vector128 CreateScalarUnsafe(int value)
+ {
+ // This relies on us stripping the "init" flag from the ".locals"
+ // declaration to let the upper bits be uninitialized.
+
+ var pResult = stackalloc int[4];
+ pResult[0] = value;
+ return Unsafe.AsRef>(pResult);
+ }
+
+ /// Creates a new instance with the first element initialized to the specified value and the remaining elements left uninitialized.
+ /// The value that element 0 will be initialized to.
+ /// A new instance with the first element initialized to and the remaining elements left uninitialized.
+ public static unsafe Vector128 CreateScalarUnsafe(long value)
+ {
+ // This relies on us stripping the "init" flag from the ".locals"
+ // declaration to let the upper bits be uninitialized.
+
+ var pResult = stackalloc long[2];
+ pResult[0] = value;
+ return Unsafe.AsRef>(pResult);
+ }
+
+ /// Creates a new instance with the first element initialized to the specified value and the remaining elements left uninitialized.
+ /// The value that element 0 will be initialized to.
+ /// A new instance with the first element initialized to and the remaining elements left uninitialized.
+ [CLSCompliant(false)]
+ public static unsafe Vector128 CreateScalarUnsafe(sbyte value)
+ {
+ // This relies on us stripping the "init" flag from the ".locals"
+ // declaration to let the upper bits be uninitialized.
+
+ var pResult = stackalloc sbyte[16];
+ pResult[0] = value;
+ return Unsafe.AsRef>(pResult);
+ }
+
+ /// Creates a new instance with the first element initialized to the specified value and the remaining elements left uninitialized.
+ /// The value that element 0 will be initialized to.
+ /// A new instance with the first element initialized to and the remaining elements left uninitialized.
+ public static unsafe Vector128 CreateScalarUnsafe(float value)
+ {
+ // This relies on us stripping the "init" flag from the ".locals"
+ // declaration to let the upper bits be uninitialized.
+
+ var pResult = stackalloc float[4];
+ pResult[0] = value;
+ return Unsafe.AsRef>(pResult);
+ }
+
+ /// Creates a new instance with the first element initialized to the specified value and the remaining elements left uninitialized.
+ /// The value that element 0 will be initialized to.
+ /// A new instance with the first element initialized to and the remaining elements left uninitialized.
+ [CLSCompliant(false)]
+ public static unsafe Vector128 CreateScalarUnsafe(ushort value)
+ {
+ // This relies on us stripping the "init" flag from the ".locals"
+ // declaration to let the upper bits be uninitialized.
+
+ var pResult = stackalloc ushort[8];
+ pResult[0] = value;
+ return Unsafe.AsRef>(pResult);
+ }
+
+ /// Creates a new instance with the first element initialized to the specified value and the remaining elements left uninitialized.
+ /// The value that element 0 will be initialized to.
+ /// A new instance with the first element initialized to and the remaining elements left uninitialized.
+ [CLSCompliant(false)]
+ public static unsafe Vector128 CreateScalarUnsafe(uint value)
+ {
+ // This relies on us stripping the "init" flag from the ".locals"
+ // declaration to let the upper bits be uninitialized.
+
+ var pResult = stackalloc uint[4];
+ pResult[0] = value;
+ return Unsafe.AsRef>(pResult);
+ }
+
+ /// Creates a new instance with the first element initialized to the specified value and the remaining elements left uninitialized.
+ /// The value that element 0 will be initialized to.
+ /// A new instance with the first element initialized to and the remaining elements left uninitialized.
+ [CLSCompliant(false)]
+ public static unsafe Vector128 CreateScalarUnsafe(ulong value)
+ {
+ // This relies on us stripping the "init" flag from the ".locals"
+ // declaration to let the upper bits be uninitialized.
+
+ var pResult = stackalloc ulong[2];
+ pResult[0] = value;
+ return Unsafe.AsRef>(pResult);
}
}
}
diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector128DebugView.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector128DebugView_1.cs
similarity index 100%
rename from src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector128DebugView.cs
rename to src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector128DebugView_1.cs
diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector128_1.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector128_1.cs
new file mode 100644
index 000000000000..d8d4095d9d35
--- /dev/null
+++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector128_1.cs
@@ -0,0 +1,278 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using Internal.Runtime.CompilerServices;
+
+namespace System.Runtime.Intrinsics
+{
+ [Intrinsic]
+ [DebuggerDisplay("{DisplayString,nq}")]
+ [DebuggerTypeProxy(typeof(Vector128DebugView<>))]
+ [StructLayout(LayoutKind.Sequential, Size = Vector128.Size)]
+ public readonly struct Vector128 where T : struct
+ {
+ // These fields exist to ensure the alignment is 8, rather than 1.
+ // This also allows the debug view to work https://github.com/dotnet/coreclr/issues/15694)
+ private readonly ulong _00;
+ private readonly ulong _01;
+
+ /// Gets a new with all elements initialized to zero.
+ /// The type of the current instance () is not supported.
+ public static Vector128 Zero
+ {
+ get
+ {
+ ThrowIfUnsupportedType();
+ return default;
+ }
+ }
+
+ internal unsafe string DisplayString
+ {
+ get
+ {
+ if (IsSupported)
+ {
+ var items = new T[ElementCount];
+ Unsafe.WriteUnaligned(ref Unsafe.As(ref items[0]), this);
+ return $"({string.Join(", ", items)})";
+ }
+ else
+ {
+ return SR.NotSupported_Type;
+ }
+ }
+ }
+
+ internal static int ElementCount
+ {
+ get
+ {
+ ThrowIfUnsupportedType();
+ return Vector128.Size / Unsafe.SizeOf();
+ }
+ }
+
+ internal static bool IsSupported
+ {
+ get
+ {
+ return (typeof(T) == typeof(byte)) ||
+ (typeof(T) == typeof(sbyte)) ||
+ (typeof(T) == typeof(short)) ||
+ (typeof(T) == typeof(ushort)) ||
+ (typeof(T) == typeof(int)) ||
+ (typeof(T) == typeof(uint)) ||
+ (typeof(T) == typeof(long)) ||
+ (typeof(T) == typeof(ulong)) ||
+ (typeof(T) == typeof(float)) ||
+ (typeof(T) == typeof(double));
+ }
+ }
+
+ internal static void ThrowIfUnsupportedType()
+ {
+ if (!IsSupported)
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+
+ /// Reinterprets the current instance as a new .
+ /// The type of the vector the current instance should be reinterpreted as.
+ /// The current instance reinterpreted as a new .
+ /// The type of the current instance () or the type of the target () is not supported.
+ public Vector128 As() where U : struct
+ {
+ ThrowIfUnsupportedType();
+ Vector128.ThrowIfUnsupportedType();
+ return Unsafe.As, Vector128>(ref Unsafe.AsRef(in this));
+ }
+
+ /// Reinterprets the current instance as a new .
+ /// The current instance reinterpreted as a new .
+ /// The type of the current instance () is not supported.
+ public Vector128 AsByte() => As();
+
+ /// Reinterprets the current instance as a new .
+ /// The current instance reinterpreted as a new .
+ /// The type of the current instance () is not supported.
+ public Vector128 AsDouble() => As();
+
+ /// Reinterprets the current instance as a new .
+ /// The current instance reinterpreted as a new .
+ /// The type of the current instance () is not supported.
+ public Vector128 AsInt16() => As();
+
+ /// Reinterprets the current instance as a new .
+ /// The current instance reinterpreted as a new .
+ /// The type of the current instance () is not supported.
+ public Vector128 AsInt32() => As();
+
+ /// Reinterprets the current instance as a new .
+ /// The current instance reinterpreted as a new .
+ /// The type of the current instance () is not supported.
+ public Vector128 AsInt64() => As();
+
+ /// Reinterprets the current instance as a new .
+ /// The current instance reinterpreted as a new .
+ /// The type of the current instance () is not supported.
+ [CLSCompliant(false)]
+ public Vector128 AsSByte() => As();
+
+ /// Reinterprets the current instance as a new .
+ /// The current instance reinterpreted as a new .
+ /// The type of the current instance () is not supported.
+ public Vector128 AsSingle() => As();
+
+ /// Reinterprets the current instance as a new .
+ /// The current instance reinterpreted as a new .
+ /// The type of the current instance () is not supported.
+ [CLSCompliant(false)]
+ public Vector128 AsUInt16() => As();
+
+ /// Reinterprets the current instance as a new .
+ /// The current instance reinterpreted as a new .
+ /// The type of the current instance () is not supported.
+ [CLSCompliant(false)]
+ public Vector128 AsUInt32() => As();
+
+ /// Reinterprets the current instance as a new .
+ /// The current instance reinterpreted as a new .
+ /// The type of the current instance () is not supported.
+ [CLSCompliant(false)]
+ public Vector128 AsUInt64() => As();
+
+ /// Gets the element at the specified index.
+ /// The index of the element to get.
+ /// The value of the element at .
+ /// The type of the current instance () is not supported.
+ /// was less than zero or greater than the number of elements.
+ public T GetElement(int index)
+ {
+ ThrowIfUnsupportedType();
+
+ if ((uint)(index) >= (uint)(ElementCount))
+ {
+ throw new ArgumentOutOfRangeException(nameof(index));
+ }
+
+ ref T e0 = ref Unsafe.As, T>(ref Unsafe.AsRef(in this));
+ return Unsafe.Add(ref e0, index);
+ }
+
+ /// Creates a new with the element at the specified index set to the specified value and the remaining elements set to the same value as that in the current instance.
+ /// The index of the element to set.
+ /// The value to set the value to.
+ /// A with the value of the element at set to and the remaining elements set to the same value as that in the current instance.
+ /// The type of the current instance () is not supported.
+ /// was less than zero or greater than the number of elements.
+ public Vector128 WithElement(int index, T value)
+ {
+ ThrowIfUnsupportedType();
+
+ if ((uint)(index) >= (uint)(ElementCount))
+ {
+ throw new ArgumentOutOfRangeException(nameof(index));
+ }
+
+ Vector128 result = this;
+ ref T e0 = ref Unsafe.As, T>(ref result);
+ Unsafe.Add(ref e0, index) = value;
+ return result;
+ }
+
+ /// Gets the value of the lower 64-bits as a new .
+ /// The value of the lower 64-bits as a new .
+ /// The type of the current instance () is not supported.
+ public Vector64 GetLower()
+ {
+ ThrowIfUnsupportedType();
+ Vector64.ThrowIfUnsupportedType();
+ return Unsafe.As, Vector64>(ref Unsafe.AsRef(in this));
+ }
+
+ /// Creates a new with the lower 64-bits set to the specified value and the upper 64-bits set to the same value as that in the current instance.
+ /// The value of the lower 64-bits as a .
+ /// A new with the lower 64-bits set to the specified value and the upper 64-bits set to the same value as that in the current instance.
+ /// The type of the current instance () is not supported.
+ public Vector128 WithLower(Vector64 value)
+ {
+ ThrowIfUnsupportedType();
+ Vector64.ThrowIfUnsupportedType();
+
+ Vector128 result = this;
+ Unsafe.As, Vector64>(ref result) = value;
+ return result;
+ }
+
+ /// Gets the value of the upper 64-bits as a new .
+ /// The value of the upper 64-bits as a new .
+ /// The type of the current instance () is not supported.
+ public Vector64 GetUpper()
+ {
+ ThrowIfUnsupportedType();
+ Vector64.ThrowIfUnsupportedType();
+
+ ref Vector64 lower = ref Unsafe.As, Vector64>(ref Unsafe.AsRef(in this));
+ return Unsafe.Add(ref lower, 1);
+ }
+
+ /// Creates a new with the upper 64-bits set to the specified value and the upper 64-bits set to the same value as that in the current instance.
+ /// The value of the upper 64-bits as a .
+ /// A new with the upper 64-bits set to the specified value and the upper 64-bits set to the same value as that in the current instance.
+ /// The type of the current instance () is not supported.
+ public Vector128 WithUpper(Vector64 value)
+ {
+ ThrowIfUnsupportedType();
+ Vector64.ThrowIfUnsupportedType();
+
+ Vector128 result = this;
+ ref Vector64 lower = ref Unsafe.As, Vector64>(ref result);
+ Unsafe.Add(ref lower, 1) = value;
+ return result;
+ }
+
+ /// Converts the current instance to a scalar containing the value of the first element.
+ /// A scalar containing the value of the first element.
+ /// The type of the current instance () is not supported.
+ public T ToScalar()
+ {
+ ThrowIfUnsupportedType();
+ return Unsafe.As, T>(ref Unsafe.AsRef(in this));
+ }
+
+ /// Converts the current instance to a new with the lower 128-bits set to the value of the current instance and the upper 128-bits initialized to zero.
+ /// A new with the lower 128-bits set to the value of the current instance and the upper 128-bits initialized to zero.
+ /// The type of the current instance () is not supported.
+ public Vector256 ToVector256()
+ {
+ ThrowIfUnsupportedType();
+ Vector256.ThrowIfUnsupportedType();
+
+ Vector256 result = Vector256.Zero;
+ Unsafe.As, Vector128>(ref result) = this;
+ return result;
+ }
+
+ /// Converts the current instance to a new with the lower 128-bits set to the value of the current instance and the upper 128-bits left uninitialized.
+ /// A new with the lower 128-bits set to the value of the current instance and the upper 128-bits left uninitialized.
+ /// The type of the current instance () is not supported.
+ public unsafe Vector256 ToVector256Unsafe()
+ {
+ ThrowIfUnsupportedType();
+ Vector256.ThrowIfUnsupportedType();
+
+ // This relies on us stripping the "init" flag from the ".locals"
+ // declaration to let the upper bits be uninitialized.
+
+ var pResult = stackalloc byte[Vector256.Size];
+ Unsafe.AsRef>(pResult) = this;
+ return Unsafe.AsRef>(pResult);
+ }
+ }
+}
diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector256.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector256.cs
index 48744bb5eab3..a4f4cd66d719 100644
--- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector256.cs
+++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector256.cs
@@ -2,45 +2,1038 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using System.Diagnostics;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
using Internal.Runtime.CompilerServices;
namespace System.Runtime.Intrinsics
{
- [Intrinsic]
- [DebuggerDisplay("{DisplayString,nq}")]
- [DebuggerTypeProxy(typeof(Vector256DebugView<>))]
- [StructLayout(LayoutKind.Sequential, Size = 32)]
- public readonly struct Vector256 where T : struct
+ public static class Vector256
{
- // These fields exist to ensure the alignment is 8, rather than 1.
- // This also allows the debug view to work https://github.com/dotnet/coreclr/issues/15694)
- private readonly ulong _00;
- private readonly ulong _01;
- private readonly ulong _02;
- private readonly ulong _03;
-
- private unsafe string DisplayString
- {
- get
- {
- // The IsPrimitive check ends up working for `bool`, `char`, `IntPtr`, and `UIntPtr`
- // which are not actually supported by any current architecture. This shouldn't be
- // an issue however and greatly simplifies the check
-
- if (typeof(T).IsPrimitive)
- {
- var items = new T[32 / Unsafe.SizeOf()];
- Unsafe.WriteUnaligned(ref Unsafe.As(ref items[0]), this);
- return $"({string.Join(", ", items)})";
- }
- else
- {
- return SR.NotSupported_Type;
- }
- }
+ internal const int Size = 32;
+
+ /// Creates a new instance with all elements initialized to the specified value.
+ /// The value that all elements will be initialized to.
+ /// A new with all elements initialized to .
+ public static unsafe Vector256 Create(byte value)
+ {
+ var pResult = stackalloc byte[32]
+ {
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ };
+
+ return Unsafe.AsRef>(pResult);
+ }
+
+ /// Creates a new instance with all elements initialized to the specified value.
+ /// The value that all elements will be initialized to.
+ /// A new with all elements initialized to .
+ public static unsafe Vector256 Create(double value)
+ {
+ var pResult = stackalloc double[4]
+ {
+ value,
+ value,
+ value,
+ value,
+ };
+
+ return Unsafe.AsRef>(pResult);
+ }
+
+ /// Creates a new instance with all elements initialized to the specified value.
+ /// The value that all elements will be initialized to.
+ /// A new with all elements initialized to .
+ public static unsafe Vector256 Create(short value)
+ {
+ var pResult = stackalloc short[16]
+ {
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ };
+
+ return Unsafe.AsRef>(pResult);
+ }
+
+ /// Creates a new instance with all elements initialized to the specified value.
+ /// The value that all elements will be initialized to.
+ /// A new with all elements initialized to .
+ public static unsafe Vector256 Create(int value)
+ {
+ var pResult = stackalloc int[8]
+ {
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ };
+
+ return Unsafe.AsRef>(pResult);
+ }
+
+ /// Creates a new instance with all elements initialized to the specified value.
+ /// The value that all elements will be initialized to.
+ /// A new with all elements initialized to .
+ public static unsafe Vector256 Create(long value)
+ {
+ var pResult = stackalloc long[4]
+ {
+ value,
+ value,
+ value,
+ value,
+ };
+
+ return Unsafe.AsRef>(pResult);
+ }
+
+ /// Creates a new instance with all elements initialized to the specified value.
+ /// The value that all elements will be initialized to.
+ /// A new with all elements initialized to .
+ [CLSCompliant(false)]
+ public static unsafe Vector256 Create(sbyte value)
+ {
+ var pResult = stackalloc sbyte[32]
+ {
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value,
+ };
+
+ return Unsafe.AsRef>(pResult);
+ }
+
+ ///