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