9c3360a5e617eec2ed72a2e6bd4d417fc6615e11
[platform/upstream/dotnet/runtime.git] / src / libraries / System.Private.CoreLib / src / System / Runtime / Intrinsics / Vector256.cs
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3
4 using System.Diagnostics;
5 using System.Numerics;
6 using System.Runtime.CompilerServices;
7 using System.Runtime.InteropServices;
8 using System.Runtime.Intrinsics.X86;
9
10 namespace System.Runtime.Intrinsics
11 {
12     // We mark certain methods with AggressiveInlining to ensure that the JIT will
13     // inline them. The JIT would otherwise not inline the method since it, at the
14     // point it tries to determine inline profability, currently cannot determine
15     // that most of the code-paths will be optimized away as "dead code".
16     //
17     // We then manually inline cases (such as certain intrinsic code-paths) that
18     // will generate code small enough to make the AgressiveInlining profitable. The
19     // other cases (such as the software fallback) are placed in their own method.
20     // This ensures we get good codegen for the "fast-path" and allows the JIT to
21     // determine inline profitability of the other paths as it would normally.
22
23     // Many of the instance methods were moved to be extension methods as it results
24     // in overall better codegen. This is because instance methods require the C# compiler
25     // to generate extra locals as the `this` parameter has to be passed by reference.
26     // Having them be extension methods means that the `this` parameter can be passed by
27     // value instead, thus reducing the number of locals and helping prevent us from hitting
28     // the internal inlining limits of the JIT.
29
30     /// <summary>Provides a collection of static methods for creating, manipulating, and otherwise operating on 256-bit vectors.</summary>
31     public static unsafe class Vector256
32     {
33         internal const int Size = 32;
34
35 #if TARGET_ARM
36         internal const int Alignment = 8;
37 #elif TARGET_ARM64
38         internal const int Alignment = 16;
39 #else
40         internal const int Alignment = 32;
41 #endif
42
43         /// <summary>Gets a value that indicates whether 256-bit vector operations are subject to hardware acceleration through JIT intrinsic support.</summary>
44         /// <value><see langword="true" /> if 256-bit vector operations are subject to hardware acceleration; otherwise, <see langword="false" />.</value>
45         /// <remarks>256-bit vector operations are subject to hardware acceleration on systems that support Single Instruction, Multiple Data (SIMD) instructions for 256-bit vectors and the RyuJIT just-in-time compiler is used to compile managed code.</remarks>
46         public static bool IsHardwareAccelerated
47         {
48             [Intrinsic]
49             get => IsHardwareAccelerated;
50         }
51
52         /// <summary>Computes the absolute value of each element in a vector.</summary>
53         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
54         /// <param name="vector">The vector that will have its absolute value computed.</param>
55         /// <returns>A vector whose elements are the absolute value of the elements in <paramref name="vector" />.</returns>
56         /// <exception cref="NotSupportedException">The type of <paramref name="vector" /> (<typeparamref name="T" />) is not supported.</exception>
57         [Intrinsic]
58         [MethodImpl(MethodImplOptions.AggressiveInlining)]
59         public static Vector256<T> Abs<T>(Vector256<T> vector)
60         {
61             return Create(
62                 Vector128.Abs(vector._lower),
63                 Vector128.Abs(vector._upper)
64             );
65         }
66
67         /// <summary>Adds two vectors to compute their sum.</summary>
68         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
69         /// <param name="left">The vector to add with <paramref name="right" />.</param>
70         /// <param name="right">The vector to add with <paramref name="left" />.</param>
71         /// <returns>The sum of <paramref name="left" /> and <paramref name="right" />.</returns>
72         /// <exception cref="NotSupportedException">The type of <paramref name="left" /> and <paramref name="right" /> (<typeparamref name="T" />) is not supported.</exception>
73         [Intrinsic]
74         [MethodImpl(MethodImplOptions.AggressiveInlining)]
75         public static Vector256<T> Add<T>(Vector256<T> left, Vector256<T> right) => left + right;
76
77         /// <summary>Computes the bitwise-and of a given vector and the ones complement of another vector.</summary>
78         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
79         /// <param name="left">The vector to bitwise-and with <paramref name="right" />.</param>
80         /// <param name="right">The vector to that is ones-complemented before being bitwise-and with <paramref name="left" />.</param>
81         /// <returns>The bitwise-and of <paramref name="left" /> and the ones-complement of <paramref name="right" />.</returns>
82         /// <exception cref="NotSupportedException">The type of <paramref name="left" /> and <paramref name="right" /> (<typeparamref name="T" />) is not supported.</exception>
83         [Intrinsic]
84         [MethodImpl(MethodImplOptions.AggressiveInlining)]
85         public static Vector256<T> AndNot<T>(Vector256<T> left, Vector256<T> right)
86         {
87             return Create(
88                 Vector128.AndNot(left._lower, right._lower),
89                 Vector128.AndNot(left._upper, right._upper)
90             );
91         }
92
93         /// <summary>Reinterprets a <see cref="Vector256{TFrom}" /> as a new <see cref="Vector256{TTo}" />.</summary>
94         /// <typeparam name="TFrom">The type of the elements in the input vector.</typeparam>
95         /// <typeparam name="TTo">The type of the elements in the output vector.</typeparam>
96         /// <param name="vector">The vector to reinterpret.</param>
97         /// <returns><paramref name="vector" /> reinterpreted as a new <see cref="Vector256{TTo}" />.</returns>
98         /// <exception cref="NotSupportedException">The type of <paramref name="vector" /> (<typeparamref name="TFrom" />) or the type of the target (<typeparamref name="TTo" />) is not supported.</exception>
99         [Intrinsic]
100         [MethodImpl(MethodImplOptions.AggressiveInlining)]
101         public static Vector256<TTo> As<TFrom, TTo>(this Vector256<TFrom> vector)
102         {
103             ThrowHelper.ThrowForUnsupportedIntrinsicsVector256BaseType<TFrom>();
104             ThrowHelper.ThrowForUnsupportedIntrinsicsVector256BaseType<TTo>();
105
106             return Unsafe.As<Vector256<TFrom>, Vector256<TTo>>(ref vector);
107         }
108
109         /// <summary>Reinterprets a <see cref="Vector256{T}" /> as a new <see cref="Vector256{Byte}" />.</summary>
110         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
111         /// <param name="vector">The vector to reinterpret.</param>
112         /// <returns><paramref name="vector" /> reinterpreted as a new <see cref="Vector256{Byte}" />.</returns>
113         /// <exception cref="NotSupportedException">The type of <paramref name="vector" /> (<typeparamref name="T" />) is not supported.</exception>
114         [Intrinsic]
115         [MethodImpl(MethodImplOptions.AggressiveInlining)]
116         public static Vector256<byte> AsByte<T>(this Vector256<T> vector) => vector.As<T, byte>();
117
118         /// <summary>Reinterprets a <see cref="Vector256{T}" /> as a new <see cref="Vector256{Double}" />.</summary>
119         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
120         /// <param name="vector">The vector to reinterpret.</param>
121         /// <returns><paramref name="vector" /> reinterpreted as a new <see cref="Vector256{Double}" />.</returns>
122         /// <exception cref="NotSupportedException">The type of <paramref name="vector" /> (<typeparamref name="T" />) is not supported.</exception>
123         [Intrinsic]
124         [MethodImpl(MethodImplOptions.AggressiveInlining)]
125         public static Vector256<double> AsDouble<T>(this Vector256<T> vector) => vector.As<T, double>();
126
127         /// <summary>Reinterprets a <see cref="Vector256{T}" /> as a new <see cref="Vector256{Int16}" />.</summary>
128         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
129         /// <param name="vector">The vector to reinterpret.</param>
130         /// <returns><paramref name="vector" /> reinterpreted as a new <see cref="Vector256{Int16}" />.</returns>
131         /// <exception cref="NotSupportedException">The type of <paramref name="vector" /> (<typeparamref name="T" />) is not supported.</exception>
132         [Intrinsic]
133         [MethodImpl(MethodImplOptions.AggressiveInlining)]
134         public static Vector256<short> AsInt16<T>(this Vector256<T> vector) => vector.As<T, short>();
135
136         /// <summary>Reinterprets a <see cref="Vector256{T}" /> as a new <see cref="Vector256{Int32}" />.</summary>
137         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
138         /// <param name="vector">The vector to reinterpret.</param>
139         /// <returns><paramref name="vector" /> reinterpreted as a new <see cref="Vector256{Int32}" />.</returns>
140         /// <exception cref="NotSupportedException">The type of <paramref name="vector" /> (<typeparamref name="T" />) is not supported.</exception>
141         [Intrinsic]
142         [MethodImpl(MethodImplOptions.AggressiveInlining)]
143         public static Vector256<int> AsInt32<T>(this Vector256<T> vector) => vector.As<T, int>();
144
145         /// <summary>Reinterprets a <see cref="Vector256{T}" /> as a new <see cref="Vector256{Int64}" />.</summary>
146         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
147         /// <param name="vector">The vector to reinterpret.</param>
148         /// <returns><paramref name="vector" /> reinterpreted as a new <see cref="Vector256{Int64}" />.</returns>
149         /// <exception cref="NotSupportedException">The type of <paramref name="vector" /> (<typeparamref name="T" />) is not supported.</exception>
150         [Intrinsic]
151         [MethodImpl(MethodImplOptions.AggressiveInlining)]
152         public static Vector256<long> AsInt64<T>(this Vector256<T> vector) => vector.As<T, long>();
153
154         /// <summary>Reinterprets a <see cref="Vector256{T}" /> as a new <see cref="Vector256{IntPtr}" />.</summary>
155         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
156         /// <param name="vector">The vector to reinterpret.</param>
157         /// <returns><paramref name="vector" /> reinterpreted as a new <see cref="Vector256{IntPtr}" />.</returns>
158         /// <exception cref="NotSupportedException">The type of <paramref name="vector" /> (<typeparamref name="T" />) is not supported.</exception>
159         [Intrinsic]
160         [MethodImpl(MethodImplOptions.AggressiveInlining)]
161         public static Vector256<nint> AsNInt<T>(this Vector256<T> vector) => vector.As<T, nint>();
162
163         /// <summary>Reinterprets a <see cref="Vector256{T}" /> as a new <see cref="Vector256{UIntPtr}" />.</summary>
164         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
165         /// <param name="vector">The vector to reinterpret.</param>
166         /// <returns><paramref name="vector" /> reinterpreted as a new <see cref="Vector256{UIntPtr}" />.</returns>
167         /// <exception cref="NotSupportedException">The type of <paramref name="vector" /> (<typeparamref name="T" />) is not supported.</exception>
168         [Intrinsic]
169         [CLSCompliant(false)]
170         [MethodImpl(MethodImplOptions.AggressiveInlining)]
171         public static Vector256<nuint> AsNUInt<T>(this Vector256<T> vector) => vector.As<T, nuint>();
172
173         /// <summary>Reinterprets a <see cref="Vector256{T}" /> as a new <see cref="Vector256{SByte}" />.</summary>
174         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
175         /// <param name="vector">The vector to reinterpret.</param>
176         /// <returns><paramref name="vector" /> reinterpreted as a new <see cref="Vector256{SByte}" />.</returns>
177         /// <exception cref="NotSupportedException">The type of <paramref name="vector" /> (<typeparamref name="T" />) is not supported.</exception>
178         [Intrinsic]
179         [CLSCompliant(false)]
180         [MethodImpl(MethodImplOptions.AggressiveInlining)]
181         public static Vector256<sbyte> AsSByte<T>(this Vector256<T> vector) => vector.As<T, sbyte>();
182
183         /// <summary>Reinterprets a <see cref="Vector256{T}" /> as a new <see cref="Vector256{Single}" />.</summary>
184         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
185         /// <param name="vector">The vector to reinterpret.</param>
186         /// <returns><paramref name="vector" /> reinterpreted as a new <see cref="Vector256{Single}" />.</returns>
187         /// <exception cref="NotSupportedException">The type of <paramref name="vector" /> (<typeparamref name="T" />) is not supported.</exception>
188         [Intrinsic]
189         [MethodImpl(MethodImplOptions.AggressiveInlining)]
190         public static Vector256<float> AsSingle<T>(this Vector256<T> vector) => vector.As<T, float>();
191
192         /// <summary>Reinterprets a <see cref="Vector256{T}" /> as a new <see cref="Vector256{UInt16}" />.</summary>
193         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
194         /// <param name="vector">The vector to reinterpret.</param>
195         /// <returns><paramref name="vector" /> reinterpreted as a new <see cref="Vector256{UInt16}" />.</returns>
196         /// <exception cref="NotSupportedException">The type of <paramref name="vector" /> (<typeparamref name="T" />) is not supported.</exception>
197         [Intrinsic]
198         [CLSCompliant(false)]
199         [MethodImpl(MethodImplOptions.AggressiveInlining)]
200         public static Vector256<ushort> AsUInt16<T>(this Vector256<T> vector) => vector.As<T, ushort>();
201
202         /// <summary>Reinterprets a <see cref="Vector256{T}" /> as a new <see cref="Vector256{UInt32}" />.</summary>
203         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
204         /// <param name="vector">The vector to reinterpret.</param>
205         /// <returns><paramref name="vector" /> reinterpreted as a new <see cref="Vector256{UInt32}" />.</returns>
206         /// <exception cref="NotSupportedException">The type of <paramref name="vector" /> (<typeparamref name="T" />) is not supported.</exception>
207         [Intrinsic]
208         [CLSCompliant(false)]
209         [MethodImpl(MethodImplOptions.AggressiveInlining)]
210         public static Vector256<uint> AsUInt32<T>(this Vector256<T> vector) => vector.As<T, uint>();
211
212         /// <summary>Reinterprets a <see cref="Vector256{T}" /> as a new <see cref="Vector256{UInt64}" />.</summary>
213         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
214         /// <param name="vector">The vector to reinterpret.</param>
215         /// <returns><paramref name="vector" /> reinterpreted as a new <see cref="Vector256{UInt64}" />.</returns>
216         /// <exception cref="NotSupportedException">The type of <paramref name="vector" /> (<typeparamref name="T" />) is not supported.</exception>
217         [Intrinsic]
218         [CLSCompliant(false)]
219         [MethodImpl(MethodImplOptions.AggressiveInlining)]
220         public static Vector256<ulong> AsUInt64<T>(this Vector256<T> vector) => vector.As<T, ulong>();
221
222         /// <summary>Reinterprets a <see cref="Vector{T}" /> as a new <see cref="Vector256{T}" />.</summary>
223         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
224         /// <param name="value">The vector to reinterpret.</param>
225         /// <returns><paramref name="value" /> reinterpreted as a new <see cref="Vector256{T}" />.</returns>
226         /// <exception cref="NotSupportedException">The type of <paramref name="value" /> (<typeparamref name="T" />) is not supported.</exception>
227         [Intrinsic]
228         [MethodImpl(MethodImplOptions.AggressiveInlining)]
229         public static Vector256<T> AsVector256<T>(this Vector<T> value)
230         {
231             Debug.Assert(Vector256<T>.Count >= Vector<T>.Count);
232             ThrowHelper.ThrowForUnsupportedIntrinsicsVector256BaseType<T>();
233
234             Vector256<T> result = default;
235             Unsafe.WriteUnaligned(ref Unsafe.As<Vector256<T>, byte>(ref result), value);
236             return result;
237         }
238
239         /// <summary>Reinterprets a <see cref="Vector256{T}" /> as a new <see cref="Vector{T}" />.</summary>
240         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
241         /// <param name="value">The vector to reinterpret.</param>
242         /// <returns><paramref name="value" /> reinterpreted as a new <see cref="Vector{T}" />.</returns>
243         /// <exception cref="NotSupportedException">The type of <paramref name="value" /> (<typeparamref name="T" />) is not supported.</exception>
244         [Intrinsic]
245         [MethodImpl(MethodImplOptions.AggressiveInlining)]
246         public static Vector<T> AsVector<T>(this Vector256<T> value)
247         {
248             Debug.Assert(Vector256<T>.Count >= Vector<T>.Count);
249             ThrowHelper.ThrowForUnsupportedIntrinsicsVector256BaseType<T>();
250
251             ref byte address = ref Unsafe.As<Vector256<T>, byte>(ref value);
252             return Unsafe.ReadUnaligned<Vector<T>>(ref address);
253         }
254
255         /// <summary>Computes the bitwise-and of two vectors.</summary>
256         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
257         /// <param name="left">The vector to bitwise-and with <paramref name="right" />.</param>
258         /// <param name="right">The vector to bitwise-and with <paramref name="left" />.</param>
259         /// <returns>The bitwise-and of <paramref name="left" /> and <paramref name="right"/>.</returns>
260         /// <exception cref="NotSupportedException">The type of <paramref name="left" /> and <paramref name="right" /> (<typeparamref name="T" />) is not supported.</exception>
261         [Intrinsic]
262         [MethodImpl(MethodImplOptions.AggressiveInlining)]
263         public static Vector256<T> BitwiseAnd<T>(Vector256<T> left, Vector256<T> right) => left & right;
264
265         /// <summary>Computes the bitwise-or of two vectors.</summary>
266         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
267         /// <param name="left">The vector to bitwise-or with <paramref name="right" />.</param>
268         /// <param name="right">The vector to bitwise-or with <paramref name="left" />.</param>
269         /// <returns>The bitwise-or of <paramref name="left" /> and <paramref name="right"/>.</returns>
270         /// <exception cref="NotSupportedException">The type of <paramref name="left" /> and <paramref name="right" /> (<typeparamref name="T" />) is not supported.</exception>
271         [Intrinsic]
272         [MethodImpl(MethodImplOptions.AggressiveInlining)]
273         public static Vector256<T> BitwiseOr<T>(Vector256<T> left, Vector256<T> right) => left | right;
274
275         /// <summary>Computes the ceiling of each element in a vector.</summary>
276         /// <param name="vector">The vector that will have its ceiling computed.</param>
277         /// <returns>A vector whose elements are the ceiling of the elements in <paramref name="vector" />.</returns>
278         /// <seealso cref="MathF.Ceiling(float)" />
279         [Intrinsic]
280         [MethodImpl(MethodImplOptions.AggressiveInlining)]
281         public static Vector256<float> Ceiling(Vector256<float> vector)
282         {
283             return Create(
284                 Vector128.Ceiling(vector._lower),
285                 Vector128.Ceiling(vector._upper)
286             );
287         }
288
289         /// <summary>Computes the ceiling of each element in a vector.</summary>
290         /// <param name="vector">The vector that will have its ceiling computed.</param>
291         /// <returns>A vector whose elements are the ceiling of the elements in <paramref name="vector" />.</returns>
292         /// <seealso cref="Math.Ceiling(double)" />
293         [Intrinsic]
294         [MethodImpl(MethodImplOptions.AggressiveInlining)]
295         public static Vector256<double> Ceiling(Vector256<double> vector)
296         {
297             return Create(
298                 Vector128.Ceiling(vector._lower),
299                 Vector128.Ceiling(vector._upper)
300             );
301         }
302
303         /// <summary>Conditionally selects a value from two vectors on a bitwise basis.</summary>
304         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
305         /// <param name="condition">The mask that is used to select a value from <paramref name="left" /> or <paramref name="right" />.</param>
306         /// <param name="left">The vector that is selected when the corresponding bit in <paramref name="condition" /> is one.</param>
307         /// <param name="right">The vector that is selected when the corresponding bit in <paramref name="condition" /> is zero.</param>
308         /// <returns>A vector whose bits come from <paramref name="left" /> or <paramref name="right" /> based on the value of <paramref name="condition" />.</returns>
309         /// <exception cref="NotSupportedException">The type of <paramref name="condition" />, <paramref name="left" />, and <paramref name="right" /> (<typeparamref name="T" />) is not supported.</exception>
310         [Intrinsic]
311         [MethodImpl(MethodImplOptions.AggressiveInlining)]
312         public static Vector256<T> ConditionalSelect<T>(Vector256<T> condition, Vector256<T> left, Vector256<T> right)
313         {
314             return Create(
315                 Vector128.ConditionalSelect(condition._lower, left._lower, right._lower),
316                 Vector128.ConditionalSelect(condition._upper, left._upper, right._upper)
317             );
318         }
319
320         /// <summary>Converts a <see cref="Vector256{Int64}" /> to a <see cref="Vector256{Double}" />.</summary>
321         /// <param name="vector">The vector to convert.</param>
322         /// <returns>The converted vector.</returns>
323         [Intrinsic]
324         [MethodImpl(MethodImplOptions.AggressiveInlining)]
325         public static Vector256<double> ConvertToDouble(Vector256<long> vector)
326         {
327             if (Avx2.IsSupported)
328             {
329                 // Based on __m256d int64_to_double_fast_precise(const __m256i v)
330                 // from https://stackoverflow.com/a/41223013/12860347. CC BY-SA 4.0
331
332                 Vector256<int> lowerBits;
333
334                 lowerBits = vector.AsInt32();
335                 lowerBits = Avx2.Blend(lowerBits, Create(0x43300000_00000000).AsInt32(), 0b10101010);           // Blend the 32 lowest significant bits of vector with the bit representation of double(2^52)
336
337                 Vector256<long> upperBits = Avx2.ShiftRightLogical(vector, 32);                                             // Extract the 32 most significant bits of vector
338                 upperBits = Avx2.Xor(upperBits, Create(0x45300000_80000000));                                   // Flip the msb of upperBits and blend with the bit representation of double(2^84 + 2^63)
339
340                 Vector256<double> result = Avx.Subtract(upperBits.AsDouble(), Create(0x45300000_80100000).AsDouble());        // Compute in double precision: (upper - (2^84 + 2^63 + 2^52)) + lower
341                 return Avx.Add(result, lowerBits.AsDouble());
342             }
343             else
344             {
345                 return Create(
346                     Vector128.ConvertToDouble(vector._lower),
347                     Vector128.ConvertToDouble(vector._upper)
348                 );
349             }
350         }
351
352         /// <summary>Converts a <see cref="Vector256{UInt64}" /> to a <see cref="Vector256{Double}" />.</summary>
353         /// <param name="vector">The vector to convert.</param>
354         /// <returns>The converted vector.</returns>
355         [Intrinsic]
356         [CLSCompliant(false)]
357         [MethodImpl(MethodImplOptions.AggressiveInlining)]
358         public static Vector256<double> ConvertToDouble(Vector256<ulong> vector)
359         {
360             if (Avx2.IsSupported)
361             {
362                 // Based on __m256d uint64_to_double_fast_precise(const __m256i v)
363                 // from https://stackoverflow.com/a/41223013/12860347. CC BY-SA 4.0
364
365                 Vector256<uint> lowerBits;
366
367                 lowerBits = vector.AsUInt32();
368                 lowerBits = Avx2.Blend(lowerBits, Create(0x43300000_00000000UL).AsUInt32(), 0b10101010);        // Blend the 32 lowest significant bits of vector with the bit representation of double(2^52)                                                 */
369
370                 Vector256<ulong> upperBits = Avx2.ShiftRightLogical(vector, 32);                                             // Extract the 32 most significant bits of vector
371                 upperBits = Avx2.Xor(upperBits, Create(0x45300000_00000000UL));                                 // Blend upperBits with the bit representation of double(2^84)
372
373                 Vector256<double> result = Avx.Subtract(upperBits.AsDouble(), Create(0x45300000_00100000UL).AsDouble());      // Compute in double precision: (upper - (2^84 + 2^52)) + lower
374                 return Avx.Add(result, lowerBits.AsDouble());
375             }
376             else
377             {
378                 return Create(
379                     Vector128.ConvertToDouble(vector._lower),
380                     Vector128.ConvertToDouble(vector._upper)
381                 );
382             }
383         }
384
385         /// <summary>Converts a <see cref="Vector256{Single}" /> to a <see cref="Vector256{Int32}" />.</summary>
386         /// <param name="vector">The vector to convert.</param>
387         /// <returns>The converted vector.</returns>
388         [Intrinsic]
389         [MethodImpl(MethodImplOptions.AggressiveInlining)]
390         public static Vector256<int> ConvertToInt32(Vector256<float> vector)
391         {
392             return Create(
393                 Vector128.ConvertToInt32(vector._lower),
394                 Vector128.ConvertToInt32(vector._upper)
395             );
396         }
397
398         /// <summary>Converts a <see cref="Vector256{Double}" /> to a <see cref="Vector256{Int64}" />.</summary>
399         /// <param name="vector">The vector to convert.</param>
400         /// <returns>The converted vector.</returns>
401         [Intrinsic]
402         [MethodImpl(MethodImplOptions.AggressiveInlining)]
403         public static Vector256<long> ConvertToInt64(Vector256<double> vector)
404         {
405             return Create(
406                 Vector128.ConvertToInt64(vector._lower),
407                 Vector128.ConvertToInt64(vector._upper)
408             );
409         }
410
411         /// <summary>Converts a <see cref="Vector256{Int32}" /> to a <see cref="Vector256{Single}" />.</summary>
412         /// <param name="vector">The vector to convert.</param>
413         /// <returns>The converted vector.</returns>
414         [Intrinsic]
415         [MethodImpl(MethodImplOptions.AggressiveInlining)]
416         public static Vector256<float> ConvertToSingle(Vector256<int> vector)
417         {
418             return Create(
419                 Vector128.ConvertToSingle(vector._lower),
420                 Vector128.ConvertToSingle(vector._upper)
421             );
422         }
423
424         /// <summary>Converts a <see cref="Vector256{UInt32}" /> to a <see cref="Vector256{Single}" />.</summary>
425         /// <param name="vector">The vector to convert.</param>
426         /// <returns>The converted vector.</returns>
427         [Intrinsic]
428         [CLSCompliant(false)]
429         [MethodImpl(MethodImplOptions.AggressiveInlining)]
430         public static Vector256<float> ConvertToSingle(Vector256<uint> vector)
431         {
432             if (Avx2.IsSupported)
433             {
434                 // This first bit of magic works because float can exactly represent integers up to 2^24
435                 //
436                 // This means everything between 0 and 2^16 (ushort.MaxValue + 1) are exact and so
437                 // converting each of the upper and lower halves will give an exact result
438
439                 Vector256<int> lowerBits = Avx2.And(vector, Create(0x0000FFFFU)).AsInt32();
440                 Vector256<int> upperBits = Avx2.ShiftRightLogical(vector, 16).AsInt32();
441
442                 Vector256<float> lower = Avx.ConvertToVector256Single(lowerBits);
443                 Vector256<float> upper = Avx.ConvertToVector256Single(upperBits);
444
445                 // This next bit of magic works because all multiples of 65536, at least up to 65535
446                 // are likewise exactly representable
447                 //
448                 // This means that scaling upper by 65536 gives us the exactly representable base value
449                 // and then the remaining lower value, which is likewise up to 65535 can be added on
450                 // giving us a result that will correctly round to the nearest representable value
451
452                 if (Fma.IsSupported)
453                 {
454                     return Fma.MultiplyAdd(upper, Create(65536.0f), lower);
455                 }
456                 else
457                 {
458                     Vector256<float> result = Avx.Multiply(upper, Create(65536.0f));
459                     return Avx.Add(result, lower);
460                 }
461             }
462             else
463             {
464                 return Create(
465                     Vector128.ConvertToSingle(vector._lower),
466                     Vector128.ConvertToSingle(vector._upper)
467                 );
468             }
469         }
470
471         /// <summary>Converts a <see cref="Vector256{Single}" /> to a <see cref="Vector256{UInt32}" />.</summary>
472         /// <param name="vector">The vector to convert.</param>
473         /// <returns>The converted vector.</returns>
474         [Intrinsic]
475         [CLSCompliant(false)]
476         [MethodImpl(MethodImplOptions.AggressiveInlining)]
477         public static Vector256<uint> ConvertToUInt32(Vector256<float> vector)
478         {
479             return Create(
480                 Vector128.ConvertToUInt32(vector._lower),
481                 Vector128.ConvertToUInt32(vector._upper)
482             );
483         }
484
485         /// <summary>Converts a <see cref="Vector256{Double}" /> to a <see cref="Vector256{UInt64}" />.</summary>
486         /// <param name="vector">The vector to convert.</param>
487         /// <returns>The converted vector.</returns>
488         [Intrinsic]
489         [CLSCompliant(false)]
490         [MethodImpl(MethodImplOptions.AggressiveInlining)]
491         public static Vector256<ulong> ConvertToUInt64(Vector256<double> vector)
492         {
493             return Create(
494                 Vector128.ConvertToUInt64(vector._lower),
495                 Vector128.ConvertToUInt64(vector._upper)
496             );
497         }
498
499         /// <summary>Copies a <see cref="Vector256{T}" /> to a given array.</summary>
500         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
501         /// <param name="vector">The vector to be copied.</param>
502         /// <param name="destination">The array to which <paramref name="vector" /> is copied.</param>
503         /// <exception cref="ArgumentException">The length of <paramref name="destination" /> is less than <see cref="Vector256{T}.Count" />.</exception>
504         /// <exception cref="NotSupportedException">The type of <paramref name="vector" /> and <paramref name="destination" /> (<typeparamref name="T" />) is not supported.</exception>
505         /// <exception cref="NullReferenceException"><paramref name="destination" /> is <c>null</c>.</exception>
506         [MethodImpl(MethodImplOptions.AggressiveInlining)]
507         public static void CopyTo<T>(this Vector256<T> vector, T[] destination)
508         {
509             // We explicitly don't check for `null` because historically this has thrown `NullReferenceException` for perf reasons
510
511             if (destination.Length < Vector256<T>.Count)
512             {
513                 ThrowHelper.ThrowArgumentException_DestinationTooShort();
514             }
515
516             Unsafe.WriteUnaligned(ref Unsafe.As<T, byte>(ref destination[0]), vector);
517         }
518
519         /// <summary>Copies a <see cref="Vector256{T}" /> to a given array starting at the specified index.</summary>
520         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
521         /// <param name="vector">The vector to be copied.</param>
522         /// <param name="destination">The array to which <paramref name="vector" /> is copied.</param>
523         /// <param name="startIndex">The starting index of <paramref name="destination" /> which <paramref name="vector" /> will be copied to.</param>
524         /// <exception cref="ArgumentException">The length of <paramref name="destination" /> is less than <see cref="Vector256{T}.Count" />.</exception>
525         /// <exception cref="ArgumentOutOfRangeException"><paramref name="startIndex" /> is negative or greater than the length of <paramref name="destination" />.</exception>
526         /// <exception cref="NotSupportedException">The type of <paramref name="vector" /> and <paramref name="destination" /> (<typeparamref name="T" />) is not supported.</exception>
527         /// <exception cref="NullReferenceException"><paramref name="destination" /> is <c>null</c>.</exception>
528         [MethodImpl(MethodImplOptions.AggressiveInlining)]
529         public static void CopyTo<T>(this Vector256<T> vector, T[] destination, int startIndex)
530         {
531             // We explicitly don't check for `null` because historically this has thrown `NullReferenceException` for perf reasons
532
533             if ((uint)startIndex >= (uint)destination.Length)
534             {
535                 ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_IndexMustBeLess();
536             }
537
538             if ((destination.Length - startIndex) < Vector256<T>.Count)
539             {
540                 ThrowHelper.ThrowArgumentException_DestinationTooShort();
541             }
542
543             Unsafe.WriteUnaligned(ref Unsafe.As<T, byte>(ref destination[startIndex]), vector);
544         }
545
546         /// <summary>Copies a <see cref="Vector256{T}" /> to a given span.</summary>
547         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
548         /// <param name="vector">The vector to be copied.</param>
549         /// <param name="destination">The span to which the <paramref name="vector" /> is copied.</param>
550         /// <exception cref="ArgumentException">The length of <paramref name="destination" /> is less than <see cref="Vector256{T}.Count" />.</exception>
551         /// <exception cref="NotSupportedException">The type of <paramref name="vector" /> and <paramref name="destination" /> (<typeparamref name="T" />) is not supported.</exception>
552         [MethodImpl(MethodImplOptions.AggressiveInlining)]
553         public static void CopyTo<T>(this Vector256<T> vector, Span<T> destination)
554         {
555             if (destination.Length < Vector256<T>.Count)
556             {
557                 ThrowHelper.ThrowArgumentException_DestinationTooShort();
558             }
559
560             Unsafe.WriteUnaligned(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(destination)), vector);
561         }
562
563         /// <summary>Creates a new <see cref="Vector256{T}" /> instance with all elements initialized to the specified value.</summary>
564         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
565         /// <param name="value">The value that all elements will be initialized to.</param>
566         /// <returns>A new <see cref="Vector256{T}" /> with all elements initialized to <paramref name="value" />.</returns>
567         /// <exception cref="NotSupportedException">The type of <paramref name="value" /> (<typeparamref name="T" />) is not supported.</exception>
568         [Intrinsic]
569         [MethodImpl(MethodImplOptions.AggressiveInlining)]
570         public static Vector256<T> Create<T>(T value)
571         {
572             Vector128<T> vector = Vector128.Create(value);
573             return Create(vector, vector);
574         }
575
576         /// <summary>Creates a new <see cref="Vector256{Byte}" /> instance with all elements initialized to the specified value.</summary>
577         /// <param name="value">The value that all elements will be initialized to.</param>
578         /// <returns>A new <see cref="Vector256{Byte}" /> with all elements initialized to <paramref name="value" />.</returns>
579         /// <remarks>On x86, this method corresponds to __m256i _mm256_set1_epi8</remarks>
580         [Intrinsic]
581         [MethodImpl(MethodImplOptions.AggressiveInlining)]
582         public static Vector256<byte> Create(byte value) => Create<byte>(value);
583
584         /// <summary>Creates a new <see cref="Vector256{Double}" /> instance with all elements initialized to the specified value.</summary>
585         /// <param name="value">The value that all elements will be initialized to.</param>
586         /// <returns>A new <see cref="Vector256{Double}" /> with all elements initialized to <paramref name="value" />.</returns>
587         /// <remarks>On x86, this method corresponds to __m256d _mm256_set1_pd</remarks>
588         [Intrinsic]
589         [MethodImpl(MethodImplOptions.AggressiveInlining)]
590         public static Vector256<double> Create(double value) => Create<double>(value);
591
592         /// <summary>Creates a new <see cref="Vector256{Int16}" /> instance with all elements initialized to the specified value.</summary>
593         /// <param name="value">The value that all elements will be initialized to.</param>
594         /// <returns>A new <see cref="Vector256{Int16}" /> with all elements initialized to <paramref name="value" />.</returns>
595         /// <remarks>On x86, this method corresponds to __m256i _mm256_set1_epi16</remarks>
596         [Intrinsic]
597         [MethodImpl(MethodImplOptions.AggressiveInlining)]
598         public static Vector256<short> Create(short value) => Create<short>(value);
599
600         /// <summary>Creates a new <see cref="Vector256{Int32}" /> instance with all elements initialized to the specified value.</summary>
601         /// <param name="value">The value that all elements will be initialized to.</param>
602         /// <returns>A new <see cref="Vector256{Int32}" /> with all elements initialized to <paramref name="value" />.</returns>
603         /// <remarks>On x86, this method corresponds to __m256i _mm256_set1_epi32</remarks>
604         [Intrinsic]
605         [MethodImpl(MethodImplOptions.AggressiveInlining)]
606         public static Vector256<int> Create(int value) => Create<int>(value);
607
608         /// <summary>Creates a new <see cref="Vector256{Int64}" /> instance with all elements initialized to the specified value.</summary>
609         /// <param name="value">The value that all elements will be initialized to.</param>
610         /// <returns>A new <see cref="Vector256{Int64}" /> with all elements initialized to <paramref name="value" />.</returns>
611         /// <remarks>On x86, this method corresponds to __m256i _mm256_set1_epi64x</remarks>
612         [Intrinsic]
613         [MethodImpl(MethodImplOptions.AggressiveInlining)]
614         public static Vector256<long> Create(long value) => Create<long>(value);
615
616         /// <summary>Creates a new <see cref="Vector256{IntPtr}" /> instance with all elements initialized to the specified value.</summary>
617         /// <param name="value">The value that all elements will be initialized to.</param>
618         /// <returns>A new <see cref="Vector256{IntPtr}" /> with all elements initialized to <paramref name="value" />.</returns>
619         [Intrinsic]
620         [MethodImpl(MethodImplOptions.AggressiveInlining)]
621         public static Vector256<nint> Create(nint value) => Create<nint>(value);
622
623         /// <summary>Creates a new <see cref="Vector256{UIntPtr}" /> instance with all elements initialized to the specified value.</summary>
624         /// <param name="value">The value that all elements will be initialized to.</param>
625         /// <returns>A new <see cref="Vector256{UIntPtr}" /> with all elements initialized to <paramref name="value" />.</returns>
626         [Intrinsic]
627         [CLSCompliant(false)]
628         [MethodImpl(MethodImplOptions.AggressiveInlining)]
629         public static Vector256<nuint> Create(nuint value) => Create<nuint>(value);
630
631         /// <summary>Creates a new <see cref="Vector256{SByte}" /> instance with all elements initialized to the specified value.</summary>
632         /// <param name="value">The value that all elements will be initialized to.</param>
633         /// <returns>A new <see cref="Vector256{SByte}" /> with all elements initialized to <paramref name="value" />.</returns>
634         /// <remarks>On x86, this method corresponds to __m256i _mm256_set1_epi8</remarks>
635         [Intrinsic]
636         [CLSCompliant(false)]
637         [MethodImpl(MethodImplOptions.AggressiveInlining)]
638         public static Vector256<sbyte> Create(sbyte value) => Create<sbyte>(value);
639
640         /// <summary>Creates a new <see cref="Vector256{Single}" /> instance with all elements initialized to the specified value.</summary>
641         /// <param name="value">The value that all elements will be initialized to.</param>
642         /// <returns>A new <see cref="Vector256{Single}" /> with all elements initialized to <paramref name="value" />.</returns>
643         /// <remarks>On x86, this method corresponds to __m256 _mm256_set1_ps</remarks>
644         [Intrinsic]
645         [MethodImpl(MethodImplOptions.AggressiveInlining)]
646         public static Vector256<float> Create(float value) => Create<float>(value);
647
648         /// <summary>Creates a new <see cref="Vector256{UInt16}" /> instance with all elements initialized to the specified value.</summary>
649         /// <param name="value">The value that all elements will be initialized to.</param>
650         /// <returns>A new <see cref="Vector256{UInt16}" /> with all elements initialized to <paramref name="value" />.</returns>
651         /// <remarks>On x86, this method corresponds to __m256i _mm256_set1_epi16</remarks>
652         [Intrinsic]
653         [CLSCompliant(false)]
654         [MethodImpl(MethodImplOptions.AggressiveInlining)]
655         public static Vector256<ushort> Create(ushort value) => Create<ushort>(value);
656
657         /// <summary>Creates a new <see cref="Vector256{UInt32}" /> instance with all elements initialized to the specified value.</summary>
658         /// <param name="value">The value that all elements will be initialized to.</param>
659         /// <returns>A new <see cref="Vector256{UInt32}" /> with all elements initialized to <paramref name="value" />.</returns>
660         /// <remarks>On x86, this method corresponds to __m256i _mm256_set1_epi32</remarks>
661         [Intrinsic]
662         [CLSCompliant(false)]
663         [MethodImpl(MethodImplOptions.AggressiveInlining)]
664         public static Vector256<uint> Create(uint value) => Create<uint>(value);
665
666         /// <summary>Creates a new <see cref="Vector256{UInt64}" /> instance with all elements initialized to the specified value.</summary>
667         /// <param name="value">The value that all elements will be initialized to.</param>
668         /// <returns>A new <see cref="Vector256{UInt64}" /> with all elements initialized to <paramref name="value" />.</returns>
669         /// <remarks>On x86, this method corresponds to __m256i _mm256_set1_epi64x</remarks>
670         [Intrinsic]
671         [CLSCompliant(false)]
672         [MethodImpl(MethodImplOptions.AggressiveInlining)]
673         public static Vector256<ulong> Create(ulong value) => Create<ulong>(value);
674
675         /// <summary>Creates a new <see cref="Vector256{T}" /> from a given array.</summary>
676         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
677         /// <param name="values">The array from which the vector is created.</param>
678         /// <returns>A new <see cref="Vector256{T}" /> with its elements set to the first <see cref="Vector256{T}.Count" /> elements from <paramref name="values" />.</returns>
679         /// <exception cref="ArgumentOutOfRangeException">The length of <paramref name="values" /> is less than <see cref="Vector256{T}.Count" />.</exception>
680         /// <exception cref="NotSupportedException">The type of <paramref name="values" /> (<typeparamref name="T" />) is not supported.</exception>
681         /// <exception cref="NullReferenceException"><paramref name="values" /> is <c>null</c>.</exception>
682         [MethodImpl(MethodImplOptions.AggressiveInlining)]
683         public static Vector256<T> Create<T>(T[] values)
684         {
685             // We explicitly don't check for `null` because historically this has thrown `NullReferenceException` for perf reasons
686
687             if (values.Length < Vector256<T>.Count)
688             {
689                 ThrowHelper.ThrowArgumentOutOfRange_IndexMustBeLessOrEqualException();
690             }
691
692             return Unsafe.ReadUnaligned<Vector256<T>>(ref Unsafe.As<T, byte>(ref values[0]));
693         }
694
695         /// <summary>Creates a new <see cref="Vector256{T}" /> from a given array.</summary>
696         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
697         /// <param name="values">The array from which the vector is created.</param>
698         /// <param name="index">The index in <paramref name="values" /> at which to being reading elements.</param>
699         /// <returns>A new <see cref="Vector256{T}" /> with its elements set to the first <see cref="Vector128{T}.Count" /> elements from <paramref name="values" />.</returns>
700         /// <exception cref="ArgumentOutOfRangeException">The length of <paramref name="values" />, starting from <paramref name="index" />, is less than <see cref="Vector256{T}.Count" />.</exception>
701         /// <exception cref="NotSupportedException">The type of <paramref name="values" /> (<typeparamref name="T" />) is not supported.</exception>
702         /// <exception cref="NullReferenceException"><paramref name="values" /> is <c>null</c>.</exception>
703         [MethodImpl(MethodImplOptions.AggressiveInlining)]
704         public static Vector256<T> Create<T>(T[] values, int index)
705         {
706             // We explicitly don't check for `null` because historically this has thrown `NullReferenceException` for perf reasons
707
708             if ((index < 0) || ((values.Length - index) < Vector256<T>.Count))
709             {
710                 ThrowHelper.ThrowArgumentOutOfRange_IndexMustBeLessOrEqualException();
711             }
712
713             return Unsafe.ReadUnaligned<Vector256<T>>(ref Unsafe.As<T, byte>(ref values[index]));
714         }
715
716         /// <summary>Creates a new <see cref="Vector256{T}" /> from a given readonly span.</summary>
717         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
718         /// <param name="values">The readonly span from which the vector is created.</param>
719         /// <returns>A new <see cref="Vector256{T}" /> with its elements set to the first <see cref="Vector256{T}.Count" /> elements from <paramref name="values" />.</returns>
720         /// <exception cref="ArgumentOutOfRangeException">The length of <paramref name="values" /> is less than <see cref="Vector256{T}.Count" />.</exception>
721         /// <exception cref="NotSupportedException">The type of <paramref name="values" /> (<typeparamref name="T" />) is not supported.</exception>
722         [MethodImpl(MethodImplOptions.AggressiveInlining)]
723         public static Vector256<T> Create<T>(ReadOnlySpan<T> values)
724         {
725             if (values.Length < Vector256<T>.Count)
726             {
727                 ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.values);
728             }
729
730             return Unsafe.ReadUnaligned<Vector256<T>>(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)));
731         }
732
733         /// <summary>Creates a new <see cref="Vector256{Byte}" /> instance with each element initialized to the corresponding specified value.</summary>
734         /// <param name="e0">The value that element 0 will be initialized to.</param>
735         /// <param name="e1">The value that element 1 will be initialized to.</param>
736         /// <param name="e2">The value that element 2 will be initialized to.</param>
737         /// <param name="e3">The value that element 3 will be initialized to.</param>
738         /// <param name="e4">The value that element 4 will be initialized to.</param>
739         /// <param name="e5">The value that element 5 will be initialized to.</param>
740         /// <param name="e6">The value that element 6 will be initialized to.</param>
741         /// <param name="e7">The value that element 7 will be initialized to.</param>
742         /// <param name="e8">The value that element 8 will be initialized to.</param>
743         /// <param name="e9">The value that element 9 will be initialized to.</param>
744         /// <param name="e10">The value that element 10 will be initialized to.</param>
745         /// <param name="e11">The value that element 11 will be initialized to.</param>
746         /// <param name="e12">The value that element 12 will be initialized to.</param>
747         /// <param name="e13">The value that element 13 will be initialized to.</param>
748         /// <param name="e14">The value that element 14 will be initialized to.</param>
749         /// <param name="e15">The value that element 15 will be initialized to.</param>
750         /// <param name="e16">The value that element 16 will be initialized to.</param>
751         /// <param name="e17">The value that element 17 will be initialized to.</param>
752         /// <param name="e18">The value that element 18 will be initialized to.</param>
753         /// <param name="e19">The value that element 19 will be initialized to.</param>
754         /// <param name="e20">The value that element 20 will be initialized to.</param>
755         /// <param name="e21">The value that element 21 will be initialized to.</param>
756         /// <param name="e22">The value that element 22 will be initialized to.</param>
757         /// <param name="e23">The value that element 23 will be initialized to.</param>
758         /// <param name="e24">The value that element 24 will be initialized to.</param>
759         /// <param name="e25">The value that element 25 will be initialized to.</param>
760         /// <param name="e26">The value that element 26 will be initialized to.</param>
761         /// <param name="e27">The value that element 27 will be initialized to.</param>
762         /// <param name="e28">The value that element 28 will be initialized to.</param>
763         /// <param name="e29">The value that element 29 will be initialized to.</param>
764         /// <param name="e30">The value that element 30 will be initialized to.</param>
765         /// <param name="e31">The value that element 31 will be initialized to.</param>
766         /// <returns>A new <see cref="Vector256{Byte}" /> with each element initialized to corresponding specified value.</returns>
767         /// <remarks>On x86, this method corresponds to __m256i _mm256_setr_epi8</remarks>
768         [Intrinsic]
769         [MethodImpl(MethodImplOptions.AggressiveInlining)]
770         public static Vector256<byte> 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,
771                                              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)
772         {
773             return Create(
774                 Vector128.Create(e0,  e1,  e2,  e3,  e4,  e5,  e6,  e7,  e8,  e9,  e10, e11, e12, e13, e14, e15),
775                 Vector128.Create(e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31)
776             );
777         }
778
779         /// <summary>Creates a new <see cref="Vector256{Double}" /> instance with each element initialized to the corresponding specified value.</summary>
780         /// <param name="e0">The value that element 0 will be initialized to.</param>
781         /// <param name="e1">The value that element 1 will be initialized to.</param>
782         /// <param name="e2">The value that element 2 will be initialized to.</param>
783         /// <param name="e3">The value that element 3 will be initialized to.</param>
784         /// <returns>A new <see cref="Vector256{Double}" /> with each element initialized to corresponding specified value.</returns>
785         /// <remarks>On x86, this method corresponds to __m256d _mm256_setr_pd</remarks>
786         [Intrinsic]
787         [MethodImpl(MethodImplOptions.AggressiveInlining)]
788         public static Vector256<double> Create(double e0, double e1, double e2, double e3)
789         {
790             return Create(
791                 Vector128.Create(e0, e1),
792                 Vector128.Create(e2, e3)
793             );
794         }
795
796         /// <summary>Creates a new <see cref="Vector256{Int16}" /> instance with each element initialized to the corresponding specified value.</summary>
797         /// <param name="e0">The value that element 0 will be initialized to.</param>
798         /// <param name="e1">The value that element 1 will be initialized to.</param>
799         /// <param name="e2">The value that element 2 will be initialized to.</param>
800         /// <param name="e3">The value that element 3 will be initialized to.</param>
801         /// <param name="e4">The value that element 4 will be initialized to.</param>
802         /// <param name="e5">The value that element 5 will be initialized to.</param>
803         /// <param name="e6">The value that element 6 will be initialized to.</param>
804         /// <param name="e7">The value that element 7 will be initialized to.</param>
805         /// <param name="e8">The value that element 8 will be initialized to.</param>
806         /// <param name="e9">The value that element 9 will be initialized to.</param>
807         /// <param name="e10">The value that element 10 will be initialized to.</param>
808         /// <param name="e11">The value that element 11 will be initialized to.</param>
809         /// <param name="e12">The value that element 12 will be initialized to.</param>
810         /// <param name="e13">The value that element 13 will be initialized to.</param>
811         /// <param name="e14">The value that element 14 will be initialized to.</param>
812         /// <param name="e15">The value that element 15 will be initialized to.</param>
813         /// <returns>A new <see cref="Vector256{Int16}" /> with each element initialized to corresponding specified value.</returns>
814         /// <remarks>On x86, this method corresponds to __m256i _mm256_setr_epi16</remarks>
815         [Intrinsic]
816         [MethodImpl(MethodImplOptions.AggressiveInlining)]
817         public static Vector256<short> Create(short e0, short e1, short e2, short e3, short e4, short e5, short e6, short e7, short e8, short e9, short e10, short e11, short e12, short e13, short e14, short e15)
818         {
819             return Create(
820                 Vector128.Create(e0, e1, e2,  e3,  e4,  e5,  e6,  e7),
821                 Vector128.Create(e8, e9, e10, e11, e12, e13, e14, e15)
822             );
823         }
824
825         /// <summary>Creates a new <see cref="Vector256{Int32}" /> instance with each element initialized to the corresponding specified value.</summary>
826         /// <param name="e0">The value that element 0 will be initialized to.</param>
827         /// <param name="e1">The value that element 1 will be initialized to.</param>
828         /// <param name="e2">The value that element 2 will be initialized to.</param>
829         /// <param name="e3">The value that element 3 will be initialized to.</param>
830         /// <param name="e4">The value that element 4 will be initialized to.</param>
831         /// <param name="e5">The value that element 5 will be initialized to.</param>
832         /// <param name="e6">The value that element 6 will be initialized to.</param>
833         /// <param name="e7">The value that element 7 will be initialized to.</param>
834         /// <returns>A new <see cref="Vector256{Int32}" /> with each element initialized to corresponding specified value.</returns>
835         /// <remarks>On x86, this method corresponds to __m256i _mm256_setr_epi32</remarks>
836         [Intrinsic]
837         [MethodImpl(MethodImplOptions.AggressiveInlining)]
838         public static Vector256<int> Create(int e0, int e1, int e2, int e3, int e4, int e5, int e6, int e7)
839         {
840             return Create(
841                 Vector128.Create(e0, e1, e2, e3),
842                 Vector128.Create(e4, e5, e6, e7)
843             );
844         }
845
846         /// <summary>Creates a new <see cref="Vector256{Int64}" /> instance with each element initialized to the corresponding specified value.</summary>
847         /// <param name="e0">The value that element 0 will be initialized to.</param>
848         /// <param name="e1">The value that element 1 will be initialized to.</param>
849         /// <param name="e2">The value that element 2 will be initialized to.</param>
850         /// <param name="e3">The value that element 3 will be initialized to.</param>
851         /// <returns>A new <see cref="Vector256{Int64}" /> with each element initialized to corresponding specified value.</returns>
852         /// <remarks>On x86, this method corresponds to __m256i _mm256_setr_epi64x</remarks>
853         [Intrinsic]
854         [MethodImpl(MethodImplOptions.AggressiveInlining)]
855         public static Vector256<long> Create(long e0, long e1, long e2, long e3)
856         {
857             return Create(
858                 Vector128.Create(e0, e1),
859                 Vector128.Create(e2, e3)
860             );
861         }
862
863         /// <summary>Creates a new <see cref="Vector256{SByte}" /> instance with each element initialized to the corresponding specified value.</summary>
864         /// <param name="e0">The value that element 0 will be initialized to.</param>
865         /// <param name="e1">The value that element 1 will be initialized to.</param>
866         /// <param name="e2">The value that element 2 will be initialized to.</param>
867         /// <param name="e3">The value that element 3 will be initialized to.</param>
868         /// <param name="e4">The value that element 4 will be initialized to.</param>
869         /// <param name="e5">The value that element 5 will be initialized to.</param>
870         /// <param name="e6">The value that element 6 will be initialized to.</param>
871         /// <param name="e7">The value that element 7 will be initialized to.</param>
872         /// <param name="e8">The value that element 8 will be initialized to.</param>
873         /// <param name="e9">The value that element 9 will be initialized to.</param>
874         /// <param name="e10">The value that element 10 will be initialized to.</param>
875         /// <param name="e11">The value that element 11 will be initialized to.</param>
876         /// <param name="e12">The value that element 12 will be initialized to.</param>
877         /// <param name="e13">The value that element 13 will be initialized to.</param>
878         /// <param name="e14">The value that element 14 will be initialized to.</param>
879         /// <param name="e15">The value that element 15 will be initialized to.</param>
880         /// <param name="e16">The value that element 16 will be initialized to.</param>
881         /// <param name="e17">The value that element 17 will be initialized to.</param>
882         /// <param name="e18">The value that element 18 will be initialized to.</param>
883         /// <param name="e19">The value that element 19 will be initialized to.</param>
884         /// <param name="e20">The value that element 20 will be initialized to.</param>
885         /// <param name="e21">The value that element 21 will be initialized to.</param>
886         /// <param name="e22">The value that element 22 will be initialized to.</param>
887         /// <param name="e23">The value that element 23 will be initialized to.</param>
888         /// <param name="e24">The value that element 24 will be initialized to.</param>
889         /// <param name="e25">The value that element 25 will be initialized to.</param>
890         /// <param name="e26">The value that element 26 will be initialized to.</param>
891         /// <param name="e27">The value that element 27 will be initialized to.</param>
892         /// <param name="e28">The value that element 28 will be initialized to.</param>
893         /// <param name="e29">The value that element 29 will be initialized to.</param>
894         /// <param name="e30">The value that element 30 will be initialized to.</param>
895         /// <param name="e31">The value that element 31 will be initialized to.</param>
896         /// <returns>A new <see cref="Vector256{SByte}" /> with each element initialized to corresponding specified value.</returns>
897         /// <remarks>On x86, this method corresponds to __m256i _mm256_setr_epi8</remarks>
898         [Intrinsic]
899         [CLSCompliant(false)]
900         [MethodImpl(MethodImplOptions.AggressiveInlining)]
901         public static Vector256<sbyte> 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,
902                                               sbyte e16, sbyte e17, sbyte e18, sbyte e19, sbyte e20, sbyte e21, sbyte e22, sbyte e23, sbyte e24, sbyte e25, sbyte e26, sbyte e27, sbyte e28, sbyte e29, sbyte e30, sbyte e31)
903         {
904             return Create(
905                 Vector128.Create(e0,  e1,  e2,  e3,  e4,  e5,  e6,  e7,  e8,  e9,  e10, e11, e12, e13, e14, e15),
906                 Vector128.Create(e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31)
907             );
908         }
909
910         /// <summary>Creates a new <see cref="Vector256{Single}" /> instance with each element initialized to the corresponding specified value.</summary>
911         /// <param name="e0">The value that element 0 will be initialized to.</param>
912         /// <param name="e1">The value that element 1 will be initialized to.</param>
913         /// <param name="e2">The value that element 2 will be initialized to.</param>
914         /// <param name="e3">The value that element 3 will be initialized to.</param>
915         /// <param name="e4">The value that element 4 will be initialized to.</param>
916         /// <param name="e5">The value that element 5 will be initialized to.</param>
917         /// <param name="e6">The value that element 6 will be initialized to.</param>
918         /// <param name="e7">The value that element 7 will be initialized to.</param>
919         /// <returns>A new <see cref="Vector256{Single}" /> with each element initialized to corresponding specified value.</returns>
920         /// <remarks>On x86, this method corresponds to __m256 _mm256_setr_ps</remarks>
921         [Intrinsic]
922         [MethodImpl(MethodImplOptions.AggressiveInlining)]
923         public static Vector256<float> Create(float e0, float e1, float e2, float e3, float e4, float e5, float e6, float e7)
924         {
925             return Create(
926                 Vector128.Create(e0, e1, e2, e3),
927                 Vector128.Create(e4, e5, e6, e7)
928             );
929         }
930
931         /// <summary>Creates a new <see cref="Vector256{UInt16}" /> instance with each element initialized to the corresponding specified value.</summary>
932         /// <param name="e0">The value that element 0 will be initialized to.</param>
933         /// <param name="e1">The value that element 1 will be initialized to.</param>
934         /// <param name="e2">The value that element 2 will be initialized to.</param>
935         /// <param name="e3">The value that element 3 will be initialized to.</param>
936         /// <param name="e4">The value that element 4 will be initialized to.</param>
937         /// <param name="e5">The value that element 5 will be initialized to.</param>
938         /// <param name="e6">The value that element 6 will be initialized to.</param>
939         /// <param name="e7">The value that element 7 will be initialized to.</param>
940         /// <param name="e8">The value that element 8 will be initialized to.</param>
941         /// <param name="e9">The value that element 9 will be initialized to.</param>
942         /// <param name="e10">The value that element 10 will be initialized to.</param>
943         /// <param name="e11">The value that element 11 will be initialized to.</param>
944         /// <param name="e12">The value that element 12 will be initialized to.</param>
945         /// <param name="e13">The value that element 13 will be initialized to.</param>
946         /// <param name="e14">The value that element 14 will be initialized to.</param>
947         /// <param name="e15">The value that element 15 will be initialized to.</param>
948         /// <returns>A new <see cref="Vector256{UInt16}" /> with each element initialized to corresponding specified value.</returns>
949         /// <remarks>On x86, this method corresponds to __m256i _mm256_setr_epi16</remarks>
950         [Intrinsic]
951         [CLSCompliant(false)]
952         [MethodImpl(MethodImplOptions.AggressiveInlining)]
953         public static Vector256<ushort> Create(ushort e0, ushort e1, ushort e2, ushort e3, ushort e4, ushort e5, ushort e6, ushort e7, ushort e8, ushort e9, ushort e10, ushort e11, ushort e12, ushort e13, ushort e14, ushort e15)
954         {
955             return Create(
956                 Vector128.Create(e0, e1, e2,  e3,  e4,  e5,  e6,  e7),
957                 Vector128.Create(e8, e9, e10, e11, e12, e13, e14, e15)
958             );
959         }
960
961         /// <summary>Creates a new <see cref="Vector256{UInt32}" /> instance with each element initialized to the corresponding specified value.</summary>
962         /// <param name="e0">The value that element 0 will be initialized to.</param>
963         /// <param name="e1">The value that element 1 will be initialized to.</param>
964         /// <param name="e2">The value that element 2 will be initialized to.</param>
965         /// <param name="e3">The value that element 3 will be initialized to.</param>
966         /// <param name="e4">The value that element 4 will be initialized to.</param>
967         /// <param name="e5">The value that element 5 will be initialized to.</param>
968         /// <param name="e6">The value that element 6 will be initialized to.</param>
969         /// <param name="e7">The value that element 7 will be initialized to.</param>
970         /// <returns>A new <see cref="Vector256{UInt32}" /> with each element initialized to corresponding specified value.</returns>
971         /// <remarks>On x86, this method corresponds to __m256i _mm256_setr_epi32</remarks>
972         [Intrinsic]
973         [CLSCompliant(false)]
974         [MethodImpl(MethodImplOptions.AggressiveInlining)]
975         public static Vector256<uint> Create(uint e0, uint e1, uint e2, uint e3, uint e4, uint e5, uint e6, uint e7)
976         {
977             return Create(
978                 Vector128.Create(e0, e1, e2, e3),
979                 Vector128.Create(e4, e5, e6, e7)
980             );
981         }
982
983         /// <summary>Creates a new <see cref="Vector256{UInt64}" /> instance with each element initialized to the corresponding specified value.</summary>
984         /// <param name="e0">The value that element 0 will be initialized to.</param>
985         /// <param name="e1">The value that element 1 will be initialized to.</param>
986         /// <param name="e2">The value that element 2 will be initialized to.</param>
987         /// <param name="e3">The value that element 3 will be initialized to.</param>
988         /// <returns>A new <see cref="Vector256{UInt64}" /> with each element initialized to corresponding specified value.</returns>
989         /// <remarks>On x86, this method corresponds to __m256i _mm256_setr_epi64x</remarks>
990         [Intrinsic]
991         [CLSCompliant(false)]
992         [MethodImpl(MethodImplOptions.AggressiveInlining)]
993         public static Vector256<ulong> Create(ulong e0, ulong e1, ulong e2, ulong e3)
994         {
995             return Create(
996                 Vector128.Create(e0, e1),
997                 Vector128.Create(e2, e3)
998             );
999         }
1000
1001         /// <summary>Creates a new <see cref="Vector256{T}" /> instance from two <see cref="Vector128{T}" /> instances.</summary>
1002         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
1003         /// <param name="lower">The value that the lower 128-bits will be initialized to.</param>
1004         /// <param name="upper">The value that the upper 128-bits will be initialized to.</param>
1005         /// <returns>A new <see cref="Vector256{T}" /> initialized from <paramref name="lower" /> and <paramref name="upper" />.</returns>
1006         /// <exception cref="NotSupportedException">The type of <paramref name="lower" /> and <paramref name="upper" /> (<typeparamref name="T" />) is not supported.</exception>
1007         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1008         public static Vector256<T> Create<T>(Vector128<T> lower, Vector128<T> upper)
1009         {
1010             if (Avx.IsSupported)
1011             {
1012                 Vector256<T> result = lower.ToVector256Unsafe();
1013                 return result.WithUpper(upper);
1014             }
1015             else
1016             {
1017                 ThrowHelper.ThrowForUnsupportedIntrinsicsVector256BaseType<T>();
1018                 Unsafe.SkipInit(out Vector256<T> result);
1019
1020                 result.SetLowerUnsafe(lower);
1021                 result.SetUpperUnsafe(upper);
1022
1023                 return result;
1024             }
1025         }
1026
1027         /// <summary>Creates a new <see cref="Vector256{Byte}" /> instance from two <see cref="Vector128{Byte}" /> instances.</summary>
1028         /// <param name="lower">The value that the lower 128-bits will be initialized to.</param>
1029         /// <param name="upper">The value that the upper 128-bits will be initialized to.</param>
1030         /// <returns>A new <see cref="Vector256{Byte}" /> initialized from <paramref name="lower" /> and <paramref name="upper" />.</returns>
1031         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1032         public static Vector256<byte> Create(Vector128<byte> lower, Vector128<byte> upper) => Create<byte>(lower, upper);
1033
1034         /// <summary>Creates a new <see cref="Vector256{Double}" /> instance from two <see cref="Vector128{Double}" /> instances.</summary>
1035         /// <param name="lower">The value that the lower 128-bits will be initialized to.</param>
1036         /// <param name="upper">The value that the upper 128-bits will be initialized to.</param>
1037         /// <returns>A new <see cref="Vector256{Double}" /> initialized from <paramref name="lower" /> and <paramref name="upper" />.</returns>
1038         /// <remarks>On x86, this method corresponds to __m256d _mm256_setr_m128d (__m128d lo, __m128d hi)</remarks>
1039         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1040         public static Vector256<double> Create(Vector128<double> lower, Vector128<double> upper) => Create<double>(lower, upper);
1041
1042         /// <summary>Creates a new <see cref="Vector256{Int16}" /> instance from two <see cref="Vector128{Int16}" /> instances.</summary>
1043         /// <param name="lower">The value that the lower 128-bits will be initialized to.</param>
1044         /// <param name="upper">The value that the upper 128-bits will be initialized to.</param>
1045         /// <returns>A new <see cref="Vector256{Int16}" /> initialized from <paramref name="lower" /> and <paramref name="upper" />.</returns>
1046         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1047         public static Vector256<short> Create(Vector128<short> lower, Vector128<short> upper) => Create<short>(lower, upper);
1048
1049         /// <summary>Creates a new <see cref="Vector256{Int32}" /> instance from two <see cref="Vector128{Int32}" /> instances.</summary>
1050         /// <param name="lower">The value that the lower 128-bits will be initialized to.</param>
1051         /// <param name="upper">The value that the upper 128-bits will be initialized to.</param>
1052         /// <returns>A new <see cref="Vector256{Int32}" /> initialized from <paramref name="lower" /> and <paramref name="upper" />.</returns>
1053         /// <remarks>On x86, this method corresponds to __m256i _mm256_setr_m128i (__m128i lo, __m128i hi)</remarks>
1054         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1055         public static Vector256<int> Create(Vector128<int> lower, Vector128<int> upper) => Create<int>(lower, upper);
1056
1057         /// <summary>Creates a new <see cref="Vector256{Int64}" /> instance from two <see cref="Vector128{Int64}" /> instances.</summary>
1058         /// <param name="lower">The value that the lower 128-bits will be initialized to.</param>
1059         /// <param name="upper">The value that the upper 128-bits will be initialized to.</param>
1060         /// <returns>A new <see cref="Vector256{Int64}" /> initialized from <paramref name="lower" /> and <paramref name="upper" />.</returns>
1061         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1062         public static Vector256<long> Create(Vector128<long> lower, Vector128<long> upper) => Create<long>(lower, upper);
1063
1064         /// <summary>Creates a new <see cref="Vector256{IntPtr}" /> instance from two <see cref="Vector128{IntPtr}" /> instances.</summary>
1065         /// <param name="lower">The value that the lower 128-bits will be initialized to.</param>
1066         /// <param name="upper">The value that the upper 128-bits will be initialized to.</param>
1067         /// <returns>A new <see cref="Vector256{IntPtr}" /> initialized from <paramref name="lower" /> and <paramref name="upper" />.</returns>
1068         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1069         public static Vector256<nint> Create(Vector128<nint> lower, Vector128<nint> upper) => Create<nint>(lower, upper);
1070
1071         /// <summary>Creates a new <see cref="Vector256{UIntPtr}" /> instance from two <see cref="Vector128{UIntPtr}" /> instances.</summary>
1072         /// <param name="lower">The value that the lower 128-bits will be initialized to.</param>
1073         /// <param name="upper">The value that the upper 128-bits will be initialized to.</param>
1074         /// <returns>A new <see cref="Vector256{UIntPtr}" /> initialized from <paramref name="lower" /> and <paramref name="upper" />.</returns>
1075         [CLSCompliant(false)]
1076         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1077         public static Vector256<nuint> Create(Vector128<nuint> lower, Vector128<nuint> upper) => Create<nuint>(lower, upper);
1078
1079         /// <summary>Creates a new <see cref="Vector256{SByte}" /> instance from two <see cref="Vector128{SByte}" /> instances.</summary>
1080         /// <param name="lower">The value that the lower 128-bits will be initialized to.</param>
1081         /// <param name="upper">The value that the upper 128-bits will be initialized to.</param>
1082         /// <returns>A new <see cref="Vector256{SByte}" /> initialized from <paramref name="lower" /> and <paramref name="upper" />.</returns>
1083         [CLSCompliant(false)]
1084         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1085         public static Vector256<sbyte> Create(Vector128<sbyte> lower, Vector128<sbyte> upper) => Create<sbyte>(lower, upper);
1086
1087         /// <summary>Creates a new <see cref="Vector256{Single}" /> instance from two <see cref="Vector128{Single}" /> instances.</summary>
1088         /// <param name="lower">The value that the lower 128-bits will be initialized to.</param>
1089         /// <param name="upper">The value that the upper 128-bits will be initialized to.</param>
1090         /// <returns>A new <see cref="Vector256{Single}" /> initialized from <paramref name="lower" /> and <paramref name="upper" />.</returns>
1091         /// <remarks>On x86, this method corresponds to __m256 _mm256_setr_m128 (__m128 lo, __m128 hi)</remarks>
1092         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1093         public static Vector256<float> Create(Vector128<float> lower, Vector128<float> upper) => Create<float>(lower, upper);
1094
1095         /// <summary>Creates a new <see cref="Vector256{UInt16}" /> instance from two <see cref="Vector128{UInt16}" /> instances.</summary>
1096         /// <param name="lower">The value that the lower 128-bits will be initialized to.</param>
1097         /// <param name="upper">The value that the upper 128-bits will be initialized to.</param>
1098         /// <returns>A new <see cref="Vector256{UInt16}" /> initialized from <paramref name="lower" /> and <paramref name="upper" />.</returns>
1099         [CLSCompliant(false)]
1100         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1101         public static Vector256<ushort> Create(Vector128<ushort> lower, Vector128<ushort> upper) => Create<ushort>(lower, upper);
1102
1103         /// <summary>Creates a new <see cref="Vector256{UInt32}" /> instance from two <see cref="Vector128{UInt32}" /> instances.</summary>
1104         /// <param name="lower">The value that the lower 128-bits will be initialized to.</param>
1105         /// <param name="upper">The value that the upper 128-bits will be initialized to.</param>
1106         /// <returns>A new <see cref="Vector256{UInt32}" /> initialized from <paramref name="lower" /> and <paramref name="upper" />.</returns>
1107         /// <remarks>On x86, this method corresponds to __m256i _mm256_setr_m128i (__m128i lo, __m128i hi)</remarks>
1108         [CLSCompliant(false)]
1109         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1110         public static Vector256<uint> Create(Vector128<uint> lower, Vector128<uint> upper) => Create<uint>(lower, upper);
1111
1112         /// <summary>Creates a new <see cref="Vector256{UInt64}" /> instance from two <see cref="Vector128{UInt64}" /> instances.</summary>
1113         /// <param name="lower">The value that the lower 128-bits will be initialized to.</param>
1114         /// <param name="upper">The value that the upper 128-bits will be initialized to.</param>
1115         /// <returns>A new <see cref="Vector256{UInt64}" /> initialized from <paramref name="lower" /> and <paramref name="upper" />.</returns>
1116         [CLSCompliant(false)]
1117         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1118         public static Vector256<ulong> Create(Vector128<ulong> lower, Vector128<ulong> upper) => Create<ulong>(lower, upper);
1119
1120         /// <summary>Creates a new <see cref="Vector256{T}" /> instance with the first element initialized to the specified value and the remaining elements initialized to zero.</summary>
1121         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
1122         /// <param name="value">The value that element 0 will be initialized to.</param>
1123         /// <returns>A new <see cref="Vector256{T}" /> instance with the first element initialized to <paramref name="value" /> and the remaining elements initialized to zero.</returns>
1124         /// <exception cref="NotSupportedException">The type of <paramref name="value" /> (<typeparamref name="T" />) is not supported.</exception>
1125         [Intrinsic]
1126         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1127         public static Vector256<T> CreateScalar<T>(T value) => Vector128.CreateScalar(value).ToVector256();
1128
1129         /// <summary>Creates a new <see cref="Vector256{Byte}" /> instance with the first element initialized to the specified value and the remaining elements initialized to zero.</summary>
1130         /// <param name="value">The value that element 0 will be initialized to.</param>
1131         /// <returns>A new <see cref="Vector256{Byte}" /> instance with the first element initialized to <paramref name="value" /> and the remaining elements initialized to zero.</returns>
1132         [Intrinsic]
1133         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1134         public static Vector256<byte> CreateScalar(byte value) => CreateScalar<byte>(value);
1135
1136         /// <summary>Creates a new <see cref="Vector256{Double}" /> instance with the first element initialized to the specified value and the remaining elements initialized to zero.</summary>
1137         /// <param name="value">The value that element 0 will be initialized to.</param>
1138         /// <returns>A new <see cref="Vector256{Double}" /> instance with the first element initialized to <paramref name="value" /> and the remaining elements initialized to zero.</returns>
1139         [Intrinsic]
1140         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1141         public static Vector256<double> CreateScalar(double value) => CreateScalar<double>(value);
1142
1143         /// <summary>Creates a new <see cref="Vector256{Int16}" /> instance with the first element initialized to the specified value and the remaining elements initialized to zero.</summary>
1144         /// <param name="value">The value that element 0 will be initialized to.</param>
1145         /// <returns>A new <see cref="Vector256{Int16}" /> instance with the first element initialized to <paramref name="value" /> and the remaining elements initialized to zero.</returns>
1146         [Intrinsic]
1147         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1148         public static Vector256<short> CreateScalar(short value) => CreateScalar<short>(value);
1149
1150         /// <summary>Creates a new <see cref="Vector256{Int32}" /> instance with the first element initialized to the specified value and the remaining elements initialized to zero.</summary>
1151         /// <param name="value">The value that element 0 will be initialized to.</param>
1152         /// <returns>A new <see cref="Vector256{Int32}" /> instance with the first element initialized to <paramref name="value" /> and the remaining elements initialized to zero.</returns>
1153         [Intrinsic]
1154         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1155         public static Vector256<int> CreateScalar(int value) => CreateScalar<int>(value);
1156
1157         /// <summary>Creates a new <see cref="Vector256{Int64}" /> instance with the first element initialized to the specified value and the remaining elements initialized to zero.</summary>
1158         /// <param name="value">The value that element 0 will be initialized to.</param>
1159         /// <returns>A new <see cref="Vector256{Int64}" /> instance with the first element initialized to <paramref name="value" /> and the remaining elements initialized to zero.</returns>
1160         [Intrinsic]
1161         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1162         public static Vector256<long> CreateScalar(long value) => CreateScalar<long>(value);
1163
1164         /// <summary>Creates a new <see cref="Vector256{IntPtr}" /> instance with the first element initialized to the specified value and the remaining elements initialized to zero.</summary>
1165         /// <param name="value">The value that element 0 will be initialized to.</param>
1166         /// <returns>A new <see cref="Vector256{IntPtr}" /> instance with the first element initialized to <paramref name="value"/> and the remaining elements initialized to zero.</returns>
1167         [Intrinsic]
1168         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1169         public static Vector256<nint> CreateScalar(nint value) => CreateScalar<nint>(value);
1170
1171         /// <summary>Creates a new <see cref="Vector256{UIntPtr}" /> instance with the first element initialized to the specified value and the remaining elements initialized to zero.</summary>
1172         /// <param name="value">The value that element 0 will be initialized to.</param>
1173         /// <returns>A new <see cref="Vector256{UIntPtr}" /> instance with the first element initialized to <paramref name="value"/> and the remaining elements initialized to zero.</returns>
1174         [Intrinsic]
1175         [CLSCompliant(false)]
1176         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1177         public static Vector256<nuint> CreateScalar(nuint value) => CreateScalar<nuint>(value);
1178
1179         /// <summary>Creates a new <see cref="Vector256{SByte}" /> instance with the first element initialized to the specified value and the remaining elements initialized to zero.</summary>
1180         /// <param name="value">The value that element 0 will be initialized to.</param>
1181         /// <returns>A new <see cref="Vector256{SByte}" /> instance with the first element initialized to <paramref name="value" /> and the remaining elements initialized to zero.</returns>
1182         [Intrinsic]
1183         [CLSCompliant(false)]
1184         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1185         public static Vector256<sbyte> CreateScalar(sbyte value) => CreateScalar<sbyte>(value);
1186
1187         /// <summary>Creates a new <see cref="Vector256{Single}" /> instance with the first element initialized to the specified value and the remaining elements initialized to zero.</summary>
1188         /// <param name="value">The value that element 0 will be initialized to.</param>
1189         /// <returns>A new <see cref="Vector256{Single}" /> instance with the first element initialized to <paramref name="value" /> and the remaining elements initialized to zero.</returns>
1190         [Intrinsic]
1191         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1192         public static Vector256<float> CreateScalar(float value) => CreateScalar<float>(value);
1193
1194         /// <summary>Creates a new <see cref="Vector256{UInt16}" /> instance with the first element initialized to the specified value and the remaining elements initialized to zero.</summary>
1195         /// <param name="value">The value that element 0 will be initialized to.</param>
1196         /// <returns>A new <see cref="Vector256{UInt16}" /> instance with the first element initialized to <paramref name="value" /> and the remaining elements initialized to zero.</returns>
1197         [Intrinsic]
1198         [CLSCompliant(false)]
1199         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1200         public static Vector256<ushort> CreateScalar(ushort value) => CreateScalar<ushort>(value);
1201
1202         /// <summary>Creates a new <see cref="Vector256{UInt32}" /> instance with the first element initialized to the specified value and the remaining elements initialized to zero.</summary>
1203         /// <param name="value">The value that element 0 will be initialized to.</param>
1204         /// <returns>A new <see cref="Vector256{UInt32}" /> instance with the first element initialized to <paramref name="value" /> and the remaining elements initialized to zero.</returns>
1205         [Intrinsic]
1206         [CLSCompliant(false)]
1207         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1208         public static Vector256<uint> CreateScalar(uint value) => CreateScalar<uint>(value);
1209
1210         /// <summary>Creates a new <see cref="Vector256{UInt64}" /> instance with the first element initialized to the specified value and the remaining elements initialized to zero.</summary>
1211         /// <param name="value">The value that element 0 will be initialized to.</param>
1212         /// <returns>A new <see cref="Vector256{UInt64}" /> instance with the first element initialized to <paramref name="value" /> and the remaining elements initialized to zero.</returns>
1213         [Intrinsic]
1214         [CLSCompliant(false)]
1215         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1216         public static Vector256<ulong> CreateScalar(ulong value) => CreateScalar<ulong>(value);
1217
1218         /// <summary>Creates a new <see cref="Vector256{T}" /> instance with the first element initialized to the specified value and the remaining elements left uninitialized.</summary>
1219         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
1220         /// <param name="value">The value that element 0 will be initialized to.</param>
1221         /// <returns>A new <see cref="Vector256{T}" /> instance with the first element initialized to <paramref name="value" /> and the remaining elements left uninitialized.</returns>
1222         /// <exception cref="NotSupportedException">The type of <paramref name="value" /> (<typeparamref name="T" />) is not supported.</exception>
1223         [Intrinsic]
1224         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1225         public static Vector256<T> CreateScalarUnsafe<T>(T value)
1226         {
1227             // This relies on us stripping the "init" flag from the ".locals"
1228             // declaration to let the upper bits be uninitialized.
1229
1230             ThrowHelper.ThrowForUnsupportedIntrinsicsVector256BaseType<T>();
1231             Unsafe.SkipInit(out Vector256<T> result);
1232
1233             result.SetElementUnsafe(0, value);
1234             return result;
1235         }
1236
1237         /// <summary>Creates a new <see cref="Vector256{Byte}" /> instance with the first element initialized to the specified value and the remaining elements left uninitialized.</summary>
1238         /// <param name="value">The value that element 0 will be initialized to.</param>
1239         /// <returns>A new <see cref="Vector256{Byte}" /> instance with the first element initialized to <paramref name="value" /> and the remaining elements left uninitialized.</returns>
1240         [Intrinsic]
1241         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1242         public static Vector256<byte> CreateScalarUnsafe(byte value) => CreateScalarUnsafe<byte>(value);
1243
1244         /// <summary>Creates a new <see cref="Vector256{Double}" /> instance with the first element initialized to the specified value and the remaining elements left uninitialized.</summary>
1245         /// <param name="value">The value that element 0 will be initialized to.</param>
1246         /// <returns>A new <see cref="Vector256{Double}" /> instance with the first element initialized to <paramref name="value" /> and the remaining elements left uninitialized.</returns>
1247         [Intrinsic]
1248         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1249         public static Vector256<double> CreateScalarUnsafe(double value) => CreateScalarUnsafe<double>(value);
1250
1251         /// <summary>Creates a new <see cref="Vector256{Int16}" /> instance with the first element initialized to the specified value and the remaining elements left uninitialized.</summary>
1252         /// <param name="value">The value that element 0 will be initialized to.</param>
1253         /// <returns>A new <see cref="Vector256{Int16}" /> instance with the first element initialized to <paramref name="value" /> and the remaining elements left uninitialized.</returns>
1254         [Intrinsic]
1255         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1256         public static Vector256<short> CreateScalarUnsafe(short value) => CreateScalarUnsafe<short>(value);
1257
1258         /// <summary>Creates a new <see cref="Vector256{Int32}" /> instance with the first element initialized to the specified value and the remaining elements left uninitialized.</summary>
1259         /// <param name="value">The value that element 0 will be initialized to.</param>
1260         /// <returns>A new <see cref="Vector256{Int32}" /> instance with the first element initialized to <paramref name="value" /> and the remaining elements left uninitialized.</returns>
1261         [Intrinsic]
1262         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1263         public static Vector256<int> CreateScalarUnsafe(int value) => CreateScalarUnsafe<int>(value);
1264
1265         /// <summary>Creates a new <see cref="Vector256{Int64}" /> instance with the first element initialized to the specified value and the remaining elements left uninitialized.</summary>
1266         /// <param name="value">The value that element 0 will be initialized to.</param>
1267         /// <returns>A new <see cref="Vector256{Int64}" /> instance with the first element initialized to <paramref name="value" /> and the remaining elements left uninitialized.</returns>
1268         [Intrinsic]
1269         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1270         public static Vector256<long> CreateScalarUnsafe(long value) => CreateScalarUnsafe<long>(value);
1271
1272         /// <summary>Creates a new <see cref="Vector256{IntPtr}" /> instance with the first element initialized to the specified value and the remaining elements left uninitialized.</summary>
1273         /// <param name="value">The value that element 0 will be initialized to.</param>
1274         /// <returns>A new <see cref="Vector256{IntPtr}" /> instance with the first element initialized to <paramref name="value"/> and the remaining elements left uninitialized.</returns>
1275         [Intrinsic]
1276         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1277         public static Vector256<nint> CreateScalarUnsafe(nint value) => CreateScalarUnsafe<nint>(value);
1278
1279         /// <summary>Creates a new <see cref="Vector256{UIntPtr}" /> instance with the first element initialized to the specified value and the remaining elements left uninitialized.</summary>
1280         /// <param name="value">The value that element 0 will be initialized to.</param>
1281         /// <returns>A new <see cref="Vector256{UIntPtr}" /> instance with the first element initialized to <paramref name="value"/> and the remaining elements left uninitialized.</returns>
1282         [Intrinsic]
1283         [CLSCompliant(false)]
1284         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1285         public static Vector256<nuint> CreateScalarUnsafe(nuint value) => CreateScalarUnsafe<nuint>(value);
1286
1287         /// <summary>Creates a new <see cref="Vector256{SByte}" /> instance with the first element initialized to the specified value and the remaining elements left uninitialized.</summary>
1288         /// <param name="value">The value that element 0 will be initialized to.</param>
1289         /// <returns>A new <see cref="Vector256{SByte}" /> instance with the first element initialized to <paramref name="value" /> and the remaining elements left uninitialized.</returns>
1290         [Intrinsic]
1291         [CLSCompliant(false)]
1292         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1293         public static Vector256<sbyte> CreateScalarUnsafe(sbyte value) => CreateScalarUnsafe<sbyte>(value);
1294
1295         /// <summary>Creates a new <see cref="Vector256{Single}" /> instance with the first element initialized to the specified value and the remaining elements left uninitialized.</summary>
1296         /// <param name="value">The value that element 0 will be initialized to.</param>
1297         /// <returns>A new <see cref="Vector256{Single}" /> instance with the first element initialized to <paramref name="value" /> and the remaining elements left uninitialized.</returns>
1298         [Intrinsic]
1299         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1300         public static Vector256<float> CreateScalarUnsafe(float value) => CreateScalarUnsafe<float>(value);
1301
1302         /// <summary>Creates a new <see cref="Vector256{UInt16}" /> instance with the first element initialized to the specified value and the remaining elements left uninitialized.</summary>
1303         /// <param name="value">The value that element 0 will be initialized to.</param>
1304         /// <returns>A new <see cref="Vector256{UInt16}" /> instance with the first element initialized to <paramref name="value" /> and the remaining elements left uninitialized.</returns>
1305         [Intrinsic]
1306         [CLSCompliant(false)]
1307         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1308         public static Vector256<ushort> CreateScalarUnsafe(ushort value) => CreateScalarUnsafe<ushort>(value);
1309
1310         /// <summary>Creates a new <see cref="Vector256{UInt32}" /> instance with the first element initialized to the specified value and the remaining elements left uninitialized.</summary>
1311         /// <param name="value">The value that element 0 will be initialized to.</param>
1312         /// <returns>A new <see cref="Vector256{UInt32}" /> instance with the first element initialized to <paramref name="value" /> and the remaining elements left uninitialized.</returns>
1313         [Intrinsic]
1314         [CLSCompliant(false)]
1315         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1316         public static Vector256<uint> CreateScalarUnsafe(uint value) => CreateScalarUnsafe<uint>(value);
1317
1318         /// <summary>Creates a new <see cref="Vector256{UInt64}" /> instance with the first element initialized to the specified value and the remaining elements left uninitialized.</summary>
1319         /// <param name="value">The value that element 0 will be initialized to.</param>
1320         /// <returns>A new <see cref="Vector256{UInt64}" /> instance with the first element initialized to <paramref name="value" /> and the remaining elements left uninitialized.</returns>
1321         [Intrinsic]
1322         [CLSCompliant(false)]
1323         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1324         public static Vector256<ulong> CreateScalarUnsafe(ulong value) => CreateScalarUnsafe<ulong>(value);
1325
1326         /// <summary>Divides two vectors to compute their quotient.</summary>
1327         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
1328         /// <param name="left">The vector that will be divided by <paramref name="right" />.</param>
1329         /// <param name="right">The vector that will divide <paramref name="left" />.</param>
1330         /// <returns>The quotient of <paramref name="left" /> divided by <paramref name="right" />.</returns>
1331         /// <exception cref="NotSupportedException">The type of <paramref name="left" /> and <paramref name="right" /> (<typeparamref name="T" />) is not supported.</exception>
1332         [Intrinsic]
1333         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1334         public static Vector256<T> Divide<T>(Vector256<T> left, Vector256<T> right) => left / right;
1335
1336         /// <summary>Divides a vector by a scalar to compute the per-element quotient.</summary>
1337         /// <param name="left">The vector that will be divided by <paramref name="right" />.</param>
1338         /// <param name="right">The scalar that will divide <paramref name="left" />.</param>
1339         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
1340         /// <returns>The quotient of <paramref name="left" /> divided by <paramref name="right" />.</returns>
1341         [Intrinsic]
1342         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1343         public static Vector256<T> Divide<T>(Vector256<T> left, T right) => left / right;
1344
1345         /// <summary>Computes the dot product of two vectors.</summary>
1346         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
1347         /// <param name="left">The vector that will be dotted with <paramref name="right" />.</param>
1348         /// <param name="right">The vector that will be dotted with <paramref name="left" />.</param>
1349         /// <returns>The dot product of <paramref name="left" /> and <paramref name="right" />.</returns>
1350         /// <exception cref="NotSupportedException">The type of <paramref name="left" /> and <paramref name="right" /> (<typeparamref name="T" />) is not supported.</exception>
1351         [Intrinsic]
1352         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1353         public static T Dot<T>(Vector256<T> left, Vector256<T> right)
1354         {
1355             // Doing this as Dot(lower) + Dot(upper) is important for floating-point determinism
1356             // This is because the underlying dpps instruction on x86/x64 will do this equivalently
1357             // and otherwise the software vs accelerated implementations may differ in returned result.
1358
1359             T result = Vector128.Dot(left._lower, right._lower);
1360             result = Scalar<T>.Add(result, Vector128.Dot(left._upper, right._upper));
1361             return result;
1362         }
1363
1364         /// <summary>Compares two vectors to determine if they are equal on a per-element basis.</summary>
1365         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
1366         /// <param name="left">The vector to compare with <paramref name="right" />.</param>
1367         /// <param name="right">The vector to compare with <paramref name="left" />.</param>
1368         /// <returns>A vector whose elements are all-bits-set or zero, depending on if the corresponding elements in <paramref name="left" /> and <paramref name="right" /> were equal.</returns>
1369         /// <exception cref="NotSupportedException">The type of <paramref name="left" /> and <paramref name="right" /> (<typeparamref name="T" />) is not supported.</exception>
1370         [Intrinsic]
1371         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1372         public static Vector256<T> Equals<T>(Vector256<T> left, Vector256<T> right)
1373         {
1374             return Create(
1375                 Vector128.Equals(left._lower, right._lower),
1376                 Vector128.Equals(left._upper, right._upper)
1377             );
1378         }
1379
1380         /// <summary>Compares two vectors to determine if all elements are equal.</summary>
1381         /// <param name="left">The vector to compare with <paramref name="right" />.</param>
1382         /// <param name="right">The vector to compare with <paramref name="left" />.</param>
1383         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
1384         /// <returns><c>true</c> if all elements in <paramref name="left" /> were equal to the corresponding element in <paramref name="right" />.</returns>
1385         /// <exception cref="NotSupportedException">The type of <paramref name="left" /> and <paramref name="right" /> (<typeparamref name="T" />) is not supported.</exception>
1386         [Intrinsic]
1387         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1388         public static bool EqualsAll<T>(Vector256<T> left, Vector256<T> right) => left == right;
1389
1390         /// <summary>Compares two vectors to determine if any elements are equal.</summary>
1391         /// <param name="left">The vector to compare with <paramref name="right" />.</param>
1392         /// <param name="right">The vector to compare with <paramref name="left" />.</param>
1393         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
1394         /// <returns><c>true</c> if any elements in <paramref name="left" /> was equal to the corresponding element in <paramref name="right" />.</returns>
1395         /// <exception cref="NotSupportedException">The type of <paramref name="left" /> and <paramref name="right" /> (<typeparamref name="T" />) is not supported.</exception>
1396         [Intrinsic]
1397         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1398         public static bool EqualsAny<T>(Vector256<T> left, Vector256<T> right)
1399         {
1400             return Vector128.EqualsAny(left._lower, right._lower)
1401                 || Vector128.EqualsAny(left._upper, right._upper);
1402         }
1403
1404         /// <summary>Extracts the most significant bit from each element in a vector.</summary>
1405         /// <param name="vector">The vector whose elements should have their most significant bit extracted.</param>
1406         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
1407         /// <returns>The packed most significant bits extracted from the elements in <paramref name="vector" />.</returns>
1408         /// <exception cref="NotSupportedException">The type of <paramref name="vector" /> (<typeparamref name="T" />) is not supported.</exception>
1409         [Intrinsic]
1410         [CLSCompliant(false)]
1411         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1412         public static uint ExtractMostSignificantBits<T>(this Vector256<T> vector)
1413         {
1414             uint result = vector._lower.ExtractMostSignificantBits();
1415             result |= vector._upper.ExtractMostSignificantBits() << Vector128<T>.Count;
1416             return result;
1417         }
1418
1419         /// <summary>Computes the floor of each element in a vector.</summary>
1420         /// <param name="vector">The vector that will have its floor computed.</param>
1421         /// <returns>A vector whose elements are the floor of the elements in <paramref name="vector" />.</returns>
1422         /// <seealso cref="MathF.Floor(float)" />
1423         [Intrinsic]
1424         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1425         public static Vector256<float> Floor(Vector256<float> vector)
1426         {
1427             return Create(
1428                 Vector128.Floor(vector._lower),
1429                 Vector128.Floor(vector._upper)
1430             );
1431         }
1432
1433         /// <summary>Computes the floor of each element in a vector.</summary>
1434         /// <param name="vector">The vector that will have its floor computed.</param>
1435         /// <returns>A vector whose elements are the floor of the elements in <paramref name="vector" />.</returns>
1436         /// <seealso cref="Math.Floor(double)" />
1437         [Intrinsic]
1438         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1439         public static Vector256<double> Floor(Vector256<double> vector)
1440         {
1441             return Create(
1442                 Vector128.Floor(vector._lower),
1443                 Vector128.Floor(vector._upper)
1444             );
1445         }
1446
1447         /// <summary>Gets the element at the specified index.</summary>
1448         /// <typeparam name="T">The type of the input vector.</typeparam>
1449         /// <param name="vector">The vector to get the element from.</param>
1450         /// <param name="index">The index of the element to get.</param>
1451         /// <returns>The value of the element at <paramref name="index" />.</returns>
1452         /// <exception cref="ArgumentOutOfRangeException"><paramref name="index" /> was less than zero or greater than the number of elements.</exception>
1453         /// <exception cref="NotSupportedException">The type of <paramref name="vector" /> (<typeparamref name="T" />) is not supported.</exception>
1454         [Intrinsic]
1455         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1456         public static T GetElement<T>(this Vector256<T> vector, int index)
1457         {
1458             if ((uint)(index) >= (uint)(Vector256<T>.Count))
1459             {
1460                 ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index);
1461             }
1462
1463             return vector.GetElementUnsafe(index);
1464         }
1465
1466         /// <summary>Gets the value of the lower 128-bits as a new <see cref="Vector128{T}" />.</summary>
1467         /// <typeparam name="T">The type of the input vector.</typeparam>
1468         /// <param name="vector">The vector to get the lower 128-bits from.</param>
1469         /// <returns>The value of the lower 128-bits as a new <see cref="Vector128{T}" />.</returns>
1470         /// <exception cref="NotSupportedException">The type of <paramref name="vector" /> (<typeparamref name="T" />) is not supported.</exception>
1471         [Intrinsic]
1472         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1473         public static Vector128<T> GetLower<T>(this Vector256<T> vector)
1474         {
1475             ThrowHelper.ThrowForUnsupportedIntrinsicsVector256BaseType<T>();
1476             return vector._lower;
1477         }
1478
1479         /// <summary>Gets the value of the upper 128-bits as a new <see cref="Vector128{T}" />.</summary>
1480         /// <typeparam name="T">The type of the input vector.</typeparam>
1481         /// <param name="vector">The vector to get the upper 128-bits from.</param>
1482         /// <returns>The value of the upper 128-bits as a new <see cref="Vector128{T}" />.</returns>
1483         /// <exception cref="NotSupportedException">The type of <paramref name="vector" /> (<typeparamref name="T" />) is not supported.</exception>
1484         [Intrinsic]
1485         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1486         public static Vector128<T> GetUpper<T>(this Vector256<T> vector)
1487         {
1488             ThrowHelper.ThrowForUnsupportedIntrinsicsVector256BaseType<T>();
1489             return vector._upper;
1490         }
1491
1492         /// <summary>Compares two vectors to determine which is greater on a per-element basis.</summary>
1493         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
1494         /// <param name="left">The vector to compare with <paramref name="left" />.</param>
1495         /// <param name="right">The vector to compare with <paramref name="right" />.</param>
1496         /// <returns>A vector whose elements are all-bits-set or zero, depending on if which of the corresponding elements in <paramref name="left" /> and <paramref name="right" /> were greater.</returns>
1497         /// <exception cref="NotSupportedException">The type of <paramref name="left" /> and <paramref name="right" /> (<typeparamref name="T" />) is not supported.</exception>
1498         [Intrinsic]
1499         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1500         public static Vector256<T> GreaterThan<T>(Vector256<T> left, Vector256<T> right)
1501         {
1502             return Create(
1503                 Vector128.GreaterThan(left._lower, right._lower),
1504                 Vector128.GreaterThan(left._upper, right._upper)
1505             );
1506         }
1507
1508         /// <summary>Compares two vectors to determine if all elements are greater.</summary>
1509         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
1510         /// <param name="left">The vector to compare with <paramref name="right" />.</param>
1511         /// <param name="right">The vector to compare with <paramref name="left" />.</param>
1512         /// <returns><c>true</c> if all elements in <paramref name="left" /> were greater than the corresponding element in <paramref name="right" />.</returns>
1513         /// <exception cref="NotSupportedException">The type of <paramref name="left" /> and <paramref name="right" /> (<typeparamref name="T" />) is not supported.</exception>
1514         [Intrinsic]
1515         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1516         public static bool GreaterThanAll<T>(Vector256<T> left, Vector256<T> right)
1517         {
1518             return Vector128.GreaterThanAll(left._lower, right._lower)
1519                 && Vector128.GreaterThanAll(left._upper, right._upper);
1520         }
1521
1522         /// <summary>Compares two vectors to determine if any elements are greater.</summary>
1523         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
1524         /// <param name="left">The vector to compare with <paramref name="right" />.</param>
1525         /// <param name="right">The vector to compare with <paramref name="left" />.</param>
1526         /// <returns><c>true</c> if any elements in <paramref name="left" /> was greater than the corresponding element in <paramref name="right" />.</returns>
1527         /// <exception cref="NotSupportedException">The type of <paramref name="left" /> and <paramref name="right" /> (<typeparamref name="T" />) is not supported.</exception>
1528         [Intrinsic]
1529         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1530         public static bool GreaterThanAny<T>(Vector256<T> left, Vector256<T> right)
1531         {
1532             return Vector128.GreaterThanAny(left._lower, right._lower)
1533                 || Vector128.GreaterThanAny(left._upper, right._upper);
1534         }
1535
1536         /// <summary>Compares two vectors to determine which is greater or equal on a per-element basis.</summary>
1537         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
1538         /// <param name="left">The vector to compare with <paramref name="left" />.</param>
1539         /// <param name="right">The vector to compare with <paramref name="right" />.</param>
1540         /// <returns>A vector whose elements are all-bits-set or zero, depending on if which of the corresponding elements in <paramref name="left" /> and <paramref name="right" /> were greater or equal.</returns>
1541         /// <exception cref="NotSupportedException">The type of <paramref name="left" /> and <paramref name="right" /> (<typeparamref name="T" />) is not supported.</exception>
1542         [Intrinsic]
1543         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1544         public static Vector256<T> GreaterThanOrEqual<T>(Vector256<T> left, Vector256<T> right)
1545         {
1546             return Create(
1547                 Vector128.GreaterThanOrEqual(left._lower, right._lower),
1548                 Vector128.GreaterThanOrEqual(left._upper, right._upper)
1549             );
1550         }
1551
1552         /// <summary>Compares two vectors to determine if all elements are greater or equal.</summary>
1553         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
1554         /// <param name="left">The vector to compare with <paramref name="right" />.</param>
1555         /// <param name="right">The vector to compare with <paramref name="left" />.</param>
1556         /// <returns><c>true</c> if all elements in <paramref name="left" /> were greater than or equal to the corresponding element in <paramref name="right" />.</returns>
1557         /// <exception cref="NotSupportedException">The type of <paramref name="left" /> and <paramref name="right" /> (<typeparamref name="T" />) is not supported.</exception>
1558         [Intrinsic]
1559         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1560         public static bool GreaterThanOrEqualAll<T>(Vector256<T> left, Vector256<T> right)
1561         {
1562             return Vector128.GreaterThanOrEqualAll(left._lower, right._lower)
1563                 && Vector128.GreaterThanOrEqualAll(left._upper, right._upper);
1564         }
1565
1566         /// <summary>Compares two vectors to determine if any elements are greater or equal.</summary>
1567         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
1568         /// <param name="left">The vector to compare with <paramref name="right" />.</param>
1569         /// <param name="right">The vector to compare with <paramref name="left" />.</param>
1570         /// <returns><c>true</c> if any elements in <paramref name="left" /> was greater than or equal to the corresponding element in <paramref name="right" />.</returns>
1571         /// <exception cref="NotSupportedException">The type of <paramref name="left" /> and <paramref name="right" /> (<typeparamref name="T" />) is not supported.</exception>
1572         [Intrinsic]
1573         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1574         public static bool GreaterThanOrEqualAny<T>(Vector256<T> left, Vector256<T> right)
1575         {
1576             return Vector128.GreaterThanOrEqualAny(left._lower, right._lower)
1577                 || Vector128.GreaterThanOrEqualAny(left._upper, right._upper);
1578         }
1579
1580         /// <summary>Compares two vectors to determine which is less on a per-element basis.</summary>
1581         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
1582         /// <param name="left">The vector to compare with <paramref name="left" />.</param>
1583         /// <param name="right">The vector to compare with <paramref name="right" />.</param>
1584         /// <returns>A vector whose elements are all-bits-set or zero, depending on if which of the corresponding elements in <paramref name="left" /> and <paramref name="right" /> were less.</returns>
1585         /// <exception cref="NotSupportedException">The type of <paramref name="left" /> and <paramref name="right" /> (<typeparamref name="T" />) is not supported.</exception>
1586         [Intrinsic]
1587         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1588         public static Vector256<T> LessThan<T>(Vector256<T> left, Vector256<T> right)
1589         {
1590             return Create(
1591                 Vector128.LessThan(left._lower, right._lower),
1592                 Vector128.LessThan(left._upper, right._upper)
1593             );
1594         }
1595
1596         /// <summary>Compares two vectors to determine if all elements are less.</summary>
1597         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
1598         /// <param name="left">The vector to compare with <paramref name="right" />.</param>
1599         /// <param name="right">The vector to compare with <paramref name="left" />.</param>
1600         /// <returns><c>true</c> if all elements in <paramref name="left" /> were less than the corresponding element in <paramref name="right" />.</returns>
1601         /// <exception cref="NotSupportedException">The type of <paramref name="left" /> and <paramref name="right" /> (<typeparamref name="T" />) is not supported.</exception>
1602         [Intrinsic]
1603         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1604         public static bool LessThanAll<T>(Vector256<T> left, Vector256<T> right)
1605         {
1606             return Vector128.LessThanAll(left._lower, right._lower)
1607                 && Vector128.LessThanAll(left._upper, right._upper);
1608         }
1609
1610         /// <summary>Compares two vectors to determine if any elements are less.</summary>
1611         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
1612         /// <param name="left">The vector to compare with <paramref name="right" />.</param>
1613         /// <param name="right">The vector to compare with <paramref name="left" />.</param>
1614         /// <returns><c>true</c> if any elements in <paramref name="left" /> was less than the corresponding element in <paramref name="right" />.</returns>
1615         /// <exception cref="NotSupportedException">The type of <paramref name="left" /> and <paramref name="right" /> (<typeparamref name="T" />) is not supported.</exception>
1616         [Intrinsic]
1617         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1618         public static bool LessThanAny<T>(Vector256<T> left, Vector256<T> right)
1619         {
1620             return Vector128.LessThanAny(left._lower, right._lower)
1621                 || Vector128.LessThanAny(left._upper, right._upper);
1622         }
1623
1624         /// <summary>Compares two vectors to determine which is less or equal on a per-element basis.</summary>
1625         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
1626         /// <param name="left">The vector to compare with <paramref name="left" />.</param>
1627         /// <param name="right">The vector to compare with <paramref name="right" />.</param>
1628         /// <returns>A vector whose elements are all-bits-set or zero, depending on if which of the corresponding elements in <paramref name="left" /> and <paramref name="right" /> were less or equal.</returns>
1629         /// <exception cref="NotSupportedException">The type of <paramref name="left" /> and <paramref name="right" /> (<typeparamref name="T" />) is not supported.</exception>
1630         [Intrinsic]
1631         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1632         public static Vector256<T> LessThanOrEqual<T>(Vector256<T> left, Vector256<T> right)
1633         {
1634             return Create(
1635                 Vector128.LessThanOrEqual(left._lower, right._lower),
1636                 Vector128.LessThanOrEqual(left._upper, right._upper)
1637             );
1638         }
1639
1640         /// <summary>Compares two vectors to determine if all elements are less or equal.</summary>
1641         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
1642         /// <param name="left">The vector to compare with <paramref name="right" />.</param>
1643         /// <param name="right">The vector to compare with <paramref name="left" />.</param>
1644         /// <returns><c>true</c> if all elements in <paramref name="left" /> were less than or equal to the corresponding element in <paramref name="right" />.</returns>
1645         /// <exception cref="NotSupportedException">The type of <paramref name="left" /> and <paramref name="right" /> (<typeparamref name="T" />) is not supported.</exception>
1646         [Intrinsic]
1647         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1648         public static bool LessThanOrEqualAll<T>(Vector256<T> left, Vector256<T> right)
1649         {
1650             return Vector128.LessThanOrEqualAll(left._lower, right._lower)
1651                 && Vector128.LessThanOrEqualAll(left._upper, right._upper);
1652         }
1653
1654         /// <summary>Compares two vectors to determine if any elements are less or equal.</summary>
1655         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
1656         /// <param name="left">The vector to compare with <paramref name="right" />.</param>
1657         /// <param name="right">The vector to compare with <paramref name="left" />.</param>
1658         /// <returns><c>true</c> if any elements in <paramref name="left" /> was less than or equal to the corresponding element in <paramref name="right" />.</returns>
1659         /// <exception cref="NotSupportedException">The type of <paramref name="left" /> and <paramref name="right" /> (<typeparamref name="T" />) is not supported.</exception>
1660         [Intrinsic]
1661         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1662         public static bool LessThanOrEqualAny<T>(Vector256<T> left, Vector256<T> right)
1663         {
1664             return Vector128.LessThanOrEqualAny(left._lower, right._lower)
1665                 || Vector128.LessThanOrEqualAny(left._upper, right._upper);
1666         }
1667
1668 #pragma warning disable CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type ('T')
1669         /// <summary>Loads a vector from the given source.</summary>
1670         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
1671         /// <param name="source">The source from which the vector will be loaded.</param>
1672         /// <returns>The vector loaded from <paramref name="source" />.</returns>
1673         /// <exception cref="NotSupportedException">The type of <paramref name="source" /> (<typeparamref name="T" />) is not supported.</exception>
1674         [Intrinsic]
1675         [CLSCompliant(false)]
1676         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1677         public static Vector256<T> Load<T>(T* source) => LoadUnsafe(ref *source);
1678
1679         /// <summary>Loads a vector from the given aligned source.</summary>
1680         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
1681         /// <param name="source">The aligned source from which the vector will be loaded.</param>
1682         /// <returns>The vector loaded from <paramref name="source" />.</returns>
1683         /// <exception cref="NotSupportedException">The type of <paramref name="source" /> (<typeparamref name="T" />) is not supported.</exception>
1684         [Intrinsic]
1685         [CLSCompliant(false)]
1686         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1687         public static Vector256<T> LoadAligned<T>(T* source)
1688         {
1689             ThrowHelper.ThrowForUnsupportedIntrinsicsVector256BaseType<T>();
1690
1691             if (((nuint)(source) % Alignment) != 0)
1692             {
1693                 ThrowHelper.ThrowAccessViolationException();
1694             }
1695
1696             return *(Vector256<T>*)(source);
1697         }
1698
1699         /// <summary>Loads a vector from the given aligned source.</summary>
1700         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
1701         /// <param name="source">The aligned source from which the vector will be loaded.</param>
1702         /// <returns>The vector loaded from <paramref name="source" />.</returns>
1703         /// <exception cref="NotSupportedException">The type of <paramref name="source" /> (<typeparamref name="T" />) is not supported.</exception>
1704         /// <remarks>This method may bypass the cache on certain platforms.</remarks>
1705         [Intrinsic]
1706         [CLSCompliant(false)]
1707         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1708         public static Vector256<T> LoadAlignedNonTemporal<T>(T* source) => LoadAligned(source);
1709 #pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type ('T')
1710
1711         /// <summary>Loads a vector from the given source.</summary>
1712         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
1713         /// <param name="source">The source from which the vector will be loaded.</param>
1714         /// <returns>The vector loaded from <paramref name="source" />.</returns>
1715         /// <exception cref="NotSupportedException">The type of <paramref name="source" /> (<typeparamref name="T" />) is not supported.</exception>
1716         [Intrinsic]
1717         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1718         public static Vector256<T> LoadUnsafe<T>(ref readonly T source)
1719         {
1720             ThrowHelper.ThrowForUnsupportedIntrinsicsVector256BaseType<T>();
1721             ref readonly byte address = ref Unsafe.As<T, byte>(ref Unsafe.AsRef(in source));
1722             return Unsafe.ReadUnaligned<Vector256<T>>(in address);
1723         }
1724
1725         /// <summary>Loads a vector from the given source and element offset.</summary>
1726         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
1727         /// <param name="source">The source to which <paramref name="elementOffset" /> will be added before loading the vector.</param>
1728         /// <param name="elementOffset">The element offset from <paramref name="source" /> from which the vector will be loaded.</param>
1729         /// <returns>The vector loaded from <paramref name="source" /> plus <paramref name="elementOffset" />.</returns>
1730         /// <exception cref="NotSupportedException">The type of <paramref name="source" /> (<typeparamref name="T" />) is not supported.</exception>
1731         [Intrinsic]
1732         [CLSCompliant(false)]
1733         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1734         public static Vector256<T> LoadUnsafe<T>(ref readonly T source, nuint elementOffset)
1735         {
1736             ThrowHelper.ThrowForUnsupportedIntrinsicsVector256BaseType<T>();
1737             ref readonly byte address = ref Unsafe.As<T, byte>(ref Unsafe.Add(ref Unsafe.AsRef(in source), (nint)elementOffset));
1738             return Unsafe.ReadUnaligned<Vector256<T>>(in address);
1739         }
1740
1741         /// <summary>Loads a vector from the given source and reinterprets it as <see cref="ushort"/>.</summary>
1742         /// <param name="source">The source from which the vector will be loaded.</param>
1743         /// <returns>The vector loaded from <paramref name="source" />.</returns>
1744         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1745         internal static Vector256<ushort> LoadUnsafe(ref char source) =>
1746             LoadUnsafe(ref Unsafe.As<char, ushort>(ref source));
1747
1748         /// <summary>Loads a vector from the given source and element offset and reinterprets it as <see cref="ushort"/>.</summary>
1749         /// <param name="source">The source to which <paramref name="elementOffset" /> will be added before loading the vector.</param>
1750         /// <param name="elementOffset">The element offset from <paramref name="source" /> from which the vector will be loaded.</param>
1751         /// <returns>The vector loaded from <paramref name="source" /> plus <paramref name="elementOffset" />.</returns>
1752         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1753         internal static Vector256<ushort> LoadUnsafe(ref char source, nuint elementOffset) =>
1754             LoadUnsafe(ref Unsafe.As<char, ushort>(ref source), elementOffset);
1755
1756         /// <summary>Computes the maximum of two vectors on a per-element basis.</summary>
1757         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
1758         /// <param name="left">The vector to compare with <paramref name="right" />.</param>
1759         /// <param name="right">The vector to compare with <paramref name="left" />.</param>
1760         /// <returns>A vector whose elements are the maximum of the corresponding elements in <paramref name="left" /> and <paramref name="right" />.</returns>
1761         /// <exception cref="NotSupportedException">The type of <paramref name="left" /> and <paramref name="right" /> (<typeparamref name="T" />) is not supported.</exception>
1762         [Intrinsic]
1763         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1764         public static Vector256<T> Max<T>(Vector256<T> left, Vector256<T> right)
1765         {
1766             return Create(
1767                 Vector128.Max(left._lower, right._lower),
1768                 Vector128.Max(left._upper, right._upper)
1769             );
1770         }
1771
1772         /// <summary>Computes the minimum of two vectors on a per-element basis.</summary>
1773         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
1774         /// <param name="left">The vector to compare with <paramref name="right" />.</param>
1775         /// <param name="right">The vector to compare with <paramref name="left" />.</param>
1776         /// <returns>A vector whose elements are the minimum of the corresponding elements in <paramref name="left" /> and <paramref name="right" />.</returns>
1777         /// <exception cref="NotSupportedException">The type of <paramref name="left" /> and <paramref name="right" /> (<typeparamref name="T" />) is not supported.</exception>
1778         [Intrinsic]
1779         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1780         public static Vector256<T> Min<T>(Vector256<T> left, Vector256<T> right)
1781         {
1782             return Create(
1783                 Vector128.Min(left._lower, right._lower),
1784                 Vector128.Min(left._upper, right._upper)
1785             );
1786         }
1787
1788         /// <summary>Multiplies two vectors to compute their element-wise product.</summary>
1789         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
1790         /// <param name="left">The vector to multiply with <paramref name="right" />.</param>
1791         /// <param name="right">The vector to multiply with <paramref name="left" />.</param>
1792         /// <returns>The element-wise product of <paramref name="left" /> and <paramref name="right" />.</returns>
1793         /// <exception cref="NotSupportedException">The type of <paramref name="left" /> and <paramref name="right" /> (<typeparamref name="T" />) is not supported.</exception>
1794         [Intrinsic]
1795         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1796         public static Vector256<T> Multiply<T>(Vector256<T> left, Vector256<T> right) => left * right;
1797
1798         /// <summary>Multiplies a vector by a scalar to compute their product.</summary>
1799         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
1800         /// <param name="left">The vector to multiply with <paramref name="right" />.</param>
1801         /// <param name="right">The scalar to multiply with <paramref name="left" />.</param>
1802         /// <returns>The product of <paramref name="left" /> and <paramref name="right" />.</returns>
1803         /// <exception cref="NotSupportedException">The type of <paramref name="left" /> and <paramref name="right" /> (<typeparamref name="T" />) is not supported.</exception>
1804         [Intrinsic]
1805         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1806         public static Vector256<T> Multiply<T>(Vector256<T> left, T right) => left * right;
1807
1808         /// <summary>Multiplies a vector by a scalar to compute their product.</summary>
1809         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
1810         /// <param name="left">The scalar to multiply with <paramref name="right" />.</param>
1811         /// <param name="right">The vector to multiply with <paramref name="left" />.</param>
1812         /// <returns>The product of <paramref name="left" /> and <paramref name="right" />.</returns>
1813         /// <exception cref="NotSupportedException">The type of <paramref name="left" /> and <paramref name="right" /> (<typeparamref name="T" />) is not supported.</exception>
1814         [Intrinsic]
1815         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1816         public static Vector256<T> Multiply<T>(T left, Vector256<T> right) => left * right;
1817
1818         /// <summary>Narrows two <see cref="Vector256{Double}"/> instances into one <see cref="Vector256{Single}" />.</summary>
1819         /// <param name="lower">The vector that will be narrowed to the lower half of the result vector.</param>
1820         /// <param name="upper">The vector that will be narrowed to the upper half of the result vector.</param>
1821         /// <returns>A <see cref="Vector256{Single}"/> containing elements narrowed from <paramref name="lower" /> and <paramref name="upper" />.</returns>
1822         [Intrinsic]
1823         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1824         public static Vector256<float> Narrow(Vector256<double> lower, Vector256<double> upper)
1825         {
1826             return Create(
1827                 Vector128.Narrow(lower._lower, lower._upper),
1828                 Vector128.Narrow(upper._lower, upper._upper)
1829             );
1830         }
1831
1832         /// <summary>Narrows two <see cref="Vector256{Int16}"/> instances into one <see cref="Vector256{SByte}" />.</summary>
1833         /// <param name="lower">The vector that will be narrowed to the lower half of the result vector.</param>
1834         /// <param name="upper">The vector that will be narrowed to the upper half of the result vector.</param>
1835         /// <returns>A <see cref="Vector256{SByte}"/> containing elements narrowed from <paramref name="lower" /> and <paramref name="upper" />.</returns>
1836         [Intrinsic]
1837         [CLSCompliant(false)]
1838         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1839         public static Vector256<sbyte> Narrow(Vector256<short> lower, Vector256<short> upper)
1840         {
1841             return Create(
1842                 Vector128.Narrow(lower._lower, lower._upper),
1843                 Vector128.Narrow(upper._lower, upper._upper)
1844             );
1845         }
1846
1847         /// <summary>Narrows two <see cref="Vector256{Int32}"/> instances into one <see cref="Vector256{Int16}" />.</summary>
1848         /// <param name="lower">The vector that will be narrowed to the lower half of the result vector.</param>
1849         /// <param name="upper">The vector that will be narrowed to the upper half of the result vector.</param>
1850         /// <returns>A <see cref="Vector256{Int16}"/> containing elements narrowed from <paramref name="lower" /> and <paramref name="upper" />.</returns>
1851         [Intrinsic]
1852         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1853         public static Vector256<short> Narrow(Vector256<int> lower, Vector256<int> upper)
1854         {
1855             return Create(
1856                 Vector128.Narrow(lower._lower, lower._upper),
1857                 Vector128.Narrow(upper._lower, upper._upper)
1858             );
1859         }
1860
1861         /// <summary>Narrows two <see cref="Vector256{Int64}"/> instances into one <see cref="Vector256{Int32}" />.</summary>
1862         /// <param name="lower">The vector that will be narrowed to the lower half of the result vector.</param>
1863         /// <param name="upper">The vector that will be narrowed to the upper half of the result vector.</param>
1864         /// <returns>A <see cref="Vector256{Int32}"/> containing elements narrowed from <paramref name="lower" /> and <paramref name="upper" />.</returns>
1865         [Intrinsic]
1866         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1867         public static Vector256<int> Narrow(Vector256<long> lower, Vector256<long> upper)
1868         {
1869             return Create(
1870                 Vector128.Narrow(lower._lower, lower._upper),
1871                 Vector128.Narrow(upper._lower, upper._upper)
1872             );
1873         }
1874
1875         /// <summary>Narrows two <see cref="Vector256{UInt16}"/> instances into one <see cref="Vector256{Byte}" />.</summary>
1876         /// <param name="lower">The vector that will be narrowed to the lower half of the result vector.</param>
1877         /// <param name="upper">The vector that will be narrowed to the upper half of the result vector.</param>
1878         /// <returns>A <see cref="Vector256{Byte}"/> containing elements narrowed from <paramref name="lower" /> and <paramref name="upper" />.</returns>
1879         [Intrinsic]
1880         [CLSCompliant(false)]
1881         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1882         public static Vector256<byte> Narrow(Vector256<ushort> lower, Vector256<ushort> upper)
1883         {
1884             return Create(
1885                 Vector128.Narrow(lower._lower, lower._upper),
1886                 Vector128.Narrow(upper._lower, upper._upper)
1887             );
1888         }
1889
1890         /// <summary>Narrows two <see cref="Vector256{UInt32}"/> instances into one <see cref="Vector256{UInt16}" />.</summary>
1891         /// <param name="lower">The vector that will be narrowed to the lower half of the result vector.</param>
1892         /// <param name="upper">The vector that will be narrowed to the upper half of the result vector.</param>
1893         /// <returns>A <see cref="Vector256{UInt16}"/> containing elements narrowed from <paramref name="lower" /> and <paramref name="upper" />.</returns>
1894         [Intrinsic]
1895         [CLSCompliant(false)]
1896         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1897         public static Vector256<ushort> Narrow(Vector256<uint> lower, Vector256<uint> upper)
1898         {
1899             return Create(
1900                 Vector128.Narrow(lower._lower, lower._upper),
1901                 Vector128.Narrow(upper._lower, upper._upper)
1902             );
1903         }
1904
1905         /// <summary>Narrows two <see cref="Vector256{UInt64}"/> instances into one <see cref="Vector256{UInt32}" />.</summary>
1906         /// <param name="lower">The vector that will be narrowed to the lower half of the result vector.</param>
1907         /// <param name="upper">The vector that will be narrowed to the upper half of the result vector.</param>
1908         /// <returns>A <see cref="Vector256{UInt32}"/> containing elements narrowed from <paramref name="lower" /> and <paramref name="upper" />.</returns>
1909         [Intrinsic]
1910         [CLSCompliant(false)]
1911         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1912         public static Vector256<uint> Narrow(Vector256<ulong> lower, Vector256<ulong> upper)
1913         {
1914             return Create(
1915                 Vector128.Narrow(lower._lower, lower._upper),
1916                 Vector128.Narrow(upper._lower, upper._upper)
1917             );
1918         }
1919
1920         /// <summary>Negates a vector.</summary>
1921         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
1922         /// <param name="vector">The vector to negate.</param>
1923         /// <returns>A vector whose elements are the negation of the corresponding elements in <paramref name="vector" />.</returns>
1924         /// <exception cref="NotSupportedException">The type of <paramref name="vector" /> (<typeparamref name="T" />) is not supported.</exception>
1925         [Intrinsic]
1926         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1927         public static Vector256<T> Negate<T>(Vector256<T> vector) => -vector;
1928
1929         /// <summary>Computes the ones-complement of a vector.</summary>
1930         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
1931         /// <param name="vector">The vector whose ones-complement is to be computed.</param>
1932         /// <returns>A vector whose elements are the ones-complement of the corresponding elements in <paramref name="vector" />.</returns>
1933         /// <exception cref="NotSupportedException">The type of <paramref name="vector" /> (<typeparamref name="T" />) is not supported.</exception>
1934         [Intrinsic]
1935         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1936         public static Vector256<T> OnesComplement<T>(Vector256<T> vector)
1937         {
1938             return Create(
1939                 Vector128.OnesComplement(vector._lower),
1940                 Vector128.OnesComplement(vector._upper)
1941             );
1942         }
1943
1944         /// <summary>Shifts each element of a vector left by the specified amount.</summary>
1945         /// <param name="vector">The vector whose elements are to be shifted.</param>
1946         /// <param name="shiftCount">The number of bits by which to shift each element.</param>
1947         /// <returns>A vector whose elements where shifted left by <paramref name="shiftCount" />.</returns>
1948         [Intrinsic]
1949         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1950         public static Vector256<byte> ShiftLeft(Vector256<byte> vector, int shiftCount)
1951         {
1952             return Create(
1953                 Vector128.ShiftLeft(vector._lower, shiftCount),
1954                 Vector128.ShiftLeft(vector._upper, shiftCount)
1955             );
1956         }
1957
1958         /// <summary>Shifts each element of a vector left by the specified amount.</summary>
1959         /// <param name="vector">The vector whose elements are to be shifted.</param>
1960         /// <param name="shiftCount">The number of bits by which to shift each element.</param>
1961         /// <returns>A vector whose elements where shifted left by <paramref name="shiftCount" />.</returns>
1962         [Intrinsic]
1963         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1964         public static Vector256<short> ShiftLeft(Vector256<short> vector, int shiftCount)
1965         {
1966             return Create(
1967                 Vector128.ShiftLeft(vector._lower, shiftCount),
1968                 Vector128.ShiftLeft(vector._upper, shiftCount)
1969             );
1970         }
1971
1972         /// <summary>Shifts each element of a vector left by the specified amount.</summary>
1973         /// <param name="vector">The vector whose elements are to be shifted.</param>
1974         /// <param name="shiftCount">The number of bits by which to shift each element.</param>
1975         /// <returns>A vector whose elements where shifted left by <paramref name="shiftCount" />.</returns>
1976         [Intrinsic]
1977         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1978         public static Vector256<int> ShiftLeft(Vector256<int> vector, int shiftCount)
1979         {
1980             return Create(
1981                 Vector128.ShiftLeft(vector._lower, shiftCount),
1982                 Vector128.ShiftLeft(vector._upper, shiftCount)
1983             );
1984         }
1985
1986         /// <summary>Shifts each element of a vector left by the specified amount.</summary>
1987         /// <param name="vector">The vector whose elements are to be shifted.</param>
1988         /// <param name="shiftCount">The number of bits by which to shift each element.</param>
1989         /// <returns>A vector whose elements where shifted left by <paramref name="shiftCount" />.</returns>
1990         [Intrinsic]
1991         [MethodImpl(MethodImplOptions.AggressiveInlining)]
1992         public static Vector256<long> ShiftLeft(Vector256<long> vector, int shiftCount)
1993         {
1994             return Create(
1995                 Vector128.ShiftLeft(vector._lower, shiftCount),
1996                 Vector128.ShiftLeft(vector._upper, shiftCount)
1997             );
1998         }
1999
2000         /// <summary>Shifts each element of a vector left by the specified amount.</summary>
2001         /// <param name="vector">The vector whose elements are to be shifted.</param>
2002         /// <param name="shiftCount">The number of bits by which to shift each element.</param>
2003         /// <returns>A vector whose elements where shifted left by <paramref name="shiftCount" />.</returns>
2004         [Intrinsic]
2005         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2006         public static Vector256<nint> ShiftLeft(Vector256<nint> vector, int shiftCount)
2007         {
2008             return Create(
2009                 Vector128.ShiftLeft(vector._lower, shiftCount),
2010                 Vector128.ShiftLeft(vector._upper, shiftCount)
2011             );
2012         }
2013
2014         /// <summary>Shifts each element of a vector left by the specified amount.</summary>
2015         /// <param name="vector">The vector whose elements are to be shifted.</param>
2016         /// <param name="shiftCount">The number of bits by which to shift each element.</param>
2017         /// <returns>A vector whose elements where shifted left by <paramref name="shiftCount" />.</returns>
2018         [Intrinsic]
2019         [CLSCompliant(false)]
2020         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2021         public static Vector256<nuint> ShiftLeft(Vector256<nuint> vector, int shiftCount)
2022         {
2023             return Create(
2024                 Vector128.ShiftLeft(vector._lower, shiftCount),
2025                 Vector128.ShiftLeft(vector._upper, shiftCount)
2026             );
2027         }
2028
2029         /// <summary>Shifts each element of a vector left by the specified amount.</summary>
2030         /// <param name="vector">The vector whose elements are to be shifted.</param>
2031         /// <param name="shiftCount">The number of bits by which to shift each element.</param>
2032         /// <returns>A vector whose elements where shifted left by <paramref name="shiftCount" />.</returns>
2033         [Intrinsic]
2034         [CLSCompliant(false)]
2035         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2036         public static Vector256<sbyte> ShiftLeft(Vector256<sbyte> vector, int shiftCount)
2037         {
2038             return Create(
2039                 Vector128.ShiftLeft(vector._lower, shiftCount),
2040                 Vector128.ShiftLeft(vector._upper, shiftCount)
2041             );
2042         }
2043
2044         /// <summary>Shifts each element of a vector left by the specified amount.</summary>
2045         /// <param name="vector">The vector whose elements are to be shifted.</param>
2046         /// <param name="shiftCount">The number of bits by which to shift each element.</param>
2047         /// <returns>A vector whose elements where shifted left by <paramref name="shiftCount" />.</returns>
2048         [Intrinsic]
2049         [CLSCompliant(false)]
2050         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2051         public static Vector256<ushort> ShiftLeft(Vector256<ushort> vector, int shiftCount)
2052         {
2053             return Create(
2054                 Vector128.ShiftLeft(vector._lower, shiftCount),
2055                 Vector128.ShiftLeft(vector._upper, shiftCount)
2056             );
2057         }
2058
2059         /// <summary>Shifts each element of a vector left by the specified amount.</summary>
2060         /// <param name="vector">The vector whose elements are to be shifted.</param>
2061         /// <param name="shiftCount">The number of bits by which to shift each element.</param>
2062         /// <returns>A vector whose elements where shifted left by <paramref name="shiftCount" />.</returns>
2063         [Intrinsic]
2064         [CLSCompliant(false)]
2065         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2066         public static Vector256<uint> ShiftLeft(Vector256<uint> vector, int shiftCount)
2067         {
2068             return Create(
2069                 Vector128.ShiftLeft(vector._lower, shiftCount),
2070                 Vector128.ShiftLeft(vector._upper, shiftCount)
2071             );
2072         }
2073
2074         /// <summary>Shifts each element of a vector left by the specified amount.</summary>
2075         /// <param name="vector">The vector whose elements are to be shifted.</param>
2076         /// <param name="shiftCount">The number of bits by which to shift each element.</param>
2077         /// <returns>A vector whose elements where shifted left by <paramref name="shiftCount" />.</returns>
2078         [Intrinsic]
2079         [CLSCompliant(false)]
2080         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2081         public static Vector256<ulong> ShiftLeft(Vector256<ulong> vector, int shiftCount)
2082         {
2083             return Create(
2084                 Vector128.ShiftLeft(vector._lower, shiftCount),
2085                 Vector128.ShiftLeft(vector._upper, shiftCount)
2086             );
2087         }
2088
2089         /// <summary>Shifts (signed) each element of a vector right by the specified amount.</summary>
2090         /// <param name="vector">The vector whose elements are to be shifted.</param>
2091         /// <param name="shiftCount">The number of bits by which to shift each element.</param>
2092         /// <returns>A vector whose elements where shifted right by <paramref name="shiftCount" />.</returns>
2093         [Intrinsic]
2094         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2095         public static Vector256<short> ShiftRightArithmetic(Vector256<short> vector, int shiftCount)
2096         {
2097             return Create(
2098                 Vector128.ShiftRightArithmetic(vector._lower, shiftCount),
2099                 Vector128.ShiftRightArithmetic(vector._upper, shiftCount)
2100             );
2101         }
2102
2103         /// <summary>Shifts (signed) each element of a vector right by the specified amount.</summary>
2104         /// <param name="vector">The vector whose elements are to be shifted.</param>
2105         /// <param name="shiftCount">The number of bits by which to shift each element.</param>
2106         /// <returns>A vector whose elements where shifted right by <paramref name="shiftCount" />.</returns>
2107         [Intrinsic]
2108         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2109         public static Vector256<int> ShiftRightArithmetic(Vector256<int> vector, int shiftCount)
2110         {
2111             return Create(
2112                 Vector128.ShiftRightArithmetic(vector._lower, shiftCount),
2113                 Vector128.ShiftRightArithmetic(vector._upper, shiftCount)
2114             );
2115         }
2116
2117         /// <summary>Shifts (signed) each element of a vector right by the specified amount.</summary>
2118         /// <param name="vector">The vector whose elements are to be shifted.</param>
2119         /// <param name="shiftCount">The number of bits by which to shift each element.</param>
2120         /// <returns>A vector whose elements where shifted right by <paramref name="shiftCount" />.</returns>
2121         [Intrinsic]
2122         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2123         public static Vector256<long> ShiftRightArithmetic(Vector256<long> vector, int shiftCount)
2124         {
2125             return Create(
2126                 Vector128.ShiftRightArithmetic(vector._lower, shiftCount),
2127                 Vector128.ShiftRightArithmetic(vector._upper, shiftCount)
2128             );
2129         }
2130
2131         /// <summary>Shifts (signed) each element of a vector right by the specified amount.</summary>
2132         /// <param name="vector">The vector whose elements are to be shifted.</param>
2133         /// <param name="shiftCount">The number of bits by which to shift each element.</param>
2134         /// <returns>A vector whose elements where shifted right by <paramref name="shiftCount" />.</returns>
2135         [Intrinsic]
2136         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2137         public static Vector256<nint> ShiftRightArithmetic(Vector256<nint> vector, int shiftCount)
2138         {
2139             return Create(
2140                 Vector128.ShiftRightArithmetic(vector._lower, shiftCount),
2141                 Vector128.ShiftRightArithmetic(vector._upper, shiftCount)
2142             );
2143         }
2144
2145         /// <summary>Shifts (signed) each element of a vector right by the specified amount.</summary>
2146         /// <param name="vector">The vector whose elements are to be shifted.</param>
2147         /// <param name="shiftCount">The number of bits by which to shift each element.</param>
2148         /// <returns>A vector whose elements where shifted right by <paramref name="shiftCount" />.</returns>
2149         [Intrinsic]
2150         [CLSCompliant(false)]
2151         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2152         public static Vector256<sbyte> ShiftRightArithmetic(Vector256<sbyte> vector, int shiftCount)
2153         {
2154             return Create(
2155                 Vector128.ShiftRightArithmetic(vector._lower, shiftCount),
2156                 Vector128.ShiftRightArithmetic(vector._upper, shiftCount)
2157             );
2158         }
2159
2160         /// <summary>Shifts (unsigned) each element of a vector right by the specified amount.</summary>
2161         /// <param name="vector">The vector whose elements are to be shifted.</param>
2162         /// <param name="shiftCount">The number of bits by which to shift each element.</param>
2163         /// <returns>A vector whose elements where shifted right by <paramref name="shiftCount" />.</returns>
2164         [Intrinsic]
2165         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2166         public static Vector256<byte> ShiftRightLogical(Vector256<byte> vector, int shiftCount)
2167         {
2168             return Create(
2169                 Vector128.ShiftRightLogical(vector._lower, shiftCount),
2170                 Vector128.ShiftRightLogical(vector._upper, shiftCount)
2171             );
2172         }
2173
2174         /// <summary>Shifts (unsigned) each element of a vector right by the specified amount.</summary>
2175         /// <param name="vector">The vector whose elements are to be shifted.</param>
2176         /// <param name="shiftCount">The number of bits by which to shift each element.</param>
2177         /// <returns>A vector whose elements where shifted right by <paramref name="shiftCount" />.</returns>
2178         [Intrinsic]
2179         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2180         public static Vector256<short> ShiftRightLogical(Vector256<short> vector, int shiftCount)
2181         {
2182             return Create(
2183                 Vector128.ShiftRightLogical(vector._lower, shiftCount),
2184                 Vector128.ShiftRightLogical(vector._upper, shiftCount)
2185             );
2186         }
2187
2188         /// <summary>Shifts (unsigned) each element of a vector right by the specified amount.</summary>
2189         /// <param name="vector">The vector whose elements are to be shifted.</param>
2190         /// <param name="shiftCount">The number of bits by which to shift each element.</param>
2191         /// <returns>A vector whose elements where shifted right by <paramref name="shiftCount" />.</returns>
2192         [Intrinsic]
2193         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2194         public static Vector256<int> ShiftRightLogical(Vector256<int> vector, int shiftCount)
2195         {
2196             return Create(
2197                 Vector128.ShiftRightLogical(vector._lower, shiftCount),
2198                 Vector128.ShiftRightLogical(vector._upper, shiftCount)
2199             );
2200         }
2201
2202         /// <summary>Shifts (unsigned) each element of a vector right by the specified amount.</summary>
2203         /// <param name="vector">The vector whose elements are to be shifted.</param>
2204         /// <param name="shiftCount">The number of bits by which to shift each element.</param>
2205         /// <returns>A vector whose elements where shifted right by <paramref name="shiftCount" />.</returns>
2206         [Intrinsic]
2207         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2208         public static Vector256<long> ShiftRightLogical(Vector256<long> vector, int shiftCount)
2209         {
2210             return Create(
2211                 Vector128.ShiftRightLogical(vector._lower, shiftCount),
2212                 Vector128.ShiftRightLogical(vector._upper, shiftCount)
2213             );
2214         }
2215
2216         /// <summary>Shifts (unsigned) each element of a vector right by the specified amount.</summary>
2217         /// <param name="vector">The vector whose elements are to be shifted.</param>
2218         /// <param name="shiftCount">The number of bits by which to shift each element.</param>
2219         /// <returns>A vector whose elements where shifted right by <paramref name="shiftCount" />.</returns>
2220         [Intrinsic]
2221         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2222         public static Vector256<nint> ShiftRightLogical(Vector256<nint> vector, int shiftCount)
2223         {
2224             return Create(
2225                 Vector128.ShiftRightLogical(vector._lower, shiftCount),
2226                 Vector128.ShiftRightLogical(vector._upper, shiftCount)
2227             );
2228         }
2229
2230         /// <summary>Shifts (unsigned) each element of a vector right by the specified amount.</summary>
2231         /// <param name="vector">The vector whose elements are to be shifted.</param>
2232         /// <param name="shiftCount">The number of bits by which to shift each element.</param>
2233         /// <returns>A vector whose elements where shifted right by <paramref name="shiftCount" />.</returns>
2234         [Intrinsic]
2235         [CLSCompliant(false)]
2236         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2237         public static Vector256<nuint> ShiftRightLogical(Vector256<nuint> vector, int shiftCount)
2238         {
2239             return Create(
2240                 Vector128.ShiftRightLogical(vector._lower, shiftCount),
2241                 Vector128.ShiftRightLogical(vector._upper, shiftCount)
2242             );
2243         }
2244
2245         /// <summary>Shifts (unsigned) each element of a vector right by the specified amount.</summary>
2246         /// <param name="vector">The vector whose elements are to be shifted.</param>
2247         /// <param name="shiftCount">The number of bits by which to shift each element.</param>
2248         /// <returns>A vector whose elements where shifted right by <paramref name="shiftCount" />.</returns>
2249         [Intrinsic]
2250         [CLSCompliant(false)]
2251         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2252         public static Vector256<sbyte> ShiftRightLogical(Vector256<sbyte> vector, int shiftCount)
2253         {
2254             return Create(
2255                 Vector128.ShiftRightLogical(vector._lower, shiftCount),
2256                 Vector128.ShiftRightLogical(vector._upper, shiftCount)
2257             );
2258         }
2259
2260         /// <summary>Shifts (unsigned) each element of a vector right by the specified amount.</summary>
2261         /// <param name="vector">The vector whose elements are to be shifted.</param>
2262         /// <param name="shiftCount">The number of bits by which to shift each element.</param>
2263         /// <returns>A vector whose elements where shifted right by <paramref name="shiftCount" />.</returns>
2264         [Intrinsic]
2265         [CLSCompliant(false)]
2266         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2267         public static Vector256<ushort> ShiftRightLogical(Vector256<ushort> vector, int shiftCount)
2268         {
2269             return Create(
2270                 Vector128.ShiftRightLogical(vector._lower, shiftCount),
2271                 Vector128.ShiftRightLogical(vector._upper, shiftCount)
2272             );
2273         }
2274
2275         /// <summary>Shifts (unsigned) each element of a vector right by the specified amount.</summary>
2276         /// <param name="vector">The vector whose elements are to be shifted.</param>
2277         /// <param name="shiftCount">The number of bits by which to shift each element.</param>
2278         /// <returns>A vector whose elements where shifted right by <paramref name="shiftCount" />.</returns>
2279         [Intrinsic]
2280         [CLSCompliant(false)]
2281         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2282         public static Vector256<uint> ShiftRightLogical(Vector256<uint> vector, int shiftCount)
2283         {
2284             return Create(
2285                 Vector128.ShiftRightLogical(vector._lower, shiftCount),
2286                 Vector128.ShiftRightLogical(vector._upper, shiftCount)
2287             );
2288         }
2289
2290         /// <summary>Shifts (unsigned) each element of a vector right by the specified amount.</summary>
2291         /// <param name="vector">The vector whose elements are to be shifted.</param>
2292         /// <param name="shiftCount">The number of bits by which to shift each element.</param>
2293         /// <returns>A vector whose elements where shifted right by <paramref name="shiftCount" />.</returns>
2294         [Intrinsic]
2295         [CLSCompliant(false)]
2296         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2297         public static Vector256<ulong> ShiftRightLogical(Vector256<ulong> vector, int shiftCount)
2298         {
2299             return Create(
2300                 Vector128.ShiftRightLogical(vector._lower, shiftCount),
2301                 Vector128.ShiftRightLogical(vector._upper, shiftCount)
2302             );
2303         }
2304
2305         /// <summary>Creates a new vector by selecting values from an input vector using a set of indices.</summary>
2306         /// <param name="vector">The input vector from which values are selected.</param>
2307         /// <param name="indices">The per-element indices used to select a value from <paramref name="vector" />.</param>
2308         /// <returns>A new vector containing the values from <paramref name="vector" /> selected by the given <paramref name="indices" />.</returns>
2309         [Intrinsic]
2310         public static Vector256<byte> Shuffle(Vector256<byte> vector, Vector256<byte> indices)
2311         {
2312             Unsafe.SkipInit(out Vector256<byte> result);
2313
2314             for (int index = 0; index < Vector256<byte>.Count; index++)
2315             {
2316                 byte selectedIndex = indices.GetElementUnsafe(index);
2317                 byte selectedValue = 0;
2318
2319                 if (selectedIndex < Vector256<byte>.Count)
2320                 {
2321                     selectedValue = vector.GetElementUnsafe(selectedIndex);
2322                 }
2323                 result.SetElementUnsafe(index, selectedValue);
2324             }
2325
2326             return result;
2327         }
2328
2329         /// <summary>Creates a new vector by selecting values from an input vector using a set of indices.</summary>
2330         /// <param name="vector">The input vector from which values are selected.</param>
2331         /// <param name="indices">The per-element indices used to select a value from <paramref name="vector" />.</param>
2332         /// <returns>A new vector containing the values from <paramref name="vector" /> selected by the given <paramref name="indices" />.</returns>
2333         [Intrinsic]
2334         [CLSCompliant(false)]
2335         public static Vector256<sbyte> Shuffle(Vector256<sbyte> vector, Vector256<sbyte> indices)
2336         {
2337             Unsafe.SkipInit(out Vector256<sbyte> result);
2338
2339             for (int index = 0; index < Vector256<sbyte>.Count; index++)
2340             {
2341                 byte selectedIndex = (byte)indices.GetElementUnsafe(index);
2342                 sbyte selectedValue = 0;
2343
2344                 if (selectedIndex < Vector256<sbyte>.Count)
2345                 {
2346                     selectedValue = vector.GetElementUnsafe(selectedIndex);
2347                 }
2348                 result.SetElementUnsafe(index, selectedValue);
2349             }
2350
2351             return result;
2352         }
2353
2354         /// <summary>Creates a new vector by selecting values from an input vector using a set of indices.</summary>
2355         /// <param name="vector">The input vector from which values are selected.</param>
2356         /// <param name="indices">The per-element indices used to select a value from <paramref name="vector" />.</param>
2357         /// <returns>A new vector containing the values from <paramref name="vector" /> selected by the given <paramref name="indices" />.</returns>
2358         [Intrinsic]
2359         public static Vector256<short> Shuffle(Vector256<short> vector, Vector256<short> indices)
2360         {
2361             Unsafe.SkipInit(out Vector256<short> result);
2362
2363             for (int index = 0; index < Vector256<short>.Count; index++)
2364             {
2365                 ushort selectedIndex = (ushort)indices.GetElementUnsafe(index);
2366                 short selectedValue = 0;
2367
2368                 if (selectedIndex < Vector256<short>.Count)
2369                 {
2370                     selectedValue = vector.GetElementUnsafe(selectedIndex);
2371                 }
2372                 result.SetElementUnsafe(index, selectedValue);
2373             }
2374
2375             return result;
2376         }
2377
2378         /// <summary>Creates a new vector by selecting values from an input vector using a set of indices.</summary>
2379         /// <param name="vector">The input vector from which values are selected.</param>
2380         /// <param name="indices">The per-element indices used to select a value from <paramref name="vector" />.</param>
2381         /// <returns>A new vector containing the values from <paramref name="vector" /> selected by the given <paramref name="indices" />.</returns>
2382         [Intrinsic]
2383         [CLSCompliant(false)]
2384         public static Vector256<ushort> Shuffle(Vector256<ushort> vector, Vector256<ushort> indices)
2385         {
2386             Unsafe.SkipInit(out Vector256<ushort> result);
2387
2388             for (int index = 0; index < Vector256<ushort>.Count; index++)
2389             {
2390                 ushort selectedIndex = indices.GetElementUnsafe(index);
2391                 ushort selectedValue = 0;
2392
2393                 if (selectedIndex < Vector256<ushort>.Count)
2394                 {
2395                     selectedValue = vector.GetElementUnsafe(selectedIndex);
2396                 }
2397                 result.SetElementUnsafe(index, selectedValue);
2398             }
2399
2400             return result;
2401         }
2402
2403         /// <summary>Creates a new vector by selecting values from an input vector using a set of indices.</summary>
2404         /// <param name="vector">The input vector from which values are selected.</param>
2405         /// <param name="indices">The per-element indices used to select a value from <paramref name="vector" />.</param>
2406         /// <returns>A new vector containing the values from <paramref name="vector" /> selected by the given <paramref name="indices" />.</returns>
2407         [Intrinsic]
2408         public static Vector256<int> Shuffle(Vector256<int> vector, Vector256<int> indices)
2409         {
2410             Unsafe.SkipInit(out Vector256<int> result);
2411
2412             for (int index = 0; index < Vector256<int>.Count; index++)
2413             {
2414                 uint selectedIndex = (uint)indices.GetElementUnsafe(index);
2415                 int selectedValue = 0;
2416
2417                 if (selectedIndex < Vector256<int>.Count)
2418                 {
2419                     selectedValue = vector.GetElementUnsafe((int)selectedIndex);
2420                 }
2421                 result.SetElementUnsafe(index, selectedValue);
2422             }
2423
2424             return result;
2425         }
2426
2427         /// <summary>Creates a new vector by selecting values from an input vector using a set of indices.</summary>
2428         /// <param name="vector">The input vector from which values are selected.</param>
2429         /// <param name="indices">The per-element indices used to select a value from <paramref name="vector" />.</param>
2430         /// <returns>A new vector containing the values from <paramref name="vector" /> selected by the given <paramref name="indices" />.</returns>
2431         [Intrinsic]
2432         [CLSCompliant(false)]
2433         public static Vector256<uint> Shuffle(Vector256<uint> vector, Vector256<uint> indices)
2434         {
2435             Unsafe.SkipInit(out Vector256<uint> result);
2436
2437             for (int index = 0; index < Vector256<uint>.Count; index++)
2438             {
2439                 uint selectedIndex = indices.GetElementUnsafe(index);
2440                 uint selectedValue = 0;
2441
2442                 if (selectedIndex < Vector256<uint>.Count)
2443                 {
2444                     selectedValue = vector.GetElementUnsafe((int)selectedIndex);
2445                 }
2446                 result.SetElementUnsafe(index, selectedValue);
2447             }
2448
2449             return result;
2450         }
2451
2452         /// <summary>Creates a new vector by selecting values from an input vector using a set of indices.</summary>
2453         /// <param name="vector">The input vector from which values are selected.</param>
2454         /// <param name="indices">The per-element indices used to select a value from <paramref name="vector" />.</param>
2455         /// <returns>A new vector containing the values from <paramref name="vector" /> selected by the given <paramref name="indices" />.</returns>
2456         [Intrinsic]
2457         public static Vector256<float> Shuffle(Vector256<float> vector, Vector256<int> indices)
2458         {
2459             Unsafe.SkipInit(out Vector256<float> result);
2460
2461             for (int index = 0; index < Vector256<float>.Count; index++)
2462             {
2463                 uint selectedIndex = (uint)indices.GetElementUnsafe(index);
2464                 float selectedValue = 0;
2465
2466                 if (selectedIndex < Vector256<float>.Count)
2467                 {
2468                     selectedValue = vector.GetElementUnsafe((int)selectedIndex);
2469                 }
2470                 result.SetElementUnsafe(index, selectedValue);
2471             }
2472
2473             return result;
2474         }
2475
2476         /// <summary>Creates a new vector by selecting values from an input vector using a set of indices.</summary>
2477         /// <param name="vector">The input vector from which values are selected.</param>
2478         /// <param name="indices">The per-element indices used to select a value from <paramref name="vector" />.</param>
2479         /// <returns>A new vector containing the values from <paramref name="vector" /> selected by the given <paramref name="indices" />.</returns>
2480         [Intrinsic]
2481         public static Vector256<long> Shuffle(Vector256<long> vector, Vector256<long> indices)
2482         {
2483             Unsafe.SkipInit(out Vector256<long> result);
2484
2485             for (int index = 0; index < Vector256<long>.Count; index++)
2486             {
2487                 ulong selectedIndex = (ulong)indices.GetElementUnsafe(index);
2488                 long selectedValue = 0;
2489
2490                 if (selectedIndex < (uint)Vector256<long>.Count)
2491                 {
2492                     selectedValue = vector.GetElementUnsafe((int)selectedIndex);
2493                 }
2494                 result.SetElementUnsafe(index, selectedValue);
2495             }
2496
2497             return result;
2498         }
2499
2500         /// <summary>Creates a new vector by selecting values from an input vector using a set of indices.</summary>
2501         /// <param name="vector">The input vector from which values are selected.</param>
2502         /// <param name="indices">The per-element indices used to select a value from <paramref name="vector" />.</param>
2503         /// <returns>A new vector containing the values from <paramref name="vector" /> selected by the given <paramref name="indices" />.</returns>
2504         [Intrinsic]
2505         [CLSCompliant(false)]
2506         public static Vector256<ulong> Shuffle(Vector256<ulong> vector, Vector256<ulong> indices)
2507         {
2508             Unsafe.SkipInit(out Vector256<ulong> result);
2509
2510             for (int index = 0; index < Vector256<ulong>.Count; index++)
2511             {
2512                 ulong selectedIndex = indices.GetElementUnsafe(index);
2513                 ulong selectedValue = 0;
2514
2515                 if (selectedIndex < (uint)Vector256<ulong>.Count)
2516                 {
2517                     selectedValue = vector.GetElementUnsafe((int)selectedIndex);
2518                 }
2519                 result.SetElementUnsafe(index, selectedValue);
2520             }
2521
2522             return result;
2523         }
2524
2525         /// <summary>Creates a new vector by selecting values from an input vector using a set of indices.</summary>
2526         /// <param name="vector">The input vector from which values are selected.</param>
2527         /// <param name="indices">The per-element indices used to select a value from <paramref name="vector" />.</param>
2528         /// <returns>A new vector containing the values from <paramref name="vector" /> selected by the given <paramref name="indices" />.</returns>
2529         [Intrinsic]
2530         public static Vector256<double> Shuffle(Vector256<double> vector, Vector256<long> indices)
2531         {
2532             Unsafe.SkipInit(out Vector256<double> result);
2533
2534             for (int index = 0; index < Vector256<double>.Count; index++)
2535             {
2536                 ulong selectedIndex = (ulong)indices.GetElementUnsafe(index);
2537                 double selectedValue = 0;
2538
2539                 if (selectedIndex < (uint)Vector256<double>.Count)
2540                 {
2541                     selectedValue = vector.GetElementUnsafe((int)selectedIndex);
2542                 }
2543                 result.SetElementUnsafe(index, selectedValue);
2544             }
2545
2546             return result;
2547         }
2548
2549         /// <summary>Computes the square root of a vector on a per-element basis.</summary>
2550         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
2551         /// <param name="vector">The vector whose square root is to be computed.</param>
2552         /// <returns>A vector whose elements are the square root of the corresponding elements in <paramref name="vector" />.</returns>
2553         /// <exception cref="NotSupportedException">The type of <paramref name="vector" /> (<typeparamref name="T" />) is not supported.</exception>
2554         [Intrinsic]
2555         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2556         public static Vector256<T> Sqrt<T>(Vector256<T> vector)
2557         {
2558             return Create(
2559                 Vector128.Sqrt(vector._lower),
2560                 Vector128.Sqrt(vector._upper)
2561             );
2562         }
2563
2564 #pragma warning disable CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type ('T')
2565         /// <summary>Stores a vector at the given destination.</summary>
2566         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
2567         /// <param name="source">The vector that will be stored.</param>
2568         /// <param name="destination">The destination at which <paramref name="source" /> will be stored.</param>
2569         /// <exception cref="NotSupportedException">The type of <paramref name="source" /> and <paramref name="destination" /> (<typeparamref name="T" />) is not supported.</exception>
2570         [Intrinsic]
2571         [CLSCompliant(false)]
2572         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2573         public static void Store<T>(this Vector256<T> source, T* destination) => source.StoreUnsafe(ref *destination);
2574
2575         /// <summary>Stores a vector at the given aligned destination.</summary>
2576         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
2577         /// <param name="source">The vector that will be stored.</param>
2578         /// <param name="destination">The aligned destination at which <paramref name="source" /> will be stored.</param>
2579         /// <exception cref="NotSupportedException">The type of <paramref name="source" /> and <paramref name="destination" /> (<typeparamref name="T" />) is not supported.</exception>
2580         [Intrinsic]
2581         [CLSCompliant(false)]
2582         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2583         public static void StoreAligned<T>(this Vector256<T> source, T* destination)
2584         {
2585             ThrowHelper.ThrowForUnsupportedIntrinsicsVector256BaseType<T>();
2586
2587             if (((nuint)(destination) % Alignment) != 0)
2588             {
2589                 ThrowHelper.ThrowAccessViolationException();
2590             }
2591
2592             *(Vector256<T>*)(destination) = source;
2593         }
2594
2595         /// <summary>Stores a vector at the given aligned destination.</summary>
2596         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
2597         /// <param name="source">The vector that will be stored.</param>
2598         /// <param name="destination">The aligned destination at which <paramref name="source" /> will be stored.</param>
2599         /// <exception cref="NotSupportedException">The type of <paramref name="source" /> and <paramref name="destination" /> (<typeparamref name="T" />) is not supported.</exception>
2600         /// <remarks>This method may bypass the cache on certain platforms.</remarks>
2601         [Intrinsic]
2602         [CLSCompliant(false)]
2603         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2604         public static void StoreAlignedNonTemporal<T>(this Vector256<T> source, T* destination) => source.StoreAligned(destination);
2605 #pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type ('T')
2606
2607         /// <summary>Stores a vector at the given destination.</summary>
2608         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
2609         /// <param name="source">The vector that will be stored.</param>
2610         /// <param name="destination">The destination at which <paramref name="source" /> will be stored.</param>
2611         /// <exception cref="NotSupportedException">The type of <paramref name="source" /> and <paramref name="destination" /> (<typeparamref name="T" />) is not supported.</exception>
2612         [Intrinsic]
2613         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2614         public static void StoreUnsafe<T>(this Vector256<T> source, ref T destination)
2615         {
2616             ThrowHelper.ThrowForUnsupportedIntrinsicsVector256BaseType<T>();
2617             ref byte address = ref Unsafe.As<T, byte>(ref destination);
2618             Unsafe.WriteUnaligned(ref address, source);
2619         }
2620
2621         /// <summary>Stores a vector at the given destination.</summary>
2622         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
2623         /// <param name="source">The vector that will be stored.</param>
2624         /// <param name="destination">The destination to which <paramref name="elementOffset" /> will be added before the vector will be stored.</param>
2625         /// <param name="elementOffset">The element offset from <paramref name="destination" /> from which the vector will be stored.</param>
2626         /// <exception cref="NotSupportedException">The type of <paramref name="source" /> and <paramref name="destination" /> (<typeparamref name="T" />) is not supported.</exception>
2627         [Intrinsic]
2628         [CLSCompliant(false)]
2629         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2630         public static void StoreUnsafe<T>(this Vector256<T> source, ref T destination, nuint elementOffset)
2631         {
2632             ThrowHelper.ThrowForUnsupportedIntrinsicsVector256BaseType<T>();
2633             destination = ref Unsafe.Add(ref destination, (nint)elementOffset);
2634             Unsafe.WriteUnaligned(ref Unsafe.As<T, byte>(ref destination), source);
2635         }
2636
2637         /// <summary>Subtracts two vectors to compute their difference.</summary>
2638         /// <param name="left">The vector from which <paramref name="right" /> will be subtracted.</param>
2639         /// <param name="right">The vector to subtract from <paramref name="left" />.</param>
2640         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
2641         /// <returns>The difference of <paramref name="left" /> and <paramref name="right" />.</returns>
2642         /// <exception cref="NotSupportedException">The type of <paramref name="left" /> and <paramref name="right" /> (<typeparamref name="T" />) is not supported.</exception>
2643         [Intrinsic]
2644         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2645         public static Vector256<T> Subtract<T>(Vector256<T> left, Vector256<T> right) => left - right;
2646
2647         /// <summary>Computes the sum of all elements in a vector.</summary>
2648         /// <param name="vector">The vector whose elements will be summed.</param>
2649         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
2650         /// <returns>The sum of all elements in <paramref name="vector" />.</returns>
2651         /// <exception cref="NotSupportedException">The type of <paramref name="vector" /> (<typeparamref name="T" />) is not supported.</exception>
2652         [Intrinsic]
2653         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2654         public static T Sum<T>(Vector256<T> vector)
2655         {
2656             // Doing this as Sum(lower) + Sum(upper) is important for floating-point determinism
2657             // This is because the underlying dpps instruction on x86/x64 will do this equivalently
2658             // and otherwise the software vs accelerated implementations may differ in returned result.
2659
2660             T result = Vector128.Sum(vector._lower);
2661             result = Scalar<T>.Add(result, Vector128.Sum(vector._upper));
2662             return result;
2663         }
2664
2665         /// <summary>Converts the given vector to a scalar containing the value of the first element.</summary>
2666         /// <typeparam name="T">The type of the input vector.</typeparam>
2667         /// <param name="vector">The vector to get the first element from.</param>
2668         /// <returns>A scalar <typeparamref name="T" /> containing the value of the first element.</returns>
2669         /// <exception cref="NotSupportedException">The type of <paramref name="vector" /> (<typeparamref name="T" />) is not supported.</exception>
2670         [Intrinsic]
2671         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2672         public static T ToScalar<T>(this Vector256<T> vector)
2673         {
2674             ThrowHelper.ThrowForUnsupportedIntrinsicsVector256BaseType<T>();
2675             return vector.GetElementUnsafe(0);
2676         }
2677
2678         /// <summary>Converts the given vector to a new <see cref="Vector512{T}" /> with the lower 256-bits set to the value of the given vector and the upper 256-bits initialized to zero.</summary>
2679         /// <typeparam name="T">The type of the input vector.</typeparam>
2680         /// <param name="vector">The vector to extend.</param>
2681         /// <returns>A new <see cref="Vector512{T}" /> with the lower 256-bits set to the value of <paramref name="vector" /> and the upper 256-bits initialized to zero.</returns>
2682         /// <exception cref="NotSupportedException">The type of <paramref name="vector" /> (<typeparamref name="T" />) is not supported.</exception>
2683         [Intrinsic]
2684         public static Vector512<T> ToVector512<T>(this Vector256<T> vector)
2685         {
2686             ThrowHelper.ThrowForUnsupportedIntrinsicsVector256BaseType<T>();
2687
2688             Vector512<T> result = default;
2689             result.SetLowerUnsafe(vector);
2690             return result;
2691         }
2692
2693         /// <summary>Converts the given vector to a new <see cref="Vector512{T}" /> with the lower 256-bits set to the value of the given vector and the upper 256-bits left uninitialized.</summary>
2694         /// <typeparam name="T">The type of the input vector.</typeparam>
2695         /// <param name="vector">The vector to extend.</param>
2696         /// <returns>A new <see cref="Vector512{T}" /> with the lower 256-bits set to the value of <paramref name="vector" /> and the upper 256-bits left uninitialized.</returns>
2697         /// <exception cref="NotSupportedException">The type of <paramref name="vector" /> (<typeparamref name="T" />) is not supported.</exception>
2698         [Intrinsic]
2699         public static unsafe Vector512<T> ToVector512Unsafe<T>(this Vector256<T> vector)
2700         {
2701             ThrowHelper.ThrowForUnsupportedIntrinsicsVector256BaseType<T>();
2702
2703             // This relies on us stripping the "init" flag from the ".locals"
2704             // declaration to let the upper bits be uninitialized.
2705
2706             Unsafe.SkipInit(out Vector512<T> result);
2707             result.SetLowerUnsafe(vector);
2708             return result;
2709         }
2710
2711         /// <summary>Tries to copy a <see cref="Vector{T}" /> to a given span.</summary>
2712         /// <typeparam name="T">The type of the input vector.</typeparam>
2713         /// <param name="vector">The vector to copy.</param>
2714         /// <param name="destination">The span to which <paramref name="destination" /> is copied.</param>
2715         /// <returns><c>true</c> if <paramref name="vector" /> was successfully copied to <paramref name="destination" />; otherwise, <c>false</c> if the length of <paramref name="destination" /> is less than <see cref="Vector256{T}.Count" />.</returns>
2716         /// <exception cref="NotSupportedException">The type of <paramref name="vector" /> and <paramref name="destination" /> (<typeparamref name="T" />) is not supported.</exception>
2717         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2718         public static bool TryCopyTo<T>(this Vector256<T> vector, Span<T> destination)
2719         {
2720             if (destination.Length < Vector256<T>.Count)
2721             {
2722                 return false;
2723             }
2724
2725             Unsafe.WriteUnaligned(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(destination)), vector);
2726             return true;
2727         }
2728
2729         /// <summary>Widens a <see cref="Vector256{Byte}" /> into two <see cref="Vector256{UInt16} " />.</summary>
2730         /// <param name="source">The vector whose elements are to be widened.</param>
2731         /// <returns>A pair of vectors that contain the widened lower and upper halves of <paramref name="source" />.</returns>
2732         [CLSCompliant(false)]
2733         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2734         public static (Vector256<ushort> Lower, Vector256<ushort> Upper) Widen(Vector256<byte> source) => (WidenLower(source), WidenUpper(source));
2735
2736         /// <summary>Widens a <see cref="Vector256{Int16}" /> into two <see cref="Vector256{Int32} " />.</summary>
2737         /// <param name="source">The vector whose elements are to be widened.</param>
2738         /// <returns>A pair of vectors that contain the widened lower and upper halves of <paramref name="source" />.</returns>
2739         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2740         public static (Vector256<int> Lower, Vector256<int> Upper) Widen(Vector256<short> source) => (WidenLower(source), WidenUpper(source));
2741
2742         /// <summary>Widens a <see cref="Vector256{Int32}" /> into two <see cref="Vector256{Int64} " />.</summary>
2743         /// <param name="source">The vector whose elements are to be widened.</param>
2744         /// <returns>A pair of vectors that contain the widened lower and upper halves of <paramref name="source" />.</returns>
2745         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2746         public static (Vector256<long> Lower, Vector256<long> Upper) Widen(Vector256<int> source) => (WidenLower(source), WidenUpper(source));
2747
2748         /// <summary>Widens a <see cref="Vector256{SByte}" /> into two <see cref="Vector256{Int16} " />.</summary>
2749         /// <param name="source">The vector whose elements are to be widened.</param>
2750         /// <returns>A pair of vectors that contain the widened lower and upper halves of <paramref name="source" />.</returns>
2751         [CLSCompliant(false)]
2752         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2753         public static (Vector256<short> Lower, Vector256<short> Upper) Widen(Vector256<sbyte> source) => (WidenLower(source), WidenUpper(source));
2754
2755         /// <summary>Widens a <see cref="Vector256{Single}" /> into two <see cref="Vector256{Double} " />.</summary>
2756         /// <param name="source">The vector whose elements are to be widened.</param>
2757         /// <returns>A pair of vectors that contain the widened lower and upper halves of <paramref name="source" />.</returns>
2758         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2759         public static (Vector256<double> Lower, Vector256<double> Upper) Widen(Vector256<float> source) => (WidenLower(source), WidenUpper(source));
2760
2761         /// <summary>Widens a <see cref="Vector256{UInt16}" /> into two <see cref="Vector256{UInt32} " />.</summary>
2762         /// <param name="source">The vector whose elements are to be widened.</param>
2763         /// <returns>A pair of vectors that contain the widened lower and upper halves of <paramref name="source" />.</returns>
2764         [CLSCompliant(false)]
2765         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2766         public static (Vector256<uint> Lower, Vector256<uint> Upper) Widen(Vector256<ushort> source) => (WidenLower(source), WidenUpper(source));
2767
2768         /// <summary>Widens a <see cref="Vector256{UInt32}" /> into two <see cref="Vector256{UInt64} " />.</summary>
2769         /// <param name="source">The vector whose elements are to be widened.</param>
2770         /// <returns>A pair of vectors that contain the widened lower and upper halves of <paramref name="source" />.</returns>
2771         [CLSCompliant(false)]
2772         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2773         public static (Vector256<ulong> Lower, Vector256<ulong> Upper) Widen(Vector256<uint> source) => (WidenLower(source), WidenUpper(source));
2774
2775         /// <summary>Widens the lower half of a <see cref="Vector256{Byte}" /> into a <see cref="Vector256{UInt16} " />.</summary>
2776         /// <param name="source">The vector whose elements are to be widened.</param>
2777         /// <returns>A vector that contain the widened lower half of <paramref name="source" />.</returns>
2778         [Intrinsic]
2779         [CLSCompliant(false)]
2780         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2781         public static Vector256<ushort> WidenLower(Vector256<byte> source)
2782         {
2783             Vector128<byte> lower = source._lower;
2784
2785             return Create(
2786                 Vector128.WidenLower(lower),
2787                 Vector128.WidenUpper(lower)
2788             );
2789         }
2790
2791         /// <summary>Widens the lower half of a <see cref="Vector256{Int16}" /> into a <see cref="Vector256{Int32} " />.</summary>
2792         /// <param name="source">The vector whose elements are to be widened.</param>
2793         /// <returns>A vector that contain the widened lower half of <paramref name="source" />.</returns>
2794         [Intrinsic]
2795         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2796         public static Vector256<int> WidenLower(Vector256<short> source)
2797         {
2798             Vector128<short> lower = source._lower;
2799
2800             return Create(
2801                 Vector128.WidenLower(lower),
2802                 Vector128.WidenUpper(lower)
2803             );
2804         }
2805
2806         /// <summary>Widens the lower half of a <see cref="Vector256{Int32}" /> into a <see cref="Vector256{Int64} " />.</summary>
2807         /// <param name="source">The vector whose elements are to be widened.</param>
2808         /// <returns>A vector that contain the widened lower half of <paramref name="source" />.</returns>
2809         [Intrinsic]
2810         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2811         public static Vector256<long> WidenLower(Vector256<int> source)
2812         {
2813             Vector128<int> lower = source._lower;
2814
2815             return Create(
2816                 Vector128.WidenLower(lower),
2817                 Vector128.WidenUpper(lower)
2818             );
2819         }
2820
2821         /// <summary>Widens the lower half of a <see cref="Vector256{SByte}" /> into a <see cref="Vector256{Int16} " />.</summary>
2822         /// <param name="source">The vector whose elements are to be widened.</param>
2823         /// <returns>A vector that contain the widened lower half of <paramref name="source" />.</returns>
2824         [Intrinsic]
2825         [CLSCompliant(false)]
2826         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2827         public static Vector256<short> WidenLower(Vector256<sbyte> source)
2828         {
2829             Vector128<sbyte> lower = source._lower;
2830
2831             return Create(
2832                 Vector128.WidenLower(lower),
2833                 Vector128.WidenUpper(lower)
2834             );
2835         }
2836         /// <summary>Widens the lower half of a <see cref="Vector256{Single}" /> into a <see cref="Vector256{Double} " />.</summary>
2837         /// <param name="source">The vector whose elements are to be widened.</param>
2838         /// <returns>A vector that contain the widened lower half of <paramref name="source" />.</returns>
2839         [Intrinsic]
2840         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2841         public static Vector256<double> WidenLower(Vector256<float> source)
2842         {
2843             Vector128<float> lower = source._lower;
2844
2845             return Create(
2846                 Vector128.WidenLower(lower),
2847                 Vector128.WidenUpper(lower)
2848             );
2849         }
2850
2851         /// <summary>Widens the lower half of a <see cref="Vector256{UInt16}" /> into a <see cref="Vector256{UInt32} " />.</summary>
2852         /// <param name="source">The vector whose elements are to be widened.</param>
2853         /// <returns>A vector that contain the widened lower half of <paramref name="source" />.</returns>
2854         [Intrinsic]
2855         [CLSCompliant(false)]
2856         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2857         public static Vector256<uint> WidenLower(Vector256<ushort> source)
2858         {
2859             Vector128<ushort> lower = source._lower;
2860
2861             return Create(
2862                 Vector128.WidenLower(lower),
2863                 Vector128.WidenUpper(lower)
2864             );
2865         }
2866
2867         /// <summary>Widens the lower half of a <see cref="Vector256{UInt32}" /> into a <see cref="Vector256{UInt64} " />.</summary>
2868         /// <param name="source">The vector whose elements are to be widened.</param>
2869         /// <returns>A vector that contain the widened lower half of <paramref name="source" />.</returns>
2870         [Intrinsic]
2871         [CLSCompliant(false)]
2872         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2873         public static Vector256<ulong> WidenLower(Vector256<uint> source)
2874         {
2875             Vector128<uint> lower = source._lower;
2876
2877             return Create(
2878                 Vector128.WidenLower(lower),
2879                 Vector128.WidenUpper(lower)
2880             );
2881         }
2882
2883         /// <summary>Widens the upper half of a <see cref="Vector256{Byte}" /> into a <see cref="Vector256{UInt16} " />.</summary>
2884         /// <param name="source">The vector whose elements are to be widened.</param>
2885         /// <returns>A vector that contain the widened upper half of <paramref name="source" />.</returns>
2886         [Intrinsic]
2887         [CLSCompliant(false)]
2888         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2889         public static Vector256<ushort> WidenUpper(Vector256<byte> source)
2890         {
2891             Vector128<byte> upper = source._upper;
2892
2893             return Create(
2894                 Vector128.WidenLower(upper),
2895                 Vector128.WidenUpper(upper)
2896             );
2897         }
2898
2899         /// <summary>Widens the upper half of a <see cref="Vector256{Int16}" /> into a <see cref="Vector256{Int32} " />.</summary>
2900         /// <param name="source">The vector whose elements are to be widened.</param>
2901         /// <returns>A vector that contain the widened upper half of <paramref name="source" />.</returns>
2902         [Intrinsic]
2903         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2904         public static Vector256<int> WidenUpper(Vector256<short> source)
2905         {
2906             Vector128<short> upper = source._upper;
2907
2908             return Create(
2909                 Vector128.WidenLower(upper),
2910                 Vector128.WidenUpper(upper)
2911             );
2912         }
2913
2914         /// <summary>Widens the upper half of a <see cref="Vector256{Int32}" /> into a <see cref="Vector256{Int64} " />.</summary>
2915         /// <param name="source">The vector whose elements are to be widened.</param>
2916         /// <returns>A vector that contain the widened upper half of <paramref name="source" />.</returns>
2917         [Intrinsic]
2918         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2919         public static Vector256<long> WidenUpper(Vector256<int> source)
2920         {
2921             Vector128<int> upper = source._upper;
2922
2923             return Create(
2924                 Vector128.WidenLower(upper),
2925                 Vector128.WidenUpper(upper)
2926             );
2927         }
2928
2929         /// <summary>Widens the upper half of a <see cref="Vector256{SByte}" /> into a <see cref="Vector256{Int16} " />.</summary>
2930         /// <param name="source">The vector whose elements are to be widened.</param>
2931         /// <returns>A vector that contain the widened upper half of <paramref name="source" />.</returns>
2932         [Intrinsic]
2933         [CLSCompliant(false)]
2934         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2935         public static Vector256<short> WidenUpper(Vector256<sbyte> source)
2936         {
2937             Vector128<sbyte> upper = source._upper;
2938
2939             return Create(
2940                 Vector128.WidenLower(upper),
2941                 Vector128.WidenUpper(upper)
2942             );
2943         }
2944
2945         /// <summary>Widens the upper half of a <see cref="Vector256{Single}" /> into a <see cref="Vector256{Double} " />.</summary>
2946         /// <param name="source">The vector whose elements are to be widened.</param>
2947         /// <returns>A vector that contain the widened upper half of <paramref name="source" />.</returns>
2948         [Intrinsic]
2949         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2950         public static Vector256<double> WidenUpper(Vector256<float> source)
2951         {
2952             Vector128<float> upper = source._upper;
2953
2954             return Create(
2955                 Vector128.WidenLower(upper),
2956                 Vector128.WidenUpper(upper)
2957             );
2958         }
2959
2960         /// <summary>Widens the upper half of a <see cref="Vector256{UInt16}" /> into a <see cref="Vector256{UInt32} " />.</summary>
2961         /// <param name="source">The vector whose elements are to be widened.</param>
2962         /// <returns>A vector that contain the widened upper half of <paramref name="source" />.</returns>
2963         [Intrinsic]
2964         [CLSCompliant(false)]
2965         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2966         public static Vector256<uint> WidenUpper(Vector256<ushort> source)
2967         {
2968             Vector128<ushort> upper = source._upper;
2969
2970             return Create(
2971                 Vector128.WidenLower(upper),
2972                 Vector128.WidenUpper(upper)
2973             );
2974         }
2975
2976         /// <summary>Widens the upper half of a <see cref="Vector256{UInt32}" /> into a <see cref="Vector256{UInt64} " />.</summary>
2977         /// <param name="source">The vector whose elements are to be widened.</param>
2978         /// <returns>A vector that contain the widened upper half of <paramref name="source" />.</returns>
2979         [Intrinsic]
2980         [CLSCompliant(false)]
2981         [MethodImpl(MethodImplOptions.AggressiveInlining)]
2982         public static Vector256<ulong> WidenUpper(Vector256<uint> source)
2983         {
2984             Vector128<uint> upper = source._upper;
2985
2986             return Create(
2987                 Vector128.WidenLower(upper),
2988                 Vector128.WidenUpper(upper)
2989             );
2990         }
2991
2992         /// <summary>Creates a new <see cref="Vector256{T}" /> 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 given vector.</summary>
2993         /// <typeparam name="T">The type of the input vector.</typeparam>
2994         /// <param name="vector">The vector to get the remaining elements from.</param>
2995         /// <param name="index">The index of the element to set.</param>
2996         /// <param name="value">The value to set the element to.</param>
2997         /// <returns>A <see cref="Vector256{T}" /> with the value of the element at <paramref name="index" /> set to <paramref name="value" /> and the remaining elements set to the same value as that in <paramref name="vector" />.</returns>
2998         /// <exception cref="ArgumentOutOfRangeException"><paramref name="index" /> was less than zero or greater than the number of elements.</exception>
2999         /// <exception cref="NotSupportedException">The type of <paramref name="vector" /> (<typeparamref name="T" />) is not supported.</exception>
3000         [Intrinsic]
3001         public static Vector256<T> WithElement<T>(this Vector256<T> vector, int index, T value)
3002         {
3003             if ((uint)(index) >= (uint)(Vector256<T>.Count))
3004             {
3005                 ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index);
3006             }
3007
3008             Vector256<T> result = vector;
3009             result.SetElementUnsafe(index, value);
3010             return result;
3011         }
3012
3013         /// <summary>Creates a new <see cref="Vector256{T}" /> with the lower 128-bits set to the specified value and the upper 128-bits set to the same value as that in the given vector.</summary>
3014         /// <typeparam name="T">The type of the input vector.</typeparam>
3015         /// <param name="vector">The vector to get the upper 128-bits from.</param>
3016         /// <param name="value">The value of the lower 128-bits as a <see cref="Vector128{T}" />.</param>
3017         /// <returns>A new <see cref="Vector256{T}" /> with the lower 128-bits set to <paramref name="value" /> and the upper 128-bits set to the same value as that in <paramref name="vector" />.</returns>
3018         /// <exception cref="NotSupportedException">The type of <paramref name="vector" /> (<typeparamref name="T" />) is not supported.</exception>
3019         [Intrinsic]
3020         [MethodImpl(MethodImplOptions.AggressiveInlining)]
3021         public static Vector256<T> WithLower<T>(this Vector256<T> vector, Vector128<T> value)
3022         {
3023             ThrowHelper.ThrowForUnsupportedIntrinsicsVector256BaseType<T>();
3024
3025             Vector256<T> result = vector;
3026             result.SetLowerUnsafe(value);
3027             return result;
3028         }
3029
3030         /// <summary>Creates a new <see cref="Vector256{T}" /> with the upper 128-bits set to the specified value and the lower 128-bits set to the same value as that in the given vector.</summary>
3031         /// <typeparam name="T">The type of the input vector.</typeparam>
3032         /// <param name="vector">The vector to get the lower 128-bits from.</param>
3033         /// <param name="value">The value of the upper 128-bits as a <see cref="Vector128{T}" />.</param>
3034         /// <returns>A new <see cref="Vector256{T}" /> with the upper 128-bits set to <paramref name="value" /> and the lower 128-bits set to the same value as that in <paramref name="vector" />.</returns>
3035         /// <exception cref="NotSupportedException">The type of <paramref name="vector" /> (<typeparamref name="T" />) is not supported.</exception>
3036         [Intrinsic]
3037         [MethodImpl(MethodImplOptions.AggressiveInlining)]
3038         public static Vector256<T> WithUpper<T>(this Vector256<T> vector, Vector128<T> value)
3039         {
3040             ThrowHelper.ThrowForUnsupportedIntrinsicsVector256BaseType<T>();
3041
3042             Vector256<T> result = vector;
3043             result.SetUpperUnsafe(value);
3044             return result;
3045         }
3046
3047         /// <summary>Computes the exclusive-or of two vectors.</summary>
3048         /// <typeparam name="T">The type of the elements in the vector.</typeparam>
3049         /// <param name="left">The vector to exclusive-or with <paramref name="right" />.</param>
3050         /// <param name="right">The vector to exclusive-or with <paramref name="left" />.</param>
3051         /// <returns>The exclusive-or of <paramref name="left" /> and <paramref name="right" />.</returns>
3052         /// <exception cref="NotSupportedException">The type of <paramref name="left" /> and <paramref name="right" /> (<typeparamref name="T" />) is not supported.</exception>
3053         [Intrinsic]
3054         [MethodImpl(MethodImplOptions.AggressiveInlining)]
3055         public static Vector256<T> Xor<T>(Vector256<T> left, Vector256<T> right) => left ^ right;
3056
3057         [MethodImpl(MethodImplOptions.AggressiveInlining)]
3058         internal static T GetElementUnsafe<T>(in this Vector256<T> vector, int index)
3059         {
3060             Debug.Assert((index >= 0) && (index < Vector256<T>.Count));
3061             ref T address = ref Unsafe.As<Vector256<T>, T>(ref Unsafe.AsRef(in vector));
3062             return Unsafe.Add(ref address, index);
3063         }
3064
3065         [MethodImpl(MethodImplOptions.AggressiveInlining)]
3066         internal static void SetElementUnsafe<T>(in this Vector256<T> vector, int index, T value)
3067         {
3068             Debug.Assert((index >= 0) && (index < Vector256<T>.Count));
3069             ref T address = ref Unsafe.As<Vector256<T>, T>(ref Unsafe.AsRef(in vector));
3070             Unsafe.Add(ref address, index) = value;
3071         }
3072
3073         [MethodImpl(MethodImplOptions.AggressiveInlining)]
3074         internal static void SetLowerUnsafe<T>(in this Vector256<T> vector, Vector128<T> value)
3075         {
3076             Unsafe.AsRef(in vector._lower) = value;
3077         }
3078
3079         [MethodImpl(MethodImplOptions.AggressiveInlining)]
3080         internal static void SetUpperUnsafe<T>(in this Vector256<T> vector, Vector128<T> value)
3081         {
3082             Unsafe.AsRef(in vector._upper) = value;
3083         }
3084     }
3085 }