More Corelib cleanup (dotnet/coreclr#26872)
[mono-project.git] / netcore / System.Private.CoreLib / shared / System / Numerics / Vector.cs
blob64315313d6ef0e6ec979e79461e5f7d41b30eebf
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 // See the LICENSE file in the project root for more information.
5 using System.Diagnostics.CodeAnalysis;
6 using System.Globalization;
7 using System.Runtime.CompilerServices;
8 using System.Runtime.InteropServices;
9 using System.Text;
11 using Internal.Runtime.CompilerServices;
13 #pragma warning disable SA1121 // explicitly using type aliases instead of built-in types
14 #if BIT64
15 using nint = System.Int64;
16 #else
17 using nint = System.Int32;
18 #endif
20 namespace System.Numerics
22 /* Note: The following patterns are used throughout the code here and are described here
24 * PATTERN:
25 * if (typeof(T) == typeof(int)) { ... }
26 * else if (typeof(T) == typeof(float)) { ... }
27 * EXPLANATION:
28 * At runtime, each instantiation of Vector<T> will be type-specific, and each of these typeof blocks will be eliminated,
29 * as typeof(T) is a (JIT) compile-time constant for each instantiation. This design was chosen to eliminate any overhead from
30 * delegates and other patterns.
32 * PATTERN:
33 * if (Vector.IsHardwareAccelerated) { ... }
34 * else { ... }
35 * EXPLANATION
36 * This pattern solves two problems:
37 * 1. Allows us to unroll loops when we know the size (when no hardware acceleration is present)
38 * 2. Allows reflection to work:
39 * - If a method is called via reflection, it will not be "intrinsified", which would cause issues if we did
40 * not provide an implementation for that case (i.e. if it only included a case which assumed 16-byte registers)
41 * (NOTE: It is assumed that Vector.IsHardwareAccelerated will be a compile-time constant, eliminating these checks
42 * from the JIT'd code.)
44 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
46 /// <summary>
47 /// A structure that represents a single Vector. The count of this Vector is fixed but CPU register dependent.
48 /// This struct only supports numerical types. This type is intended to be used as a building block for vectorizing
49 /// large algorithms. This type is immutable, individual elements cannot be modified.
50 /// </summary>
51 [Intrinsic]
52 public struct Vector<T> : IEquatable<Vector<T>>, IFormattable where T : struct
54 #region Fields
55 private Register register;
56 #endregion Fields
58 #region Static Members
59 /// <summary>
60 /// Returns the number of elements stored in the vector. This value is hardware dependent.
61 /// </summary>
62 public static int Count
64 [Intrinsic]
65 get
67 ThrowHelper.ThrowForUnsupportedVectorBaseType<T>();
68 return Unsafe.SizeOf<Vector<T>>() / Unsafe.SizeOf<T>();
72 /// <summary>
73 /// Returns a vector containing all zeroes.
74 /// </summary>
75 public static Vector<T> Zero
77 [Intrinsic]
78 get => s_zero;
80 private static readonly Vector<T> s_zero = new Vector<T>();
82 /// <summary>
83 /// Returns a vector containing all ones.
84 /// </summary>
85 public static Vector<T> One
87 [Intrinsic]
88 get => s_one;
90 private static readonly Vector<T> s_one = new Vector<T>(GetOneValue());
92 internal static Vector<T> AllOnes
94 [Intrinsic]
95 get => s_allOnes;
97 private static readonly Vector<T> s_allOnes = new Vector<T>(GetAllBitsSetValue());
98 #endregion Static Members
100 #region Constructors
101 /// <summary>
102 /// Constructs a vector whose components are all <code>value</code>
103 /// </summary>
104 [Intrinsic]
105 public unsafe Vector(T value)
106 : this()
108 if (Vector.IsHardwareAccelerated)
110 if (typeof(T) == typeof(byte))
112 fixed (byte* basePtr = &this.register.byte_0)
114 for (nint g = 0; g < Count; g++)
116 *(basePtr + g) = (byte)(object)value;
120 else if (typeof(T) == typeof(sbyte))
122 fixed (sbyte* basePtr = &this.register.sbyte_0)
124 for (nint g = 0; g < Count; g++)
126 *(basePtr + g) = (sbyte)(object)value;
130 else if (typeof(T) == typeof(ushort))
132 fixed (ushort* basePtr = &this.register.uint16_0)
134 for (nint g = 0; g < Count; g++)
136 *(basePtr + g) = (ushort)(object)value;
140 else if (typeof(T) == typeof(short))
142 fixed (short* basePtr = &this.register.int16_0)
144 for (nint g = 0; g < Count; g++)
146 *(basePtr + g) = (short)(object)value;
150 else if (typeof(T) == typeof(uint))
152 fixed (uint* basePtr = &this.register.uint32_0)
154 for (nint g = 0; g < Count; g++)
156 *(basePtr + g) = (uint)(object)value;
160 else if (typeof(T) == typeof(int))
162 fixed (int* basePtr = &this.register.int32_0)
164 for (nint g = 0; g < Count; g++)
166 *(basePtr + g) = (int)(object)value;
170 else if (typeof(T) == typeof(ulong))
172 fixed (ulong* basePtr = &this.register.uint64_0)
174 for (nint g = 0; g < Count; g++)
176 *(basePtr + g) = (ulong)(object)value;
180 else if (typeof(T) == typeof(long))
182 fixed (long* basePtr = &this.register.int64_0)
184 for (nint g = 0; g < Count; g++)
186 *(basePtr + g) = (long)(object)value;
190 else if (typeof(T) == typeof(float))
192 fixed (float* basePtr = &this.register.single_0)
194 for (nint g = 0; g < Count; g++)
196 *(basePtr + g) = (float)(object)value;
200 else if (typeof(T) == typeof(double))
202 fixed (double* basePtr = &this.register.double_0)
204 for (nint g = 0; g < Count; g++)
206 *(basePtr + g) = (double)(object)value;
211 else
213 if (typeof(T) == typeof(byte))
215 register.byte_0 = (byte)(object)value;
216 register.byte_1 = (byte)(object)value;
217 register.byte_2 = (byte)(object)value;
218 register.byte_3 = (byte)(object)value;
219 register.byte_4 = (byte)(object)value;
220 register.byte_5 = (byte)(object)value;
221 register.byte_6 = (byte)(object)value;
222 register.byte_7 = (byte)(object)value;
223 register.byte_8 = (byte)(object)value;
224 register.byte_9 = (byte)(object)value;
225 register.byte_10 = (byte)(object)value;
226 register.byte_11 = (byte)(object)value;
227 register.byte_12 = (byte)(object)value;
228 register.byte_13 = (byte)(object)value;
229 register.byte_14 = (byte)(object)value;
230 register.byte_15 = (byte)(object)value;
232 else if (typeof(T) == typeof(sbyte))
234 register.sbyte_0 = (sbyte)(object)value;
235 register.sbyte_1 = (sbyte)(object)value;
236 register.sbyte_2 = (sbyte)(object)value;
237 register.sbyte_3 = (sbyte)(object)value;
238 register.sbyte_4 = (sbyte)(object)value;
239 register.sbyte_5 = (sbyte)(object)value;
240 register.sbyte_6 = (sbyte)(object)value;
241 register.sbyte_7 = (sbyte)(object)value;
242 register.sbyte_8 = (sbyte)(object)value;
243 register.sbyte_9 = (sbyte)(object)value;
244 register.sbyte_10 = (sbyte)(object)value;
245 register.sbyte_11 = (sbyte)(object)value;
246 register.sbyte_12 = (sbyte)(object)value;
247 register.sbyte_13 = (sbyte)(object)value;
248 register.sbyte_14 = (sbyte)(object)value;
249 register.sbyte_15 = (sbyte)(object)value;
251 else if (typeof(T) == typeof(ushort))
253 register.uint16_0 = (ushort)(object)value;
254 register.uint16_1 = (ushort)(object)value;
255 register.uint16_2 = (ushort)(object)value;
256 register.uint16_3 = (ushort)(object)value;
257 register.uint16_4 = (ushort)(object)value;
258 register.uint16_5 = (ushort)(object)value;
259 register.uint16_6 = (ushort)(object)value;
260 register.uint16_7 = (ushort)(object)value;
262 else if (typeof(T) == typeof(short))
264 register.int16_0 = (short)(object)value;
265 register.int16_1 = (short)(object)value;
266 register.int16_2 = (short)(object)value;
267 register.int16_3 = (short)(object)value;
268 register.int16_4 = (short)(object)value;
269 register.int16_5 = (short)(object)value;
270 register.int16_6 = (short)(object)value;
271 register.int16_7 = (short)(object)value;
273 else if (typeof(T) == typeof(uint))
275 register.uint32_0 = (uint)(object)value;
276 register.uint32_1 = (uint)(object)value;
277 register.uint32_2 = (uint)(object)value;
278 register.uint32_3 = (uint)(object)value;
280 else if (typeof(T) == typeof(int))
282 register.int32_0 = (int)(object)value;
283 register.int32_1 = (int)(object)value;
284 register.int32_2 = (int)(object)value;
285 register.int32_3 = (int)(object)value;
287 else if (typeof(T) == typeof(ulong))
289 register.uint64_0 = (ulong)(object)value;
290 register.uint64_1 = (ulong)(object)value;
292 else if (typeof(T) == typeof(long))
294 register.int64_0 = (long)(object)value;
295 register.int64_1 = (long)(object)value;
297 else if (typeof(T) == typeof(float))
299 register.single_0 = (float)(object)value;
300 register.single_1 = (float)(object)value;
301 register.single_2 = (float)(object)value;
302 register.single_3 = (float)(object)value;
304 else if (typeof(T) == typeof(double))
306 register.double_0 = (double)(object)value;
307 register.double_1 = (double)(object)value;
312 /// <summary>
313 /// Constructs a vector from the given array. The size of the given array must be at least Vector'T.Count.
314 /// </summary>
315 [Intrinsic]
316 public unsafe Vector(T[] values) : this(values, 0) { }
318 /// <summary>
319 /// Constructs a vector from the given array, starting from the given index.
320 /// The array must contain at least Vector'T.Count from the given index.
321 /// </summary>
322 [Intrinsic]
323 public unsafe Vector(T[] values, int index)
325 if (values == null)
327 // Match the JIT's exception type here. For perf, a NullReference is thrown instead of an ArgumentNull.
328 throw new NullReferenceException(SR.Arg_NullArgumentNullRef);
330 if (index < 0 || (values.Length - index) < Count)
332 Vector.ThrowInsufficientNumberOfElementsException(Vector<T>.Count);
334 this = Unsafe.ReadUnaligned<Vector<T>>(ref Unsafe.As<T, byte>(ref values[index]));
337 internal unsafe Vector(void* dataPointer)
339 ThrowHelper.ThrowForUnsupportedVectorBaseType<T>();
340 this = Unsafe.ReadUnaligned<Vector<T>>(dataPointer);
343 private Vector(ref Register existingRegister)
345 this.register = existingRegister;
348 /// <summary>
349 /// Constructs a vector from the given <see cref="ReadOnlySpan{Byte}"/>. The span must contain at least <see cref="Vector{Byte}.Count"/> elements.
350 /// </summary>
351 [MethodImpl(MethodImplOptions.AggressiveInlining)]
352 public Vector(ReadOnlySpan<byte> values)
354 ThrowHelper.ThrowForUnsupportedVectorBaseType<T>();
355 if (values.Length < Vector<byte>.Count)
357 Vector.ThrowInsufficientNumberOfElementsException(Vector<byte>.Count);
359 this = Unsafe.ReadUnaligned<Vector<T>>(ref MemoryMarshal.GetReference(values));
362 /// <summary>
363 /// Constructs a vector from the given <see cref="ReadOnlySpan{T}"/>. The span must contain at least <see cref="Vector{T}.Count"/> elements.
364 /// </summary>
365 [MethodImpl(MethodImplOptions.AggressiveInlining)]
366 public Vector(ReadOnlySpan<T> values)
368 if (values.Length < Count)
370 Vector.ThrowInsufficientNumberOfElementsException(Vector<T>.Count);
372 this = Unsafe.ReadUnaligned<Vector<T>>(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)));
375 /// <summary>
376 /// Constructs a vector from the given <see cref="Span{T}"/>. The span must contain at least <see cref="Vector{T}.Count"/> elements.
377 /// </summary>
378 [MethodImpl(MethodImplOptions.AggressiveInlining)]
379 public Vector(Span<T> values)
381 if (values.Length < Count)
383 Vector.ThrowInsufficientNumberOfElementsException(Vector<T>.Count);
385 this = Unsafe.ReadUnaligned<Vector<T>>(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)));
387 #endregion Constructors
389 #region Public Instance Methods
390 /// <summary>
391 /// Copies the vector to the given <see cref="Span{Byte}"/>. The destination span must be at least size <see cref="Vector{Byte}.Count"/>.
392 /// </summary>
393 /// <param name="destination">The destination span which the values are copied into</param>
394 /// <exception cref="ArgumentException">If number of elements in source vector is greater than those available in destination span</exception>
395 public readonly void CopyTo(Span<byte> destination)
397 ThrowHelper.ThrowForUnsupportedVectorBaseType<T>();
398 if ((uint)destination.Length < (uint)Vector<byte>.Count)
400 ThrowHelper.ThrowArgumentException_DestinationTooShort();
403 Unsafe.WriteUnaligned<Vector<T>>(ref MemoryMarshal.GetReference(destination), this);
406 /// <summary>
407 /// Copies the vector to the given <see cref="Span{T}"/>. The destination span must be at least size <see cref="Vector{T}.Count"/>.
408 /// </summary>
409 /// <param name="destination">The destination span which the values are copied into</param>
410 /// <exception cref="ArgumentException">If number of elements in source vector is greater than those available in destination span</exception>
411 public readonly void CopyTo(Span<T> destination)
413 if ((uint)destination.Length < (uint)Count)
415 ThrowHelper.ThrowArgumentException_DestinationTooShort();
418 Unsafe.WriteUnaligned<Vector<T>>(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(destination)), this);
421 /// <summary>
422 /// Copies the vector to the given destination array. The destination array must be at least size Vector'T.Count.
423 /// </summary>
424 /// <param name="destination">The destination array which the values are copied into</param>
425 /// <exception cref="ArgumentNullException">If the destination array is null</exception>
426 /// <exception cref="ArgumentException">If number of elements in source vector is greater than those available in destination array</exception>
427 [Intrinsic]
428 public readonly void CopyTo(T[] destination)
430 CopyTo(destination, 0);
433 /// <summary>
434 /// Copies the vector to the given destination array. The destination array must be at least size Vector'T.Count.
435 /// </summary>
436 /// <param name="destination">The destination array which the values are copied into</param>
437 /// <param name="startIndex">The index to start copying to</param>
438 /// <exception cref="ArgumentNullException">If the destination array is null</exception>
439 /// <exception cref="ArgumentOutOfRangeException">If index is greater than end of the array or index is less than zero</exception>
440 /// <exception cref="ArgumentException">If number of elements in source vector is greater than those available in destination array</exception>
441 [Intrinsic]
442 public readonly unsafe void CopyTo(T[] destination, int startIndex)
444 if (destination == null)
446 // Match the JIT's exception type here. For perf, a NullReference is thrown instead of an ArgumentNull.
447 throw new NullReferenceException(SR.Arg_NullArgumentNullRef);
449 if ((uint)startIndex >= (uint)destination.Length)
451 throw new ArgumentOutOfRangeException(nameof(startIndex), SR.Format(SR.Arg_ArgumentOutOfRangeException, startIndex));
453 if ((destination.Length - startIndex) < Count)
455 throw new ArgumentException(SR.Format(SR.Arg_ElementsInSourceIsGreaterThanDestination, startIndex));
458 Unsafe.WriteUnaligned<Vector<T>>(ref Unsafe.As<T, byte>(ref destination[startIndex]), this);
461 /// <summary>
462 /// Returns the element at the given index.
463 /// </summary>
464 public readonly unsafe T this[int index]
466 [Intrinsic]
469 if ((uint)index >= (uint)Count)
471 throw new IndexOutOfRangeException(SR.Format(SR.Arg_ArgumentOutOfRangeException, index));
474 return Unsafe.Add(ref Unsafe.As<Vector<T>, T>(ref Unsafe.AsRef<Vector<T>>(in this)), index);
478 /// <summary>
479 /// Returns a boolean indicating whether the given Object is equal to this vector instance.
480 /// </summary>
481 /// <param name="obj">The Object to compare against.</param>
482 /// <returns>True if the Object is equal to this vector; False otherwise.</returns>
483 [MethodImpl(MethodImplOptions.AggressiveInlining)]
484 public override readonly bool Equals(object? obj)
486 if (!(obj is Vector<T>))
488 return false;
490 return Equals((Vector<T>)obj);
493 /// <summary>
494 /// Returns a boolean indicating whether the given vector is equal to this vector instance.
495 /// </summary>
496 /// <param name="other">The vector to compare this instance to.</param>
497 /// <returns>True if the other vector is equal to this instance; False otherwise.</returns>
498 [Intrinsic]
499 public readonly bool Equals(Vector<T> other)
501 if (Vector.IsHardwareAccelerated)
503 for (int g = 0; g < Count; g++)
505 if (!ScalarEquals(this[g], other[g]))
507 return false;
510 return true;
512 else
514 if (typeof(T) == typeof(byte))
516 return
517 this.register.byte_0 == other.register.byte_0
518 && this.register.byte_1 == other.register.byte_1
519 && this.register.byte_2 == other.register.byte_2
520 && this.register.byte_3 == other.register.byte_3
521 && this.register.byte_4 == other.register.byte_4
522 && this.register.byte_5 == other.register.byte_5
523 && this.register.byte_6 == other.register.byte_6
524 && this.register.byte_7 == other.register.byte_7
525 && this.register.byte_8 == other.register.byte_8
526 && this.register.byte_9 == other.register.byte_9
527 && this.register.byte_10 == other.register.byte_10
528 && this.register.byte_11 == other.register.byte_11
529 && this.register.byte_12 == other.register.byte_12
530 && this.register.byte_13 == other.register.byte_13
531 && this.register.byte_14 == other.register.byte_14
532 && this.register.byte_15 == other.register.byte_15;
534 else if (typeof(T) == typeof(sbyte))
536 return
537 this.register.sbyte_0 == other.register.sbyte_0
538 && this.register.sbyte_1 == other.register.sbyte_1
539 && this.register.sbyte_2 == other.register.sbyte_2
540 && this.register.sbyte_3 == other.register.sbyte_3
541 && this.register.sbyte_4 == other.register.sbyte_4
542 && this.register.sbyte_5 == other.register.sbyte_5
543 && this.register.sbyte_6 == other.register.sbyte_6
544 && this.register.sbyte_7 == other.register.sbyte_7
545 && this.register.sbyte_8 == other.register.sbyte_8
546 && this.register.sbyte_9 == other.register.sbyte_9
547 && this.register.sbyte_10 == other.register.sbyte_10
548 && this.register.sbyte_11 == other.register.sbyte_11
549 && this.register.sbyte_12 == other.register.sbyte_12
550 && this.register.sbyte_13 == other.register.sbyte_13
551 && this.register.sbyte_14 == other.register.sbyte_14
552 && this.register.sbyte_15 == other.register.sbyte_15;
554 else if (typeof(T) == typeof(ushort))
556 return
557 this.register.uint16_0 == other.register.uint16_0
558 && this.register.uint16_1 == other.register.uint16_1
559 && this.register.uint16_2 == other.register.uint16_2
560 && this.register.uint16_3 == other.register.uint16_3
561 && this.register.uint16_4 == other.register.uint16_4
562 && this.register.uint16_5 == other.register.uint16_5
563 && this.register.uint16_6 == other.register.uint16_6
564 && this.register.uint16_7 == other.register.uint16_7;
566 else if (typeof(T) == typeof(short))
568 return
569 this.register.int16_0 == other.register.int16_0
570 && this.register.int16_1 == other.register.int16_1
571 && this.register.int16_2 == other.register.int16_2
572 && this.register.int16_3 == other.register.int16_3
573 && this.register.int16_4 == other.register.int16_4
574 && this.register.int16_5 == other.register.int16_5
575 && this.register.int16_6 == other.register.int16_6
576 && this.register.int16_7 == other.register.int16_7;
578 else if (typeof(T) == typeof(uint))
580 return
581 this.register.uint32_0 == other.register.uint32_0
582 && this.register.uint32_1 == other.register.uint32_1
583 && this.register.uint32_2 == other.register.uint32_2
584 && this.register.uint32_3 == other.register.uint32_3;
586 else if (typeof(T) == typeof(int))
588 return
589 this.register.int32_0 == other.register.int32_0
590 && this.register.int32_1 == other.register.int32_1
591 && this.register.int32_2 == other.register.int32_2
592 && this.register.int32_3 == other.register.int32_3;
594 else if (typeof(T) == typeof(ulong))
596 return
597 this.register.uint64_0 == other.register.uint64_0
598 && this.register.uint64_1 == other.register.uint64_1;
600 else if (typeof(T) == typeof(long))
602 return
603 this.register.int64_0 == other.register.int64_0
604 && this.register.int64_1 == other.register.int64_1;
606 else if (typeof(T) == typeof(float))
608 return
609 this.register.single_0 == other.register.single_0
610 && this.register.single_1 == other.register.single_1
611 && this.register.single_2 == other.register.single_2
612 && this.register.single_3 == other.register.single_3;
614 else if (typeof(T) == typeof(double))
616 return
617 this.register.double_0 == other.register.double_0
618 && this.register.double_1 == other.register.double_1;
620 else
622 throw new NotSupportedException(SR.Arg_TypeNotSupported);
627 /// <summary>
628 /// Returns the hash code for this instance.
629 /// </summary>
630 /// <returns>The hash code.</returns>
631 public override readonly int GetHashCode()
633 HashCode hashCode = new HashCode();
635 if (typeof(T) == typeof(byte) ||
636 typeof(T) == typeof(sbyte) ||
637 typeof(T) == typeof(ushort) ||
638 typeof(T) == typeof(short) ||
639 typeof(T) == typeof(int) ||
640 typeof(T) == typeof(uint) ||
641 typeof(T) == typeof(long) ||
642 typeof(T) == typeof(ulong))
644 for (nint g = 0; g < Vector<int>.Count; g++)
646 hashCode.Add(Unsafe.Add(ref Unsafe.As<Vector<T>, int>(ref Unsafe.AsRef<Vector<T>>(in this)), (IntPtr)g));
649 else if (typeof(T) == typeof(float))
651 for (nint g = 0; g < Count; g++)
653 hashCode.Add(Unsafe.Add(ref Unsafe.As<Vector<T>, float>(ref Unsafe.AsRef<Vector<T>>(in this)), (IntPtr)g));
656 else if (typeof(T) == typeof(double))
658 for (nint g = 0; g < Count; g++)
660 hashCode.Add(Unsafe.Add(ref Unsafe.As<Vector<T>, double>(ref Unsafe.AsRef<Vector<T>>(in this)), (IntPtr)g));
663 else
665 throw new NotSupportedException(SR.Arg_TypeNotSupported);
668 return hashCode.ToHashCode();
671 /// <summary>
672 /// Returns a String representing this vector.
673 /// </summary>
674 /// <returns>The string representation.</returns>
675 public override readonly string ToString()
677 return ToString("G", CultureInfo.CurrentCulture);
680 /// <summary>
681 /// Returns a String representing this vector, using the specified format string to format individual elements.
682 /// </summary>
683 /// <param name="format">The format of individual elements.</param>
684 /// <returns>The string representation.</returns>
685 public readonly string ToString(string? format)
687 return ToString(format, CultureInfo.CurrentCulture);
690 /// <summary>
691 /// Returns a String representing this vector, using the specified format string to format individual elements
692 /// and the given IFormatProvider.
693 /// </summary>
694 /// <param name="format">The format of individual elements.</param>
695 /// <param name="formatProvider">The format provider to use when formatting elements.</param>
696 /// <returns>The string representation.</returns>
697 public readonly string ToString(string? format, IFormatProvider? formatProvider)
699 StringBuilder sb = new StringBuilder();
700 string separator = NumberFormatInfo.GetInstance(formatProvider).NumberGroupSeparator;
701 sb.Append('<');
702 for (int g = 0; g < Count - 1; g++)
704 sb.Append(((IFormattable)this[g]).ToString(format, formatProvider));
705 sb.Append(separator);
706 sb.Append(' ');
708 // Append last element w/out separator
709 sb.Append(((IFormattable)this[Count - 1]).ToString(format, formatProvider));
710 sb.Append('>');
711 return sb.ToString();
714 /// <summary>
715 /// Attempts to copy the vector to the given <see cref="Span{Byte}"/>. The destination span must be at least size <see cref="Vector{Byte}.Count"/>.
716 /// </summary>
717 /// <param name="destination">The destination span which the values are copied into</param>
718 /// <returns>True if the source vector was successfully copied to <paramref name="destination"/>. False if
719 /// <paramref name="destination"/> is not large enough to hold the source vector.</returns>
720 public readonly bool TryCopyTo(Span<byte> destination)
722 ThrowHelper.ThrowForUnsupportedVectorBaseType<T>();
723 if ((uint)destination.Length < (uint)Vector<byte>.Count)
725 return false;
728 Unsafe.WriteUnaligned<Vector<T>>(ref MemoryMarshal.GetReference(destination), this);
729 return true;
732 /// <summary>
733 /// Attempts to copy the vector to the given <see cref="Span{T}"/>. The destination span must be at least size <see cref="Vector{T}.Count"/>.
734 /// </summary>
735 /// <param name="destination">The destination span which the values are copied into</param>
736 /// <returns>True if the source vector was successfully copied to <paramref name="destination"/>. False if
737 /// <paramref name="destination"/> is not large enough to hold the source vector.</returns>
738 public readonly bool TryCopyTo(Span<T> destination)
740 if ((uint)destination.Length < (uint)Count)
742 return false;
745 Unsafe.WriteUnaligned<Vector<T>>(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(destination)), this);
746 return true;
748 #endregion Public Instance Methods
750 #region Arithmetic Operators
751 /// <summary>
752 /// Adds two vectors together.
753 /// </summary>
754 /// <param name="left">The first source vector.</param>
755 /// <param name="right">The second source vector.</param>
756 /// <returns>The summed vector.</returns>
757 [Intrinsic]
758 public static unsafe Vector<T> operator +(Vector<T> left, Vector<T> right)
760 unchecked
762 if (Vector.IsHardwareAccelerated)
764 if (typeof(T) == typeof(byte))
766 byte* dataPtr = stackalloc byte[Count];
767 for (int g = 0; g < Count; g++)
769 dataPtr[g] = (byte)(object)ScalarAdd(left[g], right[g]);
771 return new Vector<T>(dataPtr);
773 else if (typeof(T) == typeof(sbyte))
775 sbyte* dataPtr = stackalloc sbyte[Count];
776 for (int g = 0; g < Count; g++)
778 dataPtr[g] = (sbyte)(object)ScalarAdd(left[g], right[g]);
780 return new Vector<T>(dataPtr);
782 else if (typeof(T) == typeof(ushort))
784 ushort* dataPtr = stackalloc ushort[Count];
785 for (int g = 0; g < Count; g++)
787 dataPtr[g] = (ushort)(object)ScalarAdd(left[g], right[g]);
789 return new Vector<T>(dataPtr);
791 else if (typeof(T) == typeof(short))
793 short* dataPtr = stackalloc short[Count];
794 for (int g = 0; g < Count; g++)
796 dataPtr[g] = (short)(object)ScalarAdd(left[g], right[g]);
798 return new Vector<T>(dataPtr);
800 else if (typeof(T) == typeof(uint))
802 uint* dataPtr = stackalloc uint[Count];
803 for (int g = 0; g < Count; g++)
805 dataPtr[g] = (uint)(object)ScalarAdd(left[g], right[g]);
807 return new Vector<T>(dataPtr);
809 else if (typeof(T) == typeof(int))
811 int* dataPtr = stackalloc int[Count];
812 for (int g = 0; g < Count; g++)
814 dataPtr[g] = (int)(object)ScalarAdd(left[g], right[g]);
816 return new Vector<T>(dataPtr);
818 else if (typeof(T) == typeof(ulong))
820 ulong* dataPtr = stackalloc ulong[Count];
821 for (int g = 0; g < Count; g++)
823 dataPtr[g] = (ulong)(object)ScalarAdd(left[g], right[g]);
825 return new Vector<T>(dataPtr);
827 else if (typeof(T) == typeof(long))
829 long* dataPtr = stackalloc long[Count];
830 for (int g = 0; g < Count; g++)
832 dataPtr[g] = (long)(object)ScalarAdd(left[g], right[g]);
834 return new Vector<T>(dataPtr);
836 else if (typeof(T) == typeof(float))
838 float* dataPtr = stackalloc float[Count];
839 for (int g = 0; g < Count; g++)
841 dataPtr[g] = (float)(object)ScalarAdd(left[g], right[g]);
843 return new Vector<T>(dataPtr);
845 else if (typeof(T) == typeof(double))
847 double* dataPtr = stackalloc double[Count];
848 for (int g = 0; g < Count; g++)
850 dataPtr[g] = (double)(object)ScalarAdd(left[g], right[g]);
852 return new Vector<T>(dataPtr);
854 else
856 throw new NotSupportedException(SR.Arg_TypeNotSupported);
859 else
861 Vector<T> sum = new Vector<T>();
862 if (typeof(T) == typeof(byte))
864 sum.register.byte_0 = (byte)(left.register.byte_0 + right.register.byte_0);
865 sum.register.byte_1 = (byte)(left.register.byte_1 + right.register.byte_1);
866 sum.register.byte_2 = (byte)(left.register.byte_2 + right.register.byte_2);
867 sum.register.byte_3 = (byte)(left.register.byte_3 + right.register.byte_3);
868 sum.register.byte_4 = (byte)(left.register.byte_4 + right.register.byte_4);
869 sum.register.byte_5 = (byte)(left.register.byte_5 + right.register.byte_5);
870 sum.register.byte_6 = (byte)(left.register.byte_6 + right.register.byte_6);
871 sum.register.byte_7 = (byte)(left.register.byte_7 + right.register.byte_7);
872 sum.register.byte_8 = (byte)(left.register.byte_8 + right.register.byte_8);
873 sum.register.byte_9 = (byte)(left.register.byte_9 + right.register.byte_9);
874 sum.register.byte_10 = (byte)(left.register.byte_10 + right.register.byte_10);
875 sum.register.byte_11 = (byte)(left.register.byte_11 + right.register.byte_11);
876 sum.register.byte_12 = (byte)(left.register.byte_12 + right.register.byte_12);
877 sum.register.byte_13 = (byte)(left.register.byte_13 + right.register.byte_13);
878 sum.register.byte_14 = (byte)(left.register.byte_14 + right.register.byte_14);
879 sum.register.byte_15 = (byte)(left.register.byte_15 + right.register.byte_15);
881 else if (typeof(T) == typeof(sbyte))
883 sum.register.sbyte_0 = (sbyte)(left.register.sbyte_0 + right.register.sbyte_0);
884 sum.register.sbyte_1 = (sbyte)(left.register.sbyte_1 + right.register.sbyte_1);
885 sum.register.sbyte_2 = (sbyte)(left.register.sbyte_2 + right.register.sbyte_2);
886 sum.register.sbyte_3 = (sbyte)(left.register.sbyte_3 + right.register.sbyte_3);
887 sum.register.sbyte_4 = (sbyte)(left.register.sbyte_4 + right.register.sbyte_4);
888 sum.register.sbyte_5 = (sbyte)(left.register.sbyte_5 + right.register.sbyte_5);
889 sum.register.sbyte_6 = (sbyte)(left.register.sbyte_6 + right.register.sbyte_6);
890 sum.register.sbyte_7 = (sbyte)(left.register.sbyte_7 + right.register.sbyte_7);
891 sum.register.sbyte_8 = (sbyte)(left.register.sbyte_8 + right.register.sbyte_8);
892 sum.register.sbyte_9 = (sbyte)(left.register.sbyte_9 + right.register.sbyte_9);
893 sum.register.sbyte_10 = (sbyte)(left.register.sbyte_10 + right.register.sbyte_10);
894 sum.register.sbyte_11 = (sbyte)(left.register.sbyte_11 + right.register.sbyte_11);
895 sum.register.sbyte_12 = (sbyte)(left.register.sbyte_12 + right.register.sbyte_12);
896 sum.register.sbyte_13 = (sbyte)(left.register.sbyte_13 + right.register.sbyte_13);
897 sum.register.sbyte_14 = (sbyte)(left.register.sbyte_14 + right.register.sbyte_14);
898 sum.register.sbyte_15 = (sbyte)(left.register.sbyte_15 + right.register.sbyte_15);
900 else if (typeof(T) == typeof(ushort))
902 sum.register.uint16_0 = (ushort)(left.register.uint16_0 + right.register.uint16_0);
903 sum.register.uint16_1 = (ushort)(left.register.uint16_1 + right.register.uint16_1);
904 sum.register.uint16_2 = (ushort)(left.register.uint16_2 + right.register.uint16_2);
905 sum.register.uint16_3 = (ushort)(left.register.uint16_3 + right.register.uint16_3);
906 sum.register.uint16_4 = (ushort)(left.register.uint16_4 + right.register.uint16_4);
907 sum.register.uint16_5 = (ushort)(left.register.uint16_5 + right.register.uint16_5);
908 sum.register.uint16_6 = (ushort)(left.register.uint16_6 + right.register.uint16_6);
909 sum.register.uint16_7 = (ushort)(left.register.uint16_7 + right.register.uint16_7);
911 else if (typeof(T) == typeof(short))
913 sum.register.int16_0 = (short)(left.register.int16_0 + right.register.int16_0);
914 sum.register.int16_1 = (short)(left.register.int16_1 + right.register.int16_1);
915 sum.register.int16_2 = (short)(left.register.int16_2 + right.register.int16_2);
916 sum.register.int16_3 = (short)(left.register.int16_3 + right.register.int16_3);
917 sum.register.int16_4 = (short)(left.register.int16_4 + right.register.int16_4);
918 sum.register.int16_5 = (short)(left.register.int16_5 + right.register.int16_5);
919 sum.register.int16_6 = (short)(left.register.int16_6 + right.register.int16_6);
920 sum.register.int16_7 = (short)(left.register.int16_7 + right.register.int16_7);
922 else if (typeof(T) == typeof(uint))
924 sum.register.uint32_0 = (uint)(left.register.uint32_0 + right.register.uint32_0);
925 sum.register.uint32_1 = (uint)(left.register.uint32_1 + right.register.uint32_1);
926 sum.register.uint32_2 = (uint)(left.register.uint32_2 + right.register.uint32_2);
927 sum.register.uint32_3 = (uint)(left.register.uint32_3 + right.register.uint32_3);
929 else if (typeof(T) == typeof(int))
931 sum.register.int32_0 = (int)(left.register.int32_0 + right.register.int32_0);
932 sum.register.int32_1 = (int)(left.register.int32_1 + right.register.int32_1);
933 sum.register.int32_2 = (int)(left.register.int32_2 + right.register.int32_2);
934 sum.register.int32_3 = (int)(left.register.int32_3 + right.register.int32_3);
936 else if (typeof(T) == typeof(ulong))
938 sum.register.uint64_0 = (ulong)(left.register.uint64_0 + right.register.uint64_0);
939 sum.register.uint64_1 = (ulong)(left.register.uint64_1 + right.register.uint64_1);
941 else if (typeof(T) == typeof(long))
943 sum.register.int64_0 = (long)(left.register.int64_0 + right.register.int64_0);
944 sum.register.int64_1 = (long)(left.register.int64_1 + right.register.int64_1);
946 else if (typeof(T) == typeof(float))
948 sum.register.single_0 = (float)(left.register.single_0 + right.register.single_0);
949 sum.register.single_1 = (float)(left.register.single_1 + right.register.single_1);
950 sum.register.single_2 = (float)(left.register.single_2 + right.register.single_2);
951 sum.register.single_3 = (float)(left.register.single_3 + right.register.single_3);
953 else if (typeof(T) == typeof(double))
955 sum.register.double_0 = (double)(left.register.double_0 + right.register.double_0);
956 sum.register.double_1 = (double)(left.register.double_1 + right.register.double_1);
958 return sum;
963 /// <summary>
964 /// Subtracts the second vector from the first.
965 /// </summary>
966 /// <param name="left">The first source vector.</param>
967 /// <param name="right">The second source vector.</param>
968 /// <returns>The difference vector.</returns>
969 [Intrinsic]
970 public static unsafe Vector<T> operator -(Vector<T> left, Vector<T> right)
972 unchecked
974 if (Vector.IsHardwareAccelerated)
976 if (typeof(T) == typeof(byte))
978 byte* dataPtr = stackalloc byte[Count];
979 for (int g = 0; g < Count; g++)
981 dataPtr[g] = (byte)(object)ScalarSubtract(left[g], right[g]);
983 return new Vector<T>(dataPtr);
985 else if (typeof(T) == typeof(sbyte))
987 sbyte* dataPtr = stackalloc sbyte[Count];
988 for (int g = 0; g < Count; g++)
990 dataPtr[g] = (sbyte)(object)ScalarSubtract(left[g], right[g]);
992 return new Vector<T>(dataPtr);
994 else if (typeof(T) == typeof(ushort))
996 ushort* dataPtr = stackalloc ushort[Count];
997 for (int g = 0; g < Count; g++)
999 dataPtr[g] = (ushort)(object)ScalarSubtract(left[g], right[g]);
1001 return new Vector<T>(dataPtr);
1003 else if (typeof(T) == typeof(short))
1005 short* dataPtr = stackalloc short[Count];
1006 for (int g = 0; g < Count; g++)
1008 dataPtr[g] = (short)(object)ScalarSubtract(left[g], right[g]);
1010 return new Vector<T>(dataPtr);
1012 else if (typeof(T) == typeof(uint))
1014 uint* dataPtr = stackalloc uint[Count];
1015 for (int g = 0; g < Count; g++)
1017 dataPtr[g] = (uint)(object)ScalarSubtract(left[g], right[g]);
1019 return new Vector<T>(dataPtr);
1021 else if (typeof(T) == typeof(int))
1023 int* dataPtr = stackalloc int[Count];
1024 for (int g = 0; g < Count; g++)
1026 dataPtr[g] = (int)(object)ScalarSubtract(left[g], right[g]);
1028 return new Vector<T>(dataPtr);
1030 else if (typeof(T) == typeof(ulong))
1032 ulong* dataPtr = stackalloc ulong[Count];
1033 for (int g = 0; g < Count; g++)
1035 dataPtr[g] = (ulong)(object)ScalarSubtract(left[g], right[g]);
1037 return new Vector<T>(dataPtr);
1039 else if (typeof(T) == typeof(long))
1041 long* dataPtr = stackalloc long[Count];
1042 for (int g = 0; g < Count; g++)
1044 dataPtr[g] = (long)(object)ScalarSubtract(left[g], right[g]);
1046 return new Vector<T>(dataPtr);
1048 else if (typeof(T) == typeof(float))
1050 float* dataPtr = stackalloc float[Count];
1051 for (int g = 0; g < Count; g++)
1053 dataPtr[g] = (float)(object)ScalarSubtract(left[g], right[g]);
1055 return new Vector<T>(dataPtr);
1057 else if (typeof(T) == typeof(double))
1059 double* dataPtr = stackalloc double[Count];
1060 for (int g = 0; g < Count; g++)
1062 dataPtr[g] = (double)(object)ScalarSubtract(left[g], right[g]);
1064 return new Vector<T>(dataPtr);
1066 else
1068 throw new NotSupportedException(SR.Arg_TypeNotSupported);
1071 else
1073 Vector<T> difference = new Vector<T>();
1074 if (typeof(T) == typeof(byte))
1076 difference.register.byte_0 = (byte)(left.register.byte_0 - right.register.byte_0);
1077 difference.register.byte_1 = (byte)(left.register.byte_1 - right.register.byte_1);
1078 difference.register.byte_2 = (byte)(left.register.byte_2 - right.register.byte_2);
1079 difference.register.byte_3 = (byte)(left.register.byte_3 - right.register.byte_3);
1080 difference.register.byte_4 = (byte)(left.register.byte_4 - right.register.byte_4);
1081 difference.register.byte_5 = (byte)(left.register.byte_5 - right.register.byte_5);
1082 difference.register.byte_6 = (byte)(left.register.byte_6 - right.register.byte_6);
1083 difference.register.byte_7 = (byte)(left.register.byte_7 - right.register.byte_7);
1084 difference.register.byte_8 = (byte)(left.register.byte_8 - right.register.byte_8);
1085 difference.register.byte_9 = (byte)(left.register.byte_9 - right.register.byte_9);
1086 difference.register.byte_10 = (byte)(left.register.byte_10 - right.register.byte_10);
1087 difference.register.byte_11 = (byte)(left.register.byte_11 - right.register.byte_11);
1088 difference.register.byte_12 = (byte)(left.register.byte_12 - right.register.byte_12);
1089 difference.register.byte_13 = (byte)(left.register.byte_13 - right.register.byte_13);
1090 difference.register.byte_14 = (byte)(left.register.byte_14 - right.register.byte_14);
1091 difference.register.byte_15 = (byte)(left.register.byte_15 - right.register.byte_15);
1093 else if (typeof(T) == typeof(sbyte))
1095 difference.register.sbyte_0 = (sbyte)(left.register.sbyte_0 - right.register.sbyte_0);
1096 difference.register.sbyte_1 = (sbyte)(left.register.sbyte_1 - right.register.sbyte_1);
1097 difference.register.sbyte_2 = (sbyte)(left.register.sbyte_2 - right.register.sbyte_2);
1098 difference.register.sbyte_3 = (sbyte)(left.register.sbyte_3 - right.register.sbyte_3);
1099 difference.register.sbyte_4 = (sbyte)(left.register.sbyte_4 - right.register.sbyte_4);
1100 difference.register.sbyte_5 = (sbyte)(left.register.sbyte_5 - right.register.sbyte_5);
1101 difference.register.sbyte_6 = (sbyte)(left.register.sbyte_6 - right.register.sbyte_6);
1102 difference.register.sbyte_7 = (sbyte)(left.register.sbyte_7 - right.register.sbyte_7);
1103 difference.register.sbyte_8 = (sbyte)(left.register.sbyte_8 - right.register.sbyte_8);
1104 difference.register.sbyte_9 = (sbyte)(left.register.sbyte_9 - right.register.sbyte_9);
1105 difference.register.sbyte_10 = (sbyte)(left.register.sbyte_10 - right.register.sbyte_10);
1106 difference.register.sbyte_11 = (sbyte)(left.register.sbyte_11 - right.register.sbyte_11);
1107 difference.register.sbyte_12 = (sbyte)(left.register.sbyte_12 - right.register.sbyte_12);
1108 difference.register.sbyte_13 = (sbyte)(left.register.sbyte_13 - right.register.sbyte_13);
1109 difference.register.sbyte_14 = (sbyte)(left.register.sbyte_14 - right.register.sbyte_14);
1110 difference.register.sbyte_15 = (sbyte)(left.register.sbyte_15 - right.register.sbyte_15);
1112 else if (typeof(T) == typeof(ushort))
1114 difference.register.uint16_0 = (ushort)(left.register.uint16_0 - right.register.uint16_0);
1115 difference.register.uint16_1 = (ushort)(left.register.uint16_1 - right.register.uint16_1);
1116 difference.register.uint16_2 = (ushort)(left.register.uint16_2 - right.register.uint16_2);
1117 difference.register.uint16_3 = (ushort)(left.register.uint16_3 - right.register.uint16_3);
1118 difference.register.uint16_4 = (ushort)(left.register.uint16_4 - right.register.uint16_4);
1119 difference.register.uint16_5 = (ushort)(left.register.uint16_5 - right.register.uint16_5);
1120 difference.register.uint16_6 = (ushort)(left.register.uint16_6 - right.register.uint16_6);
1121 difference.register.uint16_7 = (ushort)(left.register.uint16_7 - right.register.uint16_7);
1123 else if (typeof(T) == typeof(short))
1125 difference.register.int16_0 = (short)(left.register.int16_0 - right.register.int16_0);
1126 difference.register.int16_1 = (short)(left.register.int16_1 - right.register.int16_1);
1127 difference.register.int16_2 = (short)(left.register.int16_2 - right.register.int16_2);
1128 difference.register.int16_3 = (short)(left.register.int16_3 - right.register.int16_3);
1129 difference.register.int16_4 = (short)(left.register.int16_4 - right.register.int16_4);
1130 difference.register.int16_5 = (short)(left.register.int16_5 - right.register.int16_5);
1131 difference.register.int16_6 = (short)(left.register.int16_6 - right.register.int16_6);
1132 difference.register.int16_7 = (short)(left.register.int16_7 - right.register.int16_7);
1134 else if (typeof(T) == typeof(uint))
1136 difference.register.uint32_0 = (uint)(left.register.uint32_0 - right.register.uint32_0);
1137 difference.register.uint32_1 = (uint)(left.register.uint32_1 - right.register.uint32_1);
1138 difference.register.uint32_2 = (uint)(left.register.uint32_2 - right.register.uint32_2);
1139 difference.register.uint32_3 = (uint)(left.register.uint32_3 - right.register.uint32_3);
1141 else if (typeof(T) == typeof(int))
1143 difference.register.int32_0 = (int)(left.register.int32_0 - right.register.int32_0);
1144 difference.register.int32_1 = (int)(left.register.int32_1 - right.register.int32_1);
1145 difference.register.int32_2 = (int)(left.register.int32_2 - right.register.int32_2);
1146 difference.register.int32_3 = (int)(left.register.int32_3 - right.register.int32_3);
1148 else if (typeof(T) == typeof(ulong))
1150 difference.register.uint64_0 = (ulong)(left.register.uint64_0 - right.register.uint64_0);
1151 difference.register.uint64_1 = (ulong)(left.register.uint64_1 - right.register.uint64_1);
1153 else if (typeof(T) == typeof(long))
1155 difference.register.int64_0 = (long)(left.register.int64_0 - right.register.int64_0);
1156 difference.register.int64_1 = (long)(left.register.int64_1 - right.register.int64_1);
1158 else if (typeof(T) == typeof(float))
1160 difference.register.single_0 = (float)(left.register.single_0 - right.register.single_0);
1161 difference.register.single_1 = (float)(left.register.single_1 - right.register.single_1);
1162 difference.register.single_2 = (float)(left.register.single_2 - right.register.single_2);
1163 difference.register.single_3 = (float)(left.register.single_3 - right.register.single_3);
1165 else if (typeof(T) == typeof(double))
1167 difference.register.double_0 = (double)(left.register.double_0 - right.register.double_0);
1168 difference.register.double_1 = (double)(left.register.double_1 - right.register.double_1);
1170 return difference;
1175 // This method is intrinsic only for certain types. It cannot access fields directly unless we are sure the context is unaccelerated.
1176 /// <summary>
1177 /// Multiplies two vectors together.
1178 /// </summary>
1179 /// <param name="left">The first source vector.</param>
1180 /// <param name="right">The second source vector.</param>
1181 /// <returns>The product vector.</returns>
1182 [Intrinsic]
1183 public static unsafe Vector<T> operator *(Vector<T> left, Vector<T> right)
1185 unchecked
1187 if (Vector.IsHardwareAccelerated)
1189 if (typeof(T) == typeof(byte))
1191 byte* dataPtr = stackalloc byte[Count];
1192 for (int g = 0; g < Count; g++)
1194 dataPtr[g] = (byte)(object)ScalarMultiply(left[g], right[g]);
1196 return new Vector<T>(dataPtr);
1198 else if (typeof(T) == typeof(sbyte))
1200 sbyte* dataPtr = stackalloc sbyte[Count];
1201 for (int g = 0; g < Count; g++)
1203 dataPtr[g] = (sbyte)(object)ScalarMultiply(left[g], right[g]);
1205 return new Vector<T>(dataPtr);
1207 else if (typeof(T) == typeof(ushort))
1209 ushort* dataPtr = stackalloc ushort[Count];
1210 for (int g = 0; g < Count; g++)
1212 dataPtr[g] = (ushort)(object)ScalarMultiply(left[g], right[g]);
1214 return new Vector<T>(dataPtr);
1216 else if (typeof(T) == typeof(short))
1218 short* dataPtr = stackalloc short[Count];
1219 for (int g = 0; g < Count; g++)
1221 dataPtr[g] = (short)(object)ScalarMultiply(left[g], right[g]);
1223 return new Vector<T>(dataPtr);
1225 else if (typeof(T) == typeof(uint))
1227 uint* dataPtr = stackalloc uint[Count];
1228 for (int g = 0; g < Count; g++)
1230 dataPtr[g] = (uint)(object)ScalarMultiply(left[g], right[g]);
1232 return new Vector<T>(dataPtr);
1234 else if (typeof(T) == typeof(int))
1236 int* dataPtr = stackalloc int[Count];
1237 for (int g = 0; g < Count; g++)
1239 dataPtr[g] = (int)(object)ScalarMultiply(left[g], right[g]);
1241 return new Vector<T>(dataPtr);
1243 else if (typeof(T) == typeof(ulong))
1245 ulong* dataPtr = stackalloc ulong[Count];
1246 for (int g = 0; g < Count; g++)
1248 dataPtr[g] = (ulong)(object)ScalarMultiply(left[g], right[g]);
1250 return new Vector<T>(dataPtr);
1252 else if (typeof(T) == typeof(long))
1254 long* dataPtr = stackalloc long[Count];
1255 for (int g = 0; g < Count; g++)
1257 dataPtr[g] = (long)(object)ScalarMultiply(left[g], right[g]);
1259 return new Vector<T>(dataPtr);
1261 else if (typeof(T) == typeof(float))
1263 float* dataPtr = stackalloc float[Count];
1264 for (int g = 0; g < Count; g++)
1266 dataPtr[g] = (float)(object)ScalarMultiply(left[g], right[g]);
1268 return new Vector<T>(dataPtr);
1270 else if (typeof(T) == typeof(double))
1272 double* dataPtr = stackalloc double[Count];
1273 for (int g = 0; g < Count; g++)
1275 dataPtr[g] = (double)(object)ScalarMultiply(left[g], right[g]);
1277 return new Vector<T>(dataPtr);
1279 else
1281 throw new NotSupportedException(SR.Arg_TypeNotSupported);
1284 else
1286 Vector<T> product = new Vector<T>();
1287 if (typeof(T) == typeof(byte))
1289 product.register.byte_0 = (byte)(left.register.byte_0 * right.register.byte_0);
1290 product.register.byte_1 = (byte)(left.register.byte_1 * right.register.byte_1);
1291 product.register.byte_2 = (byte)(left.register.byte_2 * right.register.byte_2);
1292 product.register.byte_3 = (byte)(left.register.byte_3 * right.register.byte_3);
1293 product.register.byte_4 = (byte)(left.register.byte_4 * right.register.byte_4);
1294 product.register.byte_5 = (byte)(left.register.byte_5 * right.register.byte_5);
1295 product.register.byte_6 = (byte)(left.register.byte_6 * right.register.byte_6);
1296 product.register.byte_7 = (byte)(left.register.byte_7 * right.register.byte_7);
1297 product.register.byte_8 = (byte)(left.register.byte_8 * right.register.byte_8);
1298 product.register.byte_9 = (byte)(left.register.byte_9 * right.register.byte_9);
1299 product.register.byte_10 = (byte)(left.register.byte_10 * right.register.byte_10);
1300 product.register.byte_11 = (byte)(left.register.byte_11 * right.register.byte_11);
1301 product.register.byte_12 = (byte)(left.register.byte_12 * right.register.byte_12);
1302 product.register.byte_13 = (byte)(left.register.byte_13 * right.register.byte_13);
1303 product.register.byte_14 = (byte)(left.register.byte_14 * right.register.byte_14);
1304 product.register.byte_15 = (byte)(left.register.byte_15 * right.register.byte_15);
1306 else if (typeof(T) == typeof(sbyte))
1308 product.register.sbyte_0 = (sbyte)(left.register.sbyte_0 * right.register.sbyte_0);
1309 product.register.sbyte_1 = (sbyte)(left.register.sbyte_1 * right.register.sbyte_1);
1310 product.register.sbyte_2 = (sbyte)(left.register.sbyte_2 * right.register.sbyte_2);
1311 product.register.sbyte_3 = (sbyte)(left.register.sbyte_3 * right.register.sbyte_3);
1312 product.register.sbyte_4 = (sbyte)(left.register.sbyte_4 * right.register.sbyte_4);
1313 product.register.sbyte_5 = (sbyte)(left.register.sbyte_5 * right.register.sbyte_5);
1314 product.register.sbyte_6 = (sbyte)(left.register.sbyte_6 * right.register.sbyte_6);
1315 product.register.sbyte_7 = (sbyte)(left.register.sbyte_7 * right.register.sbyte_7);
1316 product.register.sbyte_8 = (sbyte)(left.register.sbyte_8 * right.register.sbyte_8);
1317 product.register.sbyte_9 = (sbyte)(left.register.sbyte_9 * right.register.sbyte_9);
1318 product.register.sbyte_10 = (sbyte)(left.register.sbyte_10 * right.register.sbyte_10);
1319 product.register.sbyte_11 = (sbyte)(left.register.sbyte_11 * right.register.sbyte_11);
1320 product.register.sbyte_12 = (sbyte)(left.register.sbyte_12 * right.register.sbyte_12);
1321 product.register.sbyte_13 = (sbyte)(left.register.sbyte_13 * right.register.sbyte_13);
1322 product.register.sbyte_14 = (sbyte)(left.register.sbyte_14 * right.register.sbyte_14);
1323 product.register.sbyte_15 = (sbyte)(left.register.sbyte_15 * right.register.sbyte_15);
1325 else if (typeof(T) == typeof(ushort))
1327 product.register.uint16_0 = (ushort)(left.register.uint16_0 * right.register.uint16_0);
1328 product.register.uint16_1 = (ushort)(left.register.uint16_1 * right.register.uint16_1);
1329 product.register.uint16_2 = (ushort)(left.register.uint16_2 * right.register.uint16_2);
1330 product.register.uint16_3 = (ushort)(left.register.uint16_3 * right.register.uint16_3);
1331 product.register.uint16_4 = (ushort)(left.register.uint16_4 * right.register.uint16_4);
1332 product.register.uint16_5 = (ushort)(left.register.uint16_5 * right.register.uint16_5);
1333 product.register.uint16_6 = (ushort)(left.register.uint16_6 * right.register.uint16_6);
1334 product.register.uint16_7 = (ushort)(left.register.uint16_7 * right.register.uint16_7);
1336 else if (typeof(T) == typeof(short))
1338 product.register.int16_0 = (short)(left.register.int16_0 * right.register.int16_0);
1339 product.register.int16_1 = (short)(left.register.int16_1 * right.register.int16_1);
1340 product.register.int16_2 = (short)(left.register.int16_2 * right.register.int16_2);
1341 product.register.int16_3 = (short)(left.register.int16_3 * right.register.int16_3);
1342 product.register.int16_4 = (short)(left.register.int16_4 * right.register.int16_4);
1343 product.register.int16_5 = (short)(left.register.int16_5 * right.register.int16_5);
1344 product.register.int16_6 = (short)(left.register.int16_6 * right.register.int16_6);
1345 product.register.int16_7 = (short)(left.register.int16_7 * right.register.int16_7);
1347 else if (typeof(T) == typeof(uint))
1349 product.register.uint32_0 = (uint)(left.register.uint32_0 * right.register.uint32_0);
1350 product.register.uint32_1 = (uint)(left.register.uint32_1 * right.register.uint32_1);
1351 product.register.uint32_2 = (uint)(left.register.uint32_2 * right.register.uint32_2);
1352 product.register.uint32_3 = (uint)(left.register.uint32_3 * right.register.uint32_3);
1354 else if (typeof(T) == typeof(int))
1356 product.register.int32_0 = (int)(left.register.int32_0 * right.register.int32_0);
1357 product.register.int32_1 = (int)(left.register.int32_1 * right.register.int32_1);
1358 product.register.int32_2 = (int)(left.register.int32_2 * right.register.int32_2);
1359 product.register.int32_3 = (int)(left.register.int32_3 * right.register.int32_3);
1361 else if (typeof(T) == typeof(ulong))
1363 product.register.uint64_0 = (ulong)(left.register.uint64_0 * right.register.uint64_0);
1364 product.register.uint64_1 = (ulong)(left.register.uint64_1 * right.register.uint64_1);
1366 else if (typeof(T) == typeof(long))
1368 product.register.int64_0 = (long)(left.register.int64_0 * right.register.int64_0);
1369 product.register.int64_1 = (long)(left.register.int64_1 * right.register.int64_1);
1371 else if (typeof(T) == typeof(float))
1373 product.register.single_0 = (float)(left.register.single_0 * right.register.single_0);
1374 product.register.single_1 = (float)(left.register.single_1 * right.register.single_1);
1375 product.register.single_2 = (float)(left.register.single_2 * right.register.single_2);
1376 product.register.single_3 = (float)(left.register.single_3 * right.register.single_3);
1378 else if (typeof(T) == typeof(double))
1380 product.register.double_0 = (double)(left.register.double_0 * right.register.double_0);
1381 product.register.double_1 = (double)(left.register.double_1 * right.register.double_1);
1383 return product;
1388 /// <summary>
1389 /// Multiplies a vector by the given scalar.
1390 /// </summary>
1391 /// <param name="value">The source vector.</param>
1392 /// <param name="factor">The scalar value.</param>
1393 /// <returns>The scaled vector.</returns>
1394 [MethodImpl(MethodImplOptions.AggressiveInlining)]
1395 public static Vector<T> operator *(Vector<T> value, T factor) =>
1396 new Vector<T>(factor) * value;
1398 /// <summary>
1399 /// Multiplies a vector by the given scalar.
1400 /// </summary>
1401 /// <param name="factor">The scalar value.</param>
1402 /// <param name="value">The source vector.</param>
1403 /// <returns>The scaled vector.</returns>
1404 [MethodImpl(MethodImplOptions.AggressiveInlining)]
1405 public static Vector<T> operator *(T factor, Vector<T> value) =>
1406 new Vector<T>(factor) * value;
1408 // This method is intrinsic only for certain types. It cannot access fields directly unless we are sure the context is unaccelerated.
1409 /// <summary>
1410 /// Divides the first vector by the second.
1411 /// </summary>
1412 /// <param name="left">The first source vector.</param>
1413 /// <param name="right">The second source vector.</param>
1414 /// <returns>The vector resulting from the division.</returns>
1415 [Intrinsic]
1416 public static unsafe Vector<T> operator /(Vector<T> left, Vector<T> right)
1418 unchecked
1420 if (Vector.IsHardwareAccelerated)
1422 if (typeof(T) == typeof(byte))
1424 byte* dataPtr = stackalloc byte[Count];
1425 for (int g = 0; g < Count; g++)
1427 dataPtr[g] = (byte)(object)ScalarDivide(left[g], right[g]);
1429 return new Vector<T>(dataPtr);
1431 else if (typeof(T) == typeof(sbyte))
1433 sbyte* dataPtr = stackalloc sbyte[Count];
1434 for (int g = 0; g < Count; g++)
1436 dataPtr[g] = (sbyte)(object)ScalarDivide(left[g], right[g]);
1438 return new Vector<T>(dataPtr);
1440 else if (typeof(T) == typeof(ushort))
1442 ushort* dataPtr = stackalloc ushort[Count];
1443 for (int g = 0; g < Count; g++)
1445 dataPtr[g] = (ushort)(object)ScalarDivide(left[g], right[g]);
1447 return new Vector<T>(dataPtr);
1449 else if (typeof(T) == typeof(short))
1451 short* dataPtr = stackalloc short[Count];
1452 for (int g = 0; g < Count; g++)
1454 dataPtr[g] = (short)(object)ScalarDivide(left[g], right[g]);
1456 return new Vector<T>(dataPtr);
1458 else if (typeof(T) == typeof(uint))
1460 uint* dataPtr = stackalloc uint[Count];
1461 for (int g = 0; g < Count; g++)
1463 dataPtr[g] = (uint)(object)ScalarDivide(left[g], right[g]);
1465 return new Vector<T>(dataPtr);
1467 else if (typeof(T) == typeof(int))
1469 int* dataPtr = stackalloc int[Count];
1470 for (int g = 0; g < Count; g++)
1472 dataPtr[g] = (int)(object)ScalarDivide(left[g], right[g]);
1474 return new Vector<T>(dataPtr);
1476 else if (typeof(T) == typeof(ulong))
1478 ulong* dataPtr = stackalloc ulong[Count];
1479 for (int g = 0; g < Count; g++)
1481 dataPtr[g] = (ulong)(object)ScalarDivide(left[g], right[g]);
1483 return new Vector<T>(dataPtr);
1485 else if (typeof(T) == typeof(long))
1487 long* dataPtr = stackalloc long[Count];
1488 for (int g = 0; g < Count; g++)
1490 dataPtr[g] = (long)(object)ScalarDivide(left[g], right[g]);
1492 return new Vector<T>(dataPtr);
1494 else if (typeof(T) == typeof(float))
1496 float* dataPtr = stackalloc float[Count];
1497 for (int g = 0; g < Count; g++)
1499 dataPtr[g] = (float)(object)ScalarDivide(left[g], right[g]);
1501 return new Vector<T>(dataPtr);
1503 else if (typeof(T) == typeof(double))
1505 double* dataPtr = stackalloc double[Count];
1506 for (int g = 0; g < Count; g++)
1508 dataPtr[g] = (double)(object)ScalarDivide(left[g], right[g]);
1510 return new Vector<T>(dataPtr);
1512 else
1514 throw new NotSupportedException(SR.Arg_TypeNotSupported);
1517 else
1519 Vector<T> quotient = new Vector<T>();
1520 if (typeof(T) == typeof(byte))
1522 quotient.register.byte_0 = (byte)(left.register.byte_0 / right.register.byte_0);
1523 quotient.register.byte_1 = (byte)(left.register.byte_1 / right.register.byte_1);
1524 quotient.register.byte_2 = (byte)(left.register.byte_2 / right.register.byte_2);
1525 quotient.register.byte_3 = (byte)(left.register.byte_3 / right.register.byte_3);
1526 quotient.register.byte_4 = (byte)(left.register.byte_4 / right.register.byte_4);
1527 quotient.register.byte_5 = (byte)(left.register.byte_5 / right.register.byte_5);
1528 quotient.register.byte_6 = (byte)(left.register.byte_6 / right.register.byte_6);
1529 quotient.register.byte_7 = (byte)(left.register.byte_7 / right.register.byte_7);
1530 quotient.register.byte_8 = (byte)(left.register.byte_8 / right.register.byte_8);
1531 quotient.register.byte_9 = (byte)(left.register.byte_9 / right.register.byte_9);
1532 quotient.register.byte_10 = (byte)(left.register.byte_10 / right.register.byte_10);
1533 quotient.register.byte_11 = (byte)(left.register.byte_11 / right.register.byte_11);
1534 quotient.register.byte_12 = (byte)(left.register.byte_12 / right.register.byte_12);
1535 quotient.register.byte_13 = (byte)(left.register.byte_13 / right.register.byte_13);
1536 quotient.register.byte_14 = (byte)(left.register.byte_14 / right.register.byte_14);
1537 quotient.register.byte_15 = (byte)(left.register.byte_15 / right.register.byte_15);
1539 else if (typeof(T) == typeof(sbyte))
1541 quotient.register.sbyte_0 = (sbyte)(left.register.sbyte_0 / right.register.sbyte_0);
1542 quotient.register.sbyte_1 = (sbyte)(left.register.sbyte_1 / right.register.sbyte_1);
1543 quotient.register.sbyte_2 = (sbyte)(left.register.sbyte_2 / right.register.sbyte_2);
1544 quotient.register.sbyte_3 = (sbyte)(left.register.sbyte_3 / right.register.sbyte_3);
1545 quotient.register.sbyte_4 = (sbyte)(left.register.sbyte_4 / right.register.sbyte_4);
1546 quotient.register.sbyte_5 = (sbyte)(left.register.sbyte_5 / right.register.sbyte_5);
1547 quotient.register.sbyte_6 = (sbyte)(left.register.sbyte_6 / right.register.sbyte_6);
1548 quotient.register.sbyte_7 = (sbyte)(left.register.sbyte_7 / right.register.sbyte_7);
1549 quotient.register.sbyte_8 = (sbyte)(left.register.sbyte_8 / right.register.sbyte_8);
1550 quotient.register.sbyte_9 = (sbyte)(left.register.sbyte_9 / right.register.sbyte_9);
1551 quotient.register.sbyte_10 = (sbyte)(left.register.sbyte_10 / right.register.sbyte_10);
1552 quotient.register.sbyte_11 = (sbyte)(left.register.sbyte_11 / right.register.sbyte_11);
1553 quotient.register.sbyte_12 = (sbyte)(left.register.sbyte_12 / right.register.sbyte_12);
1554 quotient.register.sbyte_13 = (sbyte)(left.register.sbyte_13 / right.register.sbyte_13);
1555 quotient.register.sbyte_14 = (sbyte)(left.register.sbyte_14 / right.register.sbyte_14);
1556 quotient.register.sbyte_15 = (sbyte)(left.register.sbyte_15 / right.register.sbyte_15);
1558 else if (typeof(T) == typeof(ushort))
1560 quotient.register.uint16_0 = (ushort)(left.register.uint16_0 / right.register.uint16_0);
1561 quotient.register.uint16_1 = (ushort)(left.register.uint16_1 / right.register.uint16_1);
1562 quotient.register.uint16_2 = (ushort)(left.register.uint16_2 / right.register.uint16_2);
1563 quotient.register.uint16_3 = (ushort)(left.register.uint16_3 / right.register.uint16_3);
1564 quotient.register.uint16_4 = (ushort)(left.register.uint16_4 / right.register.uint16_4);
1565 quotient.register.uint16_5 = (ushort)(left.register.uint16_5 / right.register.uint16_5);
1566 quotient.register.uint16_6 = (ushort)(left.register.uint16_6 / right.register.uint16_6);
1567 quotient.register.uint16_7 = (ushort)(left.register.uint16_7 / right.register.uint16_7);
1569 else if (typeof(T) == typeof(short))
1571 quotient.register.int16_0 = (short)(left.register.int16_0 / right.register.int16_0);
1572 quotient.register.int16_1 = (short)(left.register.int16_1 / right.register.int16_1);
1573 quotient.register.int16_2 = (short)(left.register.int16_2 / right.register.int16_2);
1574 quotient.register.int16_3 = (short)(left.register.int16_3 / right.register.int16_3);
1575 quotient.register.int16_4 = (short)(left.register.int16_4 / right.register.int16_4);
1576 quotient.register.int16_5 = (short)(left.register.int16_5 / right.register.int16_5);
1577 quotient.register.int16_6 = (short)(left.register.int16_6 / right.register.int16_6);
1578 quotient.register.int16_7 = (short)(left.register.int16_7 / right.register.int16_7);
1580 else if (typeof(T) == typeof(uint))
1582 quotient.register.uint32_0 = (uint)(left.register.uint32_0 / right.register.uint32_0);
1583 quotient.register.uint32_1 = (uint)(left.register.uint32_1 / right.register.uint32_1);
1584 quotient.register.uint32_2 = (uint)(left.register.uint32_2 / right.register.uint32_2);
1585 quotient.register.uint32_3 = (uint)(left.register.uint32_3 / right.register.uint32_3);
1587 else if (typeof(T) == typeof(int))
1589 quotient.register.int32_0 = (int)(left.register.int32_0 / right.register.int32_0);
1590 quotient.register.int32_1 = (int)(left.register.int32_1 / right.register.int32_1);
1591 quotient.register.int32_2 = (int)(left.register.int32_2 / right.register.int32_2);
1592 quotient.register.int32_3 = (int)(left.register.int32_3 / right.register.int32_3);
1594 else if (typeof(T) == typeof(ulong))
1596 quotient.register.uint64_0 = (ulong)(left.register.uint64_0 / right.register.uint64_0);
1597 quotient.register.uint64_1 = (ulong)(left.register.uint64_1 / right.register.uint64_1);
1599 else if (typeof(T) == typeof(long))
1601 quotient.register.int64_0 = (long)(left.register.int64_0 / right.register.int64_0);
1602 quotient.register.int64_1 = (long)(left.register.int64_1 / right.register.int64_1);
1604 else if (typeof(T) == typeof(float))
1606 quotient.register.single_0 = (float)(left.register.single_0 / right.register.single_0);
1607 quotient.register.single_1 = (float)(left.register.single_1 / right.register.single_1);
1608 quotient.register.single_2 = (float)(left.register.single_2 / right.register.single_2);
1609 quotient.register.single_3 = (float)(left.register.single_3 / right.register.single_3);
1611 else if (typeof(T) == typeof(double))
1613 quotient.register.double_0 = (double)(left.register.double_0 / right.register.double_0);
1614 quotient.register.double_1 = (double)(left.register.double_1 / right.register.double_1);
1616 return quotient;
1621 /// <summary>
1622 /// Negates a given vector.
1623 /// </summary>
1624 /// <param name="value">The source vector.</param>
1625 /// <returns>The negated vector.</returns>
1626 public static Vector<T> operator -(Vector<T> value) => Zero - value;
1627 #endregion Arithmetic Operators
1629 #region Bitwise Operators
1630 /// <summary>
1631 /// Returns a new vector by performing a bitwise-and operation on each of the elements in the given vectors.
1632 /// </summary>
1633 /// <param name="left">The first source vector.</param>
1634 /// <param name="right">The second source vector.</param>
1635 /// <returns>The resultant vector.</returns>
1636 [Intrinsic]
1637 public static unsafe Vector<T> operator &(Vector<T> left, Vector<T> right)
1639 Vector<T> result = new Vector<T>();
1640 unchecked
1642 if (Vector.IsHardwareAccelerated)
1644 long* resultBase = &result.register.int64_0;
1645 long* leftBase = &left.register.int64_0;
1646 long* rightBase = &right.register.int64_0;
1647 for (int g = 0; g < Vector<long>.Count; g++)
1649 resultBase[g] = leftBase[g] & rightBase[g];
1652 else
1654 result.register.int64_0 = left.register.int64_0 & right.register.int64_0;
1655 result.register.int64_1 = left.register.int64_1 & right.register.int64_1;
1658 return result;
1661 /// <summary>
1662 /// Returns a new vector by performing a bitwise-or operation on each of the elements in the given vectors.
1663 /// </summary>
1664 /// <param name="left">The first source vector.</param>
1665 /// <param name="right">The second source vector.</param>
1666 /// <returns>The resultant vector.</returns>
1667 [Intrinsic]
1668 public static unsafe Vector<T> operator |(Vector<T> left, Vector<T> right)
1670 Vector<T> result = new Vector<T>();
1671 unchecked
1673 if (Vector.IsHardwareAccelerated)
1675 long* resultBase = &result.register.int64_0;
1676 long* leftBase = &left.register.int64_0;
1677 long* rightBase = &right.register.int64_0;
1678 for (int g = 0; g < Vector<long>.Count; g++)
1680 resultBase[g] = leftBase[g] | rightBase[g];
1683 else
1685 result.register.int64_0 = left.register.int64_0 | right.register.int64_0;
1686 result.register.int64_1 = left.register.int64_1 | right.register.int64_1;
1689 return result;
1692 /// <summary>
1693 /// Returns a new vector by performing a bitwise-exclusive-or operation on each of the elements in the given vectors.
1694 /// </summary>
1695 /// <param name="left">The first source vector.</param>
1696 /// <param name="right">The second source vector.</param>
1697 /// <returns>The resultant vector.</returns>
1698 [Intrinsic]
1699 public static unsafe Vector<T> operator ^(Vector<T> left, Vector<T> right)
1701 Vector<T> result = new Vector<T>();
1702 unchecked
1704 if (Vector.IsHardwareAccelerated)
1706 long* resultBase = &result.register.int64_0;
1707 long* leftBase = &left.register.int64_0;
1708 long* rightBase = &right.register.int64_0;
1709 for (int g = 0; g < Vector<long>.Count; g++)
1711 resultBase[g] = leftBase[g] ^ rightBase[g];
1714 else
1716 result.register.int64_0 = left.register.int64_0 ^ right.register.int64_0;
1717 result.register.int64_1 = left.register.int64_1 ^ right.register.int64_1;
1720 return result;
1723 /// <summary>
1724 /// Returns a new vector whose elements are obtained by taking the one's complement of the given vector's elements.
1725 /// </summary>
1726 /// <param name="value">The source vector.</param>
1727 /// <returns>The one's complement vector.</returns>
1728 [MethodImpl(MethodImplOptions.AggressiveInlining)]
1729 public static Vector<T> operator ~(Vector<T> value) =>
1730 s_allOnes ^ value;
1731 #endregion Bitwise Operators
1733 #region Logical Operators
1734 /// <summary>
1735 /// Returns a boolean indicating whether each pair of elements in the given vectors are equal.
1736 /// </summary>
1737 /// <param name="left">The first vector to compare.</param>
1738 /// <param name="right">The first vector to compare.</param>
1739 /// <returns>True if all elements are equal; False otherwise.</returns>
1740 [Intrinsic]
1741 [MethodImpl(MethodImplOptions.AggressiveInlining)]
1742 public static bool operator ==(Vector<T> left, Vector<T> right) =>
1743 left.Equals(right);
1745 /// <summary>
1746 /// Returns a boolean indicating whether any single pair of elements in the given vectors are not equal.
1747 /// </summary>
1748 /// <param name="left">The first vector to compare.</param>
1749 /// <param name="right">The second vector to compare.</param>
1750 /// <returns>True if left and right are not equal; False otherwise.</returns>
1751 [Intrinsic]
1752 [MethodImpl(MethodImplOptions.AggressiveInlining)]
1753 public static bool operator !=(Vector<T> left, Vector<T> right) => !(left == right);
1754 #endregion Logical Operators
1756 #region Conversions
1757 /// <summary>
1758 /// Reinterprets the bits of the given vector into those of another type.
1759 /// </summary>
1760 /// <param name="value">The source vector</param>
1761 /// <returns>The reinterpreted vector.</returns>
1762 [Intrinsic]
1763 public static explicit operator Vector<byte>(Vector<T> value) =>
1764 new Vector<byte>(ref value.register);
1766 /// <summary>
1767 /// Reinterprets the bits of the given vector into those of another type.
1768 /// </summary>
1769 /// <param name="value">The source vector</param>
1770 /// <returns>The reinterpreted vector.</returns>
1771 [CLSCompliant(false)]
1772 [Intrinsic]
1773 public static explicit operator Vector<sbyte>(Vector<T> value) =>
1774 new Vector<sbyte>(ref value.register);
1776 /// <summary>
1777 /// Reinterprets the bits of the given vector into those of another type.
1778 /// </summary>
1779 /// <param name="value">The source vector</param>
1780 /// <returns>The reinterpreted vector.</returns>
1781 [CLSCompliant(false)]
1782 [Intrinsic]
1783 public static explicit operator Vector<ushort>(Vector<T> value) =>
1784 new Vector<ushort>(ref value.register);
1786 /// <summary>
1787 /// Reinterprets the bits of the given vector into those of another type.
1788 /// </summary>
1789 /// <param name="value">The source vector</param>
1790 /// <returns>The reinterpreted vector.</returns>
1791 [Intrinsic]
1792 public static explicit operator Vector<short>(Vector<T> value) =>
1793 new Vector<short>(ref value.register);
1795 /// <summary>
1796 /// Reinterprets the bits of the given vector into those of another type.
1797 /// </summary>
1798 /// <param name="value">The source vector</param>
1799 /// <returns>The reinterpreted vector.</returns>
1800 [CLSCompliant(false)]
1801 [Intrinsic]
1802 public static explicit operator Vector<uint>(Vector<T> value) =>
1803 new Vector<uint>(ref value.register);
1805 /// <summary>
1806 /// Reinterprets the bits of the given vector into those of another type.
1807 /// </summary>
1808 /// <param name="value">The source vector</param>
1809 /// <returns>The reinterpreted vector.</returns>
1810 [Intrinsic]
1811 public static explicit operator Vector<int>(Vector<T> value) =>
1812 new Vector<int>(ref value.register);
1814 /// <summary>
1815 /// Reinterprets the bits of the given vector into those of another type.
1816 /// </summary>
1817 /// <param name="value">The source vector</param>
1818 /// <returns>The reinterpreted vector.</returns>
1819 [CLSCompliant(false)]
1820 [Intrinsic]
1821 public static explicit operator Vector<ulong>(Vector<T> value) =>
1822 new Vector<ulong>(ref value.register);
1824 /// <summary>
1825 /// Reinterprets the bits of the given vector into those of another type.
1826 /// </summary>
1827 /// <param name="value">The source vector</param>
1828 /// <returns>The reinterpreted vector.</returns>
1829 [Intrinsic]
1830 public static explicit operator Vector<long>(Vector<T> value) =>
1831 new Vector<long>(ref value.register);
1833 /// <summary>
1834 /// Reinterprets the bits of the given vector into those of another type.
1835 /// </summary>
1836 /// <param name="value">The source vector</param>
1837 /// <returns>The reinterpreted vector.</returns>
1838 [Intrinsic]
1839 public static explicit operator Vector<float>(Vector<T> value) =>
1840 new Vector<float>(ref value.register);
1842 /// <summary>
1843 /// Reinterprets the bits of the given vector into those of another type.
1844 /// </summary>
1845 /// <param name="value">The source vector</param>
1846 /// <returns>The reinterpreted vector.</returns>
1847 [Intrinsic]
1848 public static explicit operator Vector<double>(Vector<T> value) =>
1849 new Vector<double>(ref value.register);
1851 #endregion Conversions
1853 #region Internal Comparison Methods
1854 [Intrinsic]
1855 [MethodImpl(MethodImplOptions.AggressiveInlining)]
1856 internal static unsafe Vector<T> Equals(Vector<T> left, Vector<T> right)
1858 if (Vector.IsHardwareAccelerated)
1860 if (typeof(T) == typeof(byte))
1862 byte* dataPtr = stackalloc byte[Count];
1863 for (int g = 0; g < Count; g++)
1865 dataPtr[g] = ScalarEquals(left[g], right[g]) ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
1867 return new Vector<T>(dataPtr);
1869 else if (typeof(T) == typeof(sbyte))
1871 sbyte* dataPtr = stackalloc sbyte[Count];
1872 for (int g = 0; g < Count; g++)
1874 dataPtr[g] = ScalarEquals(left[g], right[g]) ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
1876 return new Vector<T>(dataPtr);
1878 else if (typeof(T) == typeof(ushort))
1880 ushort* dataPtr = stackalloc ushort[Count];
1881 for (int g = 0; g < Count; g++)
1883 dataPtr[g] = ScalarEquals(left[g], right[g]) ? ConstantHelper.GetUInt16WithAllBitsSet() : (ushort)0;
1885 return new Vector<T>(dataPtr);
1887 else if (typeof(T) == typeof(short))
1889 short* dataPtr = stackalloc short[Count];
1890 for (int g = 0; g < Count; g++)
1892 dataPtr[g] = ScalarEquals(left[g], right[g]) ? ConstantHelper.GetInt16WithAllBitsSet() : (short)0;
1894 return new Vector<T>(dataPtr);
1896 else if (typeof(T) == typeof(uint))
1898 uint* dataPtr = stackalloc uint[Count];
1899 for (int g = 0; g < Count; g++)
1901 dataPtr[g] = ScalarEquals(left[g], right[g]) ? ConstantHelper.GetUInt32WithAllBitsSet() : (uint)0;
1903 return new Vector<T>(dataPtr);
1905 else if (typeof(T) == typeof(int))
1907 int* dataPtr = stackalloc int[Count];
1908 for (int g = 0; g < Count; g++)
1910 dataPtr[g] = ScalarEquals(left[g], right[g]) ? ConstantHelper.GetInt32WithAllBitsSet() : (int)0;
1912 return new Vector<T>(dataPtr);
1914 else if (typeof(T) == typeof(ulong))
1916 ulong* dataPtr = stackalloc ulong[Count];
1917 for (int g = 0; g < Count; g++)
1919 dataPtr[g] = ScalarEquals(left[g], right[g]) ? ConstantHelper.GetUInt64WithAllBitsSet() : (ulong)0;
1921 return new Vector<T>(dataPtr);
1923 else if (typeof(T) == typeof(long))
1925 long* dataPtr = stackalloc long[Count];
1926 for (int g = 0; g < Count; g++)
1928 dataPtr[g] = ScalarEquals(left[g], right[g]) ? ConstantHelper.GetInt64WithAllBitsSet() : (long)0;
1930 return new Vector<T>(dataPtr);
1932 else if (typeof(T) == typeof(float))
1934 float* dataPtr = stackalloc float[Count];
1935 for (int g = 0; g < Count; g++)
1937 dataPtr[g] = ScalarEquals(left[g], right[g]) ? ConstantHelper.GetSingleWithAllBitsSet() : (float)0;
1939 return new Vector<T>(dataPtr);
1941 else if (typeof(T) == typeof(double))
1943 double* dataPtr = stackalloc double[Count];
1944 for (int g = 0; g < Count; g++)
1946 dataPtr[g] = ScalarEquals(left[g], right[g]) ? ConstantHelper.GetDoubleWithAllBitsSet() : (double)0;
1948 return new Vector<T>(dataPtr);
1950 else
1952 throw new NotSupportedException(SR.Arg_TypeNotSupported);
1955 else
1957 Register register = new Register();
1958 if (typeof(T) == typeof(byte))
1960 register.byte_0 = left.register.byte_0 == right.register.byte_0 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
1961 register.byte_1 = left.register.byte_1 == right.register.byte_1 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
1962 register.byte_2 = left.register.byte_2 == right.register.byte_2 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
1963 register.byte_3 = left.register.byte_3 == right.register.byte_3 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
1964 register.byte_4 = left.register.byte_4 == right.register.byte_4 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
1965 register.byte_5 = left.register.byte_5 == right.register.byte_5 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
1966 register.byte_6 = left.register.byte_6 == right.register.byte_6 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
1967 register.byte_7 = left.register.byte_7 == right.register.byte_7 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
1968 register.byte_8 = left.register.byte_8 == right.register.byte_8 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
1969 register.byte_9 = left.register.byte_9 == right.register.byte_9 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
1970 register.byte_10 = left.register.byte_10 == right.register.byte_10 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
1971 register.byte_11 = left.register.byte_11 == right.register.byte_11 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
1972 register.byte_12 = left.register.byte_12 == right.register.byte_12 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
1973 register.byte_13 = left.register.byte_13 == right.register.byte_13 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
1974 register.byte_14 = left.register.byte_14 == right.register.byte_14 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
1975 register.byte_15 = left.register.byte_15 == right.register.byte_15 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
1976 return new Vector<T>(ref register);
1978 else if (typeof(T) == typeof(sbyte))
1980 register.sbyte_0 = left.register.sbyte_0 == right.register.sbyte_0 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
1981 register.sbyte_1 = left.register.sbyte_1 == right.register.sbyte_1 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
1982 register.sbyte_2 = left.register.sbyte_2 == right.register.sbyte_2 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
1983 register.sbyte_3 = left.register.sbyte_3 == right.register.sbyte_3 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
1984 register.sbyte_4 = left.register.sbyte_4 == right.register.sbyte_4 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
1985 register.sbyte_5 = left.register.sbyte_5 == right.register.sbyte_5 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
1986 register.sbyte_6 = left.register.sbyte_6 == right.register.sbyte_6 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
1987 register.sbyte_7 = left.register.sbyte_7 == right.register.sbyte_7 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
1988 register.sbyte_8 = left.register.sbyte_8 == right.register.sbyte_8 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
1989 register.sbyte_9 = left.register.sbyte_9 == right.register.sbyte_9 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
1990 register.sbyte_10 = left.register.sbyte_10 == right.register.sbyte_10 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
1991 register.sbyte_11 = left.register.sbyte_11 == right.register.sbyte_11 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
1992 register.sbyte_12 = left.register.sbyte_12 == right.register.sbyte_12 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
1993 register.sbyte_13 = left.register.sbyte_13 == right.register.sbyte_13 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
1994 register.sbyte_14 = left.register.sbyte_14 == right.register.sbyte_14 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
1995 register.sbyte_15 = left.register.sbyte_15 == right.register.sbyte_15 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
1996 return new Vector<T>(ref register);
1998 else if (typeof(T) == typeof(ushort))
2000 register.uint16_0 = left.register.uint16_0 == right.register.uint16_0 ? ConstantHelper.GetUInt16WithAllBitsSet() : (ushort)0;
2001 register.uint16_1 = left.register.uint16_1 == right.register.uint16_1 ? ConstantHelper.GetUInt16WithAllBitsSet() : (ushort)0;
2002 register.uint16_2 = left.register.uint16_2 == right.register.uint16_2 ? ConstantHelper.GetUInt16WithAllBitsSet() : (ushort)0;
2003 register.uint16_3 = left.register.uint16_3 == right.register.uint16_3 ? ConstantHelper.GetUInt16WithAllBitsSet() : (ushort)0;
2004 register.uint16_4 = left.register.uint16_4 == right.register.uint16_4 ? ConstantHelper.GetUInt16WithAllBitsSet() : (ushort)0;
2005 register.uint16_5 = left.register.uint16_5 == right.register.uint16_5 ? ConstantHelper.GetUInt16WithAllBitsSet() : (ushort)0;
2006 register.uint16_6 = left.register.uint16_6 == right.register.uint16_6 ? ConstantHelper.GetUInt16WithAllBitsSet() : (ushort)0;
2007 register.uint16_7 = left.register.uint16_7 == right.register.uint16_7 ? ConstantHelper.GetUInt16WithAllBitsSet() : (ushort)0;
2008 return new Vector<T>(ref register);
2010 else if (typeof(T) == typeof(short))
2012 register.int16_0 = left.register.int16_0 == right.register.int16_0 ? ConstantHelper.GetInt16WithAllBitsSet() : (short)0;
2013 register.int16_1 = left.register.int16_1 == right.register.int16_1 ? ConstantHelper.GetInt16WithAllBitsSet() : (short)0;
2014 register.int16_2 = left.register.int16_2 == right.register.int16_2 ? ConstantHelper.GetInt16WithAllBitsSet() : (short)0;
2015 register.int16_3 = left.register.int16_3 == right.register.int16_3 ? ConstantHelper.GetInt16WithAllBitsSet() : (short)0;
2016 register.int16_4 = left.register.int16_4 == right.register.int16_4 ? ConstantHelper.GetInt16WithAllBitsSet() : (short)0;
2017 register.int16_5 = left.register.int16_5 == right.register.int16_5 ? ConstantHelper.GetInt16WithAllBitsSet() : (short)0;
2018 register.int16_6 = left.register.int16_6 == right.register.int16_6 ? ConstantHelper.GetInt16WithAllBitsSet() : (short)0;
2019 register.int16_7 = left.register.int16_7 == right.register.int16_7 ? ConstantHelper.GetInt16WithAllBitsSet() : (short)0;
2020 return new Vector<T>(ref register);
2022 else if (typeof(T) == typeof(uint))
2024 register.uint32_0 = left.register.uint32_0 == right.register.uint32_0 ? ConstantHelper.GetUInt32WithAllBitsSet() : (uint)0;
2025 register.uint32_1 = left.register.uint32_1 == right.register.uint32_1 ? ConstantHelper.GetUInt32WithAllBitsSet() : (uint)0;
2026 register.uint32_2 = left.register.uint32_2 == right.register.uint32_2 ? ConstantHelper.GetUInt32WithAllBitsSet() : (uint)0;
2027 register.uint32_3 = left.register.uint32_3 == right.register.uint32_3 ? ConstantHelper.GetUInt32WithAllBitsSet() : (uint)0;
2028 return new Vector<T>(ref register);
2030 else if (typeof(T) == typeof(int))
2032 register.int32_0 = left.register.int32_0 == right.register.int32_0 ? ConstantHelper.GetInt32WithAllBitsSet() : (int)0;
2033 register.int32_1 = left.register.int32_1 == right.register.int32_1 ? ConstantHelper.GetInt32WithAllBitsSet() : (int)0;
2034 register.int32_2 = left.register.int32_2 == right.register.int32_2 ? ConstantHelper.GetInt32WithAllBitsSet() : (int)0;
2035 register.int32_3 = left.register.int32_3 == right.register.int32_3 ? ConstantHelper.GetInt32WithAllBitsSet() : (int)0;
2036 return new Vector<T>(ref register);
2038 else if (typeof(T) == typeof(ulong))
2040 register.uint64_0 = left.register.uint64_0 == right.register.uint64_0 ? ConstantHelper.GetUInt64WithAllBitsSet() : (ulong)0;
2041 register.uint64_1 = left.register.uint64_1 == right.register.uint64_1 ? ConstantHelper.GetUInt64WithAllBitsSet() : (ulong)0;
2042 return new Vector<T>(ref register);
2044 else if (typeof(T) == typeof(long))
2046 register.int64_0 = left.register.int64_0 == right.register.int64_0 ? ConstantHelper.GetInt64WithAllBitsSet() : (long)0;
2047 register.int64_1 = left.register.int64_1 == right.register.int64_1 ? ConstantHelper.GetInt64WithAllBitsSet() : (long)0;
2048 return new Vector<T>(ref register);
2050 else if (typeof(T) == typeof(float))
2052 register.single_0 = left.register.single_0 == right.register.single_0 ? ConstantHelper.GetSingleWithAllBitsSet() : (float)0;
2053 register.single_1 = left.register.single_1 == right.register.single_1 ? ConstantHelper.GetSingleWithAllBitsSet() : (float)0;
2054 register.single_2 = left.register.single_2 == right.register.single_2 ? ConstantHelper.GetSingleWithAllBitsSet() : (float)0;
2055 register.single_3 = left.register.single_3 == right.register.single_3 ? ConstantHelper.GetSingleWithAllBitsSet() : (float)0;
2056 return new Vector<T>(ref register);
2058 else if (typeof(T) == typeof(double))
2060 register.double_0 = left.register.double_0 == right.register.double_0 ? ConstantHelper.GetDoubleWithAllBitsSet() : (double)0;
2061 register.double_1 = left.register.double_1 == right.register.double_1 ? ConstantHelper.GetDoubleWithAllBitsSet() : (double)0;
2062 return new Vector<T>(ref register);
2064 else
2066 throw new NotSupportedException(SR.Arg_TypeNotSupported);
2071 [Intrinsic]
2072 [MethodImpl(MethodImplOptions.AggressiveInlining)]
2073 internal static unsafe Vector<T> LessThan(Vector<T> left, Vector<T> right)
2075 if (Vector.IsHardwareAccelerated)
2077 if (typeof(T) == typeof(byte))
2079 byte* dataPtr = stackalloc byte[Count];
2080 for (int g = 0; g < Count; g++)
2082 dataPtr[g] = ScalarLessThan(left[g], right[g]) ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
2084 return new Vector<T>(dataPtr);
2086 else if (typeof(T) == typeof(sbyte))
2088 sbyte* dataPtr = stackalloc sbyte[Count];
2089 for (int g = 0; g < Count; g++)
2091 dataPtr[g] = ScalarLessThan(left[g], right[g]) ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
2093 return new Vector<T>(dataPtr);
2095 else if (typeof(T) == typeof(ushort))
2097 ushort* dataPtr = stackalloc ushort[Count];
2098 for (int g = 0; g < Count; g++)
2100 dataPtr[g] = ScalarLessThan(left[g], right[g]) ? ConstantHelper.GetUInt16WithAllBitsSet() : (ushort)0;
2102 return new Vector<T>(dataPtr);
2104 else if (typeof(T) == typeof(short))
2106 short* dataPtr = stackalloc short[Count];
2107 for (int g = 0; g < Count; g++)
2109 dataPtr[g] = ScalarLessThan(left[g], right[g]) ? ConstantHelper.GetInt16WithAllBitsSet() : (short)0;
2111 return new Vector<T>(dataPtr);
2113 else if (typeof(T) == typeof(uint))
2115 uint* dataPtr = stackalloc uint[Count];
2116 for (int g = 0; g < Count; g++)
2118 dataPtr[g] = ScalarLessThan(left[g], right[g]) ? ConstantHelper.GetUInt32WithAllBitsSet() : (uint)0;
2120 return new Vector<T>(dataPtr);
2122 else if (typeof(T) == typeof(int))
2124 int* dataPtr = stackalloc int[Count];
2125 for (int g = 0; g < Count; g++)
2127 dataPtr[g] = ScalarLessThan(left[g], right[g]) ? ConstantHelper.GetInt32WithAllBitsSet() : (int)0;
2129 return new Vector<T>(dataPtr);
2131 else if (typeof(T) == typeof(ulong))
2133 ulong* dataPtr = stackalloc ulong[Count];
2134 for (int g = 0; g < Count; g++)
2136 dataPtr[g] = ScalarLessThan(left[g], right[g]) ? ConstantHelper.GetUInt64WithAllBitsSet() : (ulong)0;
2138 return new Vector<T>(dataPtr);
2140 else if (typeof(T) == typeof(long))
2142 long* dataPtr = stackalloc long[Count];
2143 for (int g = 0; g < Count; g++)
2145 dataPtr[g] = ScalarLessThan(left[g], right[g]) ? ConstantHelper.GetInt64WithAllBitsSet() : (long)0;
2147 return new Vector<T>(dataPtr);
2149 else if (typeof(T) == typeof(float))
2151 float* dataPtr = stackalloc float[Count];
2152 for (int g = 0; g < Count; g++)
2154 dataPtr[g] = ScalarLessThan(left[g], right[g]) ? ConstantHelper.GetSingleWithAllBitsSet() : (float)0;
2156 return new Vector<T>(dataPtr);
2158 else if (typeof(T) == typeof(double))
2160 double* dataPtr = stackalloc double[Count];
2161 for (int g = 0; g < Count; g++)
2163 dataPtr[g] = ScalarLessThan(left[g], right[g]) ? ConstantHelper.GetDoubleWithAllBitsSet() : (double)0;
2165 return new Vector<T>(dataPtr);
2167 else
2169 throw new NotSupportedException(SR.Arg_TypeNotSupported);
2172 else
2174 Register register = new Register();
2175 if (typeof(T) == typeof(byte))
2177 register.byte_0 = left.register.byte_0 < right.register.byte_0 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
2178 register.byte_1 = left.register.byte_1 < right.register.byte_1 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
2179 register.byte_2 = left.register.byte_2 < right.register.byte_2 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
2180 register.byte_3 = left.register.byte_3 < right.register.byte_3 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
2181 register.byte_4 = left.register.byte_4 < right.register.byte_4 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
2182 register.byte_5 = left.register.byte_5 < right.register.byte_5 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
2183 register.byte_6 = left.register.byte_6 < right.register.byte_6 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
2184 register.byte_7 = left.register.byte_7 < right.register.byte_7 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
2185 register.byte_8 = left.register.byte_8 < right.register.byte_8 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
2186 register.byte_9 = left.register.byte_9 < right.register.byte_9 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
2187 register.byte_10 = left.register.byte_10 < right.register.byte_10 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
2188 register.byte_11 = left.register.byte_11 < right.register.byte_11 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
2189 register.byte_12 = left.register.byte_12 < right.register.byte_12 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
2190 register.byte_13 = left.register.byte_13 < right.register.byte_13 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
2191 register.byte_14 = left.register.byte_14 < right.register.byte_14 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
2192 register.byte_15 = left.register.byte_15 < right.register.byte_15 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
2193 return new Vector<T>(ref register);
2195 else if (typeof(T) == typeof(sbyte))
2197 register.sbyte_0 = left.register.sbyte_0 < right.register.sbyte_0 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
2198 register.sbyte_1 = left.register.sbyte_1 < right.register.sbyte_1 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
2199 register.sbyte_2 = left.register.sbyte_2 < right.register.sbyte_2 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
2200 register.sbyte_3 = left.register.sbyte_3 < right.register.sbyte_3 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
2201 register.sbyte_4 = left.register.sbyte_4 < right.register.sbyte_4 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
2202 register.sbyte_5 = left.register.sbyte_5 < right.register.sbyte_5 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
2203 register.sbyte_6 = left.register.sbyte_6 < right.register.sbyte_6 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
2204 register.sbyte_7 = left.register.sbyte_7 < right.register.sbyte_7 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
2205 register.sbyte_8 = left.register.sbyte_8 < right.register.sbyte_8 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
2206 register.sbyte_9 = left.register.sbyte_9 < right.register.sbyte_9 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
2207 register.sbyte_10 = left.register.sbyte_10 < right.register.sbyte_10 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
2208 register.sbyte_11 = left.register.sbyte_11 < right.register.sbyte_11 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
2209 register.sbyte_12 = left.register.sbyte_12 < right.register.sbyte_12 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
2210 register.sbyte_13 = left.register.sbyte_13 < right.register.sbyte_13 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
2211 register.sbyte_14 = left.register.sbyte_14 < right.register.sbyte_14 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
2212 register.sbyte_15 = left.register.sbyte_15 < right.register.sbyte_15 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
2213 return new Vector<T>(ref register);
2215 else if (typeof(T) == typeof(ushort))
2217 register.uint16_0 = left.register.uint16_0 < right.register.uint16_0 ? ConstantHelper.GetUInt16WithAllBitsSet() : (ushort)0;
2218 register.uint16_1 = left.register.uint16_1 < right.register.uint16_1 ? ConstantHelper.GetUInt16WithAllBitsSet() : (ushort)0;
2219 register.uint16_2 = left.register.uint16_2 < right.register.uint16_2 ? ConstantHelper.GetUInt16WithAllBitsSet() : (ushort)0;
2220 register.uint16_3 = left.register.uint16_3 < right.register.uint16_3 ? ConstantHelper.GetUInt16WithAllBitsSet() : (ushort)0;
2221 register.uint16_4 = left.register.uint16_4 < right.register.uint16_4 ? ConstantHelper.GetUInt16WithAllBitsSet() : (ushort)0;
2222 register.uint16_5 = left.register.uint16_5 < right.register.uint16_5 ? ConstantHelper.GetUInt16WithAllBitsSet() : (ushort)0;
2223 register.uint16_6 = left.register.uint16_6 < right.register.uint16_6 ? ConstantHelper.GetUInt16WithAllBitsSet() : (ushort)0;
2224 register.uint16_7 = left.register.uint16_7 < right.register.uint16_7 ? ConstantHelper.GetUInt16WithAllBitsSet() : (ushort)0;
2225 return new Vector<T>(ref register);
2227 else if (typeof(T) == typeof(short))
2229 register.int16_0 = left.register.int16_0 < right.register.int16_0 ? ConstantHelper.GetInt16WithAllBitsSet() : (short)0;
2230 register.int16_1 = left.register.int16_1 < right.register.int16_1 ? ConstantHelper.GetInt16WithAllBitsSet() : (short)0;
2231 register.int16_2 = left.register.int16_2 < right.register.int16_2 ? ConstantHelper.GetInt16WithAllBitsSet() : (short)0;
2232 register.int16_3 = left.register.int16_3 < right.register.int16_3 ? ConstantHelper.GetInt16WithAllBitsSet() : (short)0;
2233 register.int16_4 = left.register.int16_4 < right.register.int16_4 ? ConstantHelper.GetInt16WithAllBitsSet() : (short)0;
2234 register.int16_5 = left.register.int16_5 < right.register.int16_5 ? ConstantHelper.GetInt16WithAllBitsSet() : (short)0;
2235 register.int16_6 = left.register.int16_6 < right.register.int16_6 ? ConstantHelper.GetInt16WithAllBitsSet() : (short)0;
2236 register.int16_7 = left.register.int16_7 < right.register.int16_7 ? ConstantHelper.GetInt16WithAllBitsSet() : (short)0;
2237 return new Vector<T>(ref register);
2239 else if (typeof(T) == typeof(uint))
2241 register.uint32_0 = left.register.uint32_0 < right.register.uint32_0 ? ConstantHelper.GetUInt32WithAllBitsSet() : (uint)0;
2242 register.uint32_1 = left.register.uint32_1 < right.register.uint32_1 ? ConstantHelper.GetUInt32WithAllBitsSet() : (uint)0;
2243 register.uint32_2 = left.register.uint32_2 < right.register.uint32_2 ? ConstantHelper.GetUInt32WithAllBitsSet() : (uint)0;
2244 register.uint32_3 = left.register.uint32_3 < right.register.uint32_3 ? ConstantHelper.GetUInt32WithAllBitsSet() : (uint)0;
2245 return new Vector<T>(ref register);
2247 else if (typeof(T) == typeof(int))
2249 register.int32_0 = left.register.int32_0 < right.register.int32_0 ? ConstantHelper.GetInt32WithAllBitsSet() : (int)0;
2250 register.int32_1 = left.register.int32_1 < right.register.int32_1 ? ConstantHelper.GetInt32WithAllBitsSet() : (int)0;
2251 register.int32_2 = left.register.int32_2 < right.register.int32_2 ? ConstantHelper.GetInt32WithAllBitsSet() : (int)0;
2252 register.int32_3 = left.register.int32_3 < right.register.int32_3 ? ConstantHelper.GetInt32WithAllBitsSet() : (int)0;
2253 return new Vector<T>(ref register);
2255 else if (typeof(T) == typeof(ulong))
2257 register.uint64_0 = left.register.uint64_0 < right.register.uint64_0 ? ConstantHelper.GetUInt64WithAllBitsSet() : (ulong)0;
2258 register.uint64_1 = left.register.uint64_1 < right.register.uint64_1 ? ConstantHelper.GetUInt64WithAllBitsSet() : (ulong)0;
2259 return new Vector<T>(ref register);
2261 else if (typeof(T) == typeof(long))
2263 register.int64_0 = left.register.int64_0 < right.register.int64_0 ? ConstantHelper.GetInt64WithAllBitsSet() : (long)0;
2264 register.int64_1 = left.register.int64_1 < right.register.int64_1 ? ConstantHelper.GetInt64WithAllBitsSet() : (long)0;
2265 return new Vector<T>(ref register);
2267 else if (typeof(T) == typeof(float))
2269 register.single_0 = left.register.single_0 < right.register.single_0 ? ConstantHelper.GetSingleWithAllBitsSet() : (float)0;
2270 register.single_1 = left.register.single_1 < right.register.single_1 ? ConstantHelper.GetSingleWithAllBitsSet() : (float)0;
2271 register.single_2 = left.register.single_2 < right.register.single_2 ? ConstantHelper.GetSingleWithAllBitsSet() : (float)0;
2272 register.single_3 = left.register.single_3 < right.register.single_3 ? ConstantHelper.GetSingleWithAllBitsSet() : (float)0;
2273 return new Vector<T>(ref register);
2275 else if (typeof(T) == typeof(double))
2277 register.double_0 = left.register.double_0 < right.register.double_0 ? ConstantHelper.GetDoubleWithAllBitsSet() : (double)0;
2278 register.double_1 = left.register.double_1 < right.register.double_1 ? ConstantHelper.GetDoubleWithAllBitsSet() : (double)0;
2279 return new Vector<T>(ref register);
2281 else
2283 throw new NotSupportedException(SR.Arg_TypeNotSupported);
2288 [Intrinsic]
2289 [MethodImpl(MethodImplOptions.AggressiveInlining)]
2290 internal static unsafe Vector<T> GreaterThan(Vector<T> left, Vector<T> right)
2292 if (Vector.IsHardwareAccelerated)
2294 if (typeof(T) == typeof(byte))
2296 byte* dataPtr = stackalloc byte[Count];
2297 for (int g = 0; g < Count; g++)
2299 dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
2301 return new Vector<T>(dataPtr);
2303 else if (typeof(T) == typeof(sbyte))
2305 sbyte* dataPtr = stackalloc sbyte[Count];
2306 for (int g = 0; g < Count; g++)
2308 dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
2310 return new Vector<T>(dataPtr);
2312 else if (typeof(T) == typeof(ushort))
2314 ushort* dataPtr = stackalloc ushort[Count];
2315 for (int g = 0; g < Count; g++)
2317 dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? ConstantHelper.GetUInt16WithAllBitsSet() : (ushort)0;
2319 return new Vector<T>(dataPtr);
2321 else if (typeof(T) == typeof(short))
2323 short* dataPtr = stackalloc short[Count];
2324 for (int g = 0; g < Count; g++)
2326 dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? ConstantHelper.GetInt16WithAllBitsSet() : (short)0;
2328 return new Vector<T>(dataPtr);
2330 else if (typeof(T) == typeof(uint))
2332 uint* dataPtr = stackalloc uint[Count];
2333 for (int g = 0; g < Count; g++)
2335 dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? ConstantHelper.GetUInt32WithAllBitsSet() : (uint)0;
2337 return new Vector<T>(dataPtr);
2339 else if (typeof(T) == typeof(int))
2341 int* dataPtr = stackalloc int[Count];
2342 for (int g = 0; g < Count; g++)
2344 dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? ConstantHelper.GetInt32WithAllBitsSet() : (int)0;
2346 return new Vector<T>(dataPtr);
2348 else if (typeof(T) == typeof(ulong))
2350 ulong* dataPtr = stackalloc ulong[Count];
2351 for (int g = 0; g < Count; g++)
2353 dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? ConstantHelper.GetUInt64WithAllBitsSet() : (ulong)0;
2355 return new Vector<T>(dataPtr);
2357 else if (typeof(T) == typeof(long))
2359 long* dataPtr = stackalloc long[Count];
2360 for (int g = 0; g < Count; g++)
2362 dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? ConstantHelper.GetInt64WithAllBitsSet() : (long)0;
2364 return new Vector<T>(dataPtr);
2366 else if (typeof(T) == typeof(float))
2368 float* dataPtr = stackalloc float[Count];
2369 for (int g = 0; g < Count; g++)
2371 dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? ConstantHelper.GetSingleWithAllBitsSet() : (float)0;
2373 return new Vector<T>(dataPtr);
2375 else if (typeof(T) == typeof(double))
2377 double* dataPtr = stackalloc double[Count];
2378 for (int g = 0; g < Count; g++)
2380 dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? ConstantHelper.GetDoubleWithAllBitsSet() : (double)0;
2382 return new Vector<T>(dataPtr);
2384 else
2386 throw new NotSupportedException(SR.Arg_TypeNotSupported);
2389 else
2391 Register register = new Register();
2392 if (typeof(T) == typeof(byte))
2394 register.byte_0 = left.register.byte_0 > right.register.byte_0 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
2395 register.byte_1 = left.register.byte_1 > right.register.byte_1 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
2396 register.byte_2 = left.register.byte_2 > right.register.byte_2 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
2397 register.byte_3 = left.register.byte_3 > right.register.byte_3 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
2398 register.byte_4 = left.register.byte_4 > right.register.byte_4 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
2399 register.byte_5 = left.register.byte_5 > right.register.byte_5 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
2400 register.byte_6 = left.register.byte_6 > right.register.byte_6 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
2401 register.byte_7 = left.register.byte_7 > right.register.byte_7 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
2402 register.byte_8 = left.register.byte_8 > right.register.byte_8 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
2403 register.byte_9 = left.register.byte_9 > right.register.byte_9 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
2404 register.byte_10 = left.register.byte_10 > right.register.byte_10 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
2405 register.byte_11 = left.register.byte_11 > right.register.byte_11 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
2406 register.byte_12 = left.register.byte_12 > right.register.byte_12 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
2407 register.byte_13 = left.register.byte_13 > right.register.byte_13 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
2408 register.byte_14 = left.register.byte_14 > right.register.byte_14 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
2409 register.byte_15 = left.register.byte_15 > right.register.byte_15 ? ConstantHelper.GetByteWithAllBitsSet() : (byte)0;
2410 return new Vector<T>(ref register);
2412 else if (typeof(T) == typeof(sbyte))
2414 register.sbyte_0 = left.register.sbyte_0 > right.register.sbyte_0 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
2415 register.sbyte_1 = left.register.sbyte_1 > right.register.sbyte_1 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
2416 register.sbyte_2 = left.register.sbyte_2 > right.register.sbyte_2 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
2417 register.sbyte_3 = left.register.sbyte_3 > right.register.sbyte_3 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
2418 register.sbyte_4 = left.register.sbyte_4 > right.register.sbyte_4 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
2419 register.sbyte_5 = left.register.sbyte_5 > right.register.sbyte_5 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
2420 register.sbyte_6 = left.register.sbyte_6 > right.register.sbyte_6 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
2421 register.sbyte_7 = left.register.sbyte_7 > right.register.sbyte_7 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
2422 register.sbyte_8 = left.register.sbyte_8 > right.register.sbyte_8 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
2423 register.sbyte_9 = left.register.sbyte_9 > right.register.sbyte_9 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
2424 register.sbyte_10 = left.register.sbyte_10 > right.register.sbyte_10 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
2425 register.sbyte_11 = left.register.sbyte_11 > right.register.sbyte_11 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
2426 register.sbyte_12 = left.register.sbyte_12 > right.register.sbyte_12 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
2427 register.sbyte_13 = left.register.sbyte_13 > right.register.sbyte_13 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
2428 register.sbyte_14 = left.register.sbyte_14 > right.register.sbyte_14 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
2429 register.sbyte_15 = left.register.sbyte_15 > right.register.sbyte_15 ? ConstantHelper.GetSByteWithAllBitsSet() : (sbyte)0;
2430 return new Vector<T>(ref register);
2432 else if (typeof(T) == typeof(ushort))
2434 register.uint16_0 = left.register.uint16_0 > right.register.uint16_0 ? ConstantHelper.GetUInt16WithAllBitsSet() : (ushort)0;
2435 register.uint16_1 = left.register.uint16_1 > right.register.uint16_1 ? ConstantHelper.GetUInt16WithAllBitsSet() : (ushort)0;
2436 register.uint16_2 = left.register.uint16_2 > right.register.uint16_2 ? ConstantHelper.GetUInt16WithAllBitsSet() : (ushort)0;
2437 register.uint16_3 = left.register.uint16_3 > right.register.uint16_3 ? ConstantHelper.GetUInt16WithAllBitsSet() : (ushort)0;
2438 register.uint16_4 = left.register.uint16_4 > right.register.uint16_4 ? ConstantHelper.GetUInt16WithAllBitsSet() : (ushort)0;
2439 register.uint16_5 = left.register.uint16_5 > right.register.uint16_5 ? ConstantHelper.GetUInt16WithAllBitsSet() : (ushort)0;
2440 register.uint16_6 = left.register.uint16_6 > right.register.uint16_6 ? ConstantHelper.GetUInt16WithAllBitsSet() : (ushort)0;
2441 register.uint16_7 = left.register.uint16_7 > right.register.uint16_7 ? ConstantHelper.GetUInt16WithAllBitsSet() : (ushort)0;
2442 return new Vector<T>(ref register);
2444 else if (typeof(T) == typeof(short))
2446 register.int16_0 = left.register.int16_0 > right.register.int16_0 ? ConstantHelper.GetInt16WithAllBitsSet() : (short)0;
2447 register.int16_1 = left.register.int16_1 > right.register.int16_1 ? ConstantHelper.GetInt16WithAllBitsSet() : (short)0;
2448 register.int16_2 = left.register.int16_2 > right.register.int16_2 ? ConstantHelper.GetInt16WithAllBitsSet() : (short)0;
2449 register.int16_3 = left.register.int16_3 > right.register.int16_3 ? ConstantHelper.GetInt16WithAllBitsSet() : (short)0;
2450 register.int16_4 = left.register.int16_4 > right.register.int16_4 ? ConstantHelper.GetInt16WithAllBitsSet() : (short)0;
2451 register.int16_5 = left.register.int16_5 > right.register.int16_5 ? ConstantHelper.GetInt16WithAllBitsSet() : (short)0;
2452 register.int16_6 = left.register.int16_6 > right.register.int16_6 ? ConstantHelper.GetInt16WithAllBitsSet() : (short)0;
2453 register.int16_7 = left.register.int16_7 > right.register.int16_7 ? ConstantHelper.GetInt16WithAllBitsSet() : (short)0;
2454 return new Vector<T>(ref register);
2456 else if (typeof(T) == typeof(uint))
2458 register.uint32_0 = left.register.uint32_0 > right.register.uint32_0 ? ConstantHelper.GetUInt32WithAllBitsSet() : (uint)0;
2459 register.uint32_1 = left.register.uint32_1 > right.register.uint32_1 ? ConstantHelper.GetUInt32WithAllBitsSet() : (uint)0;
2460 register.uint32_2 = left.register.uint32_2 > right.register.uint32_2 ? ConstantHelper.GetUInt32WithAllBitsSet() : (uint)0;
2461 register.uint32_3 = left.register.uint32_3 > right.register.uint32_3 ? ConstantHelper.GetUInt32WithAllBitsSet() : (uint)0;
2462 return new Vector<T>(ref register);
2464 else if (typeof(T) == typeof(int))
2466 register.int32_0 = left.register.int32_0 > right.register.int32_0 ? ConstantHelper.GetInt32WithAllBitsSet() : (int)0;
2467 register.int32_1 = left.register.int32_1 > right.register.int32_1 ? ConstantHelper.GetInt32WithAllBitsSet() : (int)0;
2468 register.int32_2 = left.register.int32_2 > right.register.int32_2 ? ConstantHelper.GetInt32WithAllBitsSet() : (int)0;
2469 register.int32_3 = left.register.int32_3 > right.register.int32_3 ? ConstantHelper.GetInt32WithAllBitsSet() : (int)0;
2470 return new Vector<T>(ref register);
2472 else if (typeof(T) == typeof(ulong))
2474 register.uint64_0 = left.register.uint64_0 > right.register.uint64_0 ? ConstantHelper.GetUInt64WithAllBitsSet() : (ulong)0;
2475 register.uint64_1 = left.register.uint64_1 > right.register.uint64_1 ? ConstantHelper.GetUInt64WithAllBitsSet() : (ulong)0;
2476 return new Vector<T>(ref register);
2478 else if (typeof(T) == typeof(long))
2480 register.int64_0 = left.register.int64_0 > right.register.int64_0 ? ConstantHelper.GetInt64WithAllBitsSet() : (long)0;
2481 register.int64_1 = left.register.int64_1 > right.register.int64_1 ? ConstantHelper.GetInt64WithAllBitsSet() : (long)0;
2482 return new Vector<T>(ref register);
2484 else if (typeof(T) == typeof(float))
2486 register.single_0 = left.register.single_0 > right.register.single_0 ? ConstantHelper.GetSingleWithAllBitsSet() : (float)0;
2487 register.single_1 = left.register.single_1 > right.register.single_1 ? ConstantHelper.GetSingleWithAllBitsSet() : (float)0;
2488 register.single_2 = left.register.single_2 > right.register.single_2 ? ConstantHelper.GetSingleWithAllBitsSet() : (float)0;
2489 register.single_3 = left.register.single_3 > right.register.single_3 ? ConstantHelper.GetSingleWithAllBitsSet() : (float)0;
2490 return new Vector<T>(ref register);
2492 else if (typeof(T) == typeof(double))
2494 register.double_0 = left.register.double_0 > right.register.double_0 ? ConstantHelper.GetDoubleWithAllBitsSet() : (double)0;
2495 register.double_1 = left.register.double_1 > right.register.double_1 ? ConstantHelper.GetDoubleWithAllBitsSet() : (double)0;
2496 return new Vector<T>(ref register);
2498 else
2500 throw new NotSupportedException(SR.Arg_TypeNotSupported);
2505 [Intrinsic]
2506 internal static Vector<T> GreaterThanOrEqual(Vector<T> left, Vector<T> right)
2508 return Equals(left, right) | GreaterThan(left, right);
2511 [Intrinsic]
2512 internal static Vector<T> LessThanOrEqual(Vector<T> left, Vector<T> right)
2514 return Equals(left, right) | LessThan(left, right);
2517 [Intrinsic]
2518 internal static Vector<T> ConditionalSelect(Vector<T> condition, Vector<T> left, Vector<T> right)
2520 return (left & condition) | (Vector.AndNot(right, condition));
2522 #endregion Comparison Methods
2524 #region Internal Math Methods
2525 [Intrinsic]
2526 internal static unsafe Vector<T> Abs(Vector<T> value)
2528 if (typeof(T) == typeof(byte))
2530 return value;
2532 else if (typeof(T) == typeof(ushort))
2534 return value;
2536 else if (typeof(T) == typeof(uint))
2538 return value;
2540 else if (typeof(T) == typeof(ulong))
2542 return value;
2544 if (Vector.IsHardwareAccelerated)
2546 if (typeof(T) == typeof(sbyte))
2548 sbyte* dataPtr = stackalloc sbyte[Count];
2549 for (int g = 0; g < Count; g++)
2551 dataPtr[g] = (sbyte)(object)(Math.Abs((sbyte)(object)value[g]));
2553 return new Vector<T>(dataPtr);
2555 else if (typeof(T) == typeof(short))
2557 short* dataPtr = stackalloc short[Count];
2558 for (int g = 0; g < Count; g++)
2560 dataPtr[g] = (short)(object)(Math.Abs((short)(object)value[g]));
2562 return new Vector<T>(dataPtr);
2564 else if (typeof(T) == typeof(int))
2566 int* dataPtr = stackalloc int[Count];
2567 for (int g = 0; g < Count; g++)
2569 dataPtr[g] = (int)(object)(Math.Abs((int)(object)value[g]));
2571 return new Vector<T>(dataPtr);
2573 else if (typeof(T) == typeof(long))
2575 long* dataPtr = stackalloc long[Count];
2576 for (int g = 0; g < Count; g++)
2578 dataPtr[g] = (long)(object)(Math.Abs((long)(object)value[g]));
2580 return new Vector<T>(dataPtr);
2582 else if (typeof(T) == typeof(float))
2584 float* dataPtr = stackalloc float[Count];
2585 for (int g = 0; g < Count; g++)
2587 dataPtr[g] = (float)(object)(Math.Abs((float)(object)value[g]));
2589 return new Vector<T>(dataPtr);
2591 else if (typeof(T) == typeof(double))
2593 double* dataPtr = stackalloc double[Count];
2594 for (int g = 0; g < Count; g++)
2596 dataPtr[g] = (double)(object)(Math.Abs((double)(object)value[g]));
2598 return new Vector<T>(dataPtr);
2600 else
2602 throw new NotSupportedException(SR.Arg_TypeNotSupported);
2605 else
2607 if (typeof(T) == typeof(sbyte))
2609 value.register.sbyte_0 = (sbyte)(Math.Abs(value.register.sbyte_0));
2610 value.register.sbyte_1 = (sbyte)(Math.Abs(value.register.sbyte_1));
2611 value.register.sbyte_2 = (sbyte)(Math.Abs(value.register.sbyte_2));
2612 value.register.sbyte_3 = (sbyte)(Math.Abs(value.register.sbyte_3));
2613 value.register.sbyte_4 = (sbyte)(Math.Abs(value.register.sbyte_4));
2614 value.register.sbyte_5 = (sbyte)(Math.Abs(value.register.sbyte_5));
2615 value.register.sbyte_6 = (sbyte)(Math.Abs(value.register.sbyte_6));
2616 value.register.sbyte_7 = (sbyte)(Math.Abs(value.register.sbyte_7));
2617 value.register.sbyte_8 = (sbyte)(Math.Abs(value.register.sbyte_8));
2618 value.register.sbyte_9 = (sbyte)(Math.Abs(value.register.sbyte_9));
2619 value.register.sbyte_10 = (sbyte)(Math.Abs(value.register.sbyte_10));
2620 value.register.sbyte_11 = (sbyte)(Math.Abs(value.register.sbyte_11));
2621 value.register.sbyte_12 = (sbyte)(Math.Abs(value.register.sbyte_12));
2622 value.register.sbyte_13 = (sbyte)(Math.Abs(value.register.sbyte_13));
2623 value.register.sbyte_14 = (sbyte)(Math.Abs(value.register.sbyte_14));
2624 value.register.sbyte_15 = (sbyte)(Math.Abs(value.register.sbyte_15));
2625 return value;
2627 else if (typeof(T) == typeof(short))
2629 value.register.int16_0 = (short)(Math.Abs(value.register.int16_0));
2630 value.register.int16_1 = (short)(Math.Abs(value.register.int16_1));
2631 value.register.int16_2 = (short)(Math.Abs(value.register.int16_2));
2632 value.register.int16_3 = (short)(Math.Abs(value.register.int16_3));
2633 value.register.int16_4 = (short)(Math.Abs(value.register.int16_4));
2634 value.register.int16_5 = (short)(Math.Abs(value.register.int16_5));
2635 value.register.int16_6 = (short)(Math.Abs(value.register.int16_6));
2636 value.register.int16_7 = (short)(Math.Abs(value.register.int16_7));
2637 return value;
2639 else if (typeof(T) == typeof(int))
2641 value.register.int32_0 = (int)(Math.Abs(value.register.int32_0));
2642 value.register.int32_1 = (int)(Math.Abs(value.register.int32_1));
2643 value.register.int32_2 = (int)(Math.Abs(value.register.int32_2));
2644 value.register.int32_3 = (int)(Math.Abs(value.register.int32_3));
2645 return value;
2647 else if (typeof(T) == typeof(long))
2649 value.register.int64_0 = (long)(Math.Abs(value.register.int64_0));
2650 value.register.int64_1 = (long)(Math.Abs(value.register.int64_1));
2651 return value;
2653 else if (typeof(T) == typeof(float))
2655 value.register.single_0 = (float)(Math.Abs(value.register.single_0));
2656 value.register.single_1 = (float)(Math.Abs(value.register.single_1));
2657 value.register.single_2 = (float)(Math.Abs(value.register.single_2));
2658 value.register.single_3 = (float)(Math.Abs(value.register.single_3));
2659 return value;
2661 else if (typeof(T) == typeof(double))
2663 value.register.double_0 = (double)(Math.Abs(value.register.double_0));
2664 value.register.double_1 = (double)(Math.Abs(value.register.double_1));
2665 return value;
2667 else
2669 throw new NotSupportedException(SR.Arg_TypeNotSupported);
2674 [Intrinsic]
2675 internal static unsafe Vector<T> Min(Vector<T> left, Vector<T> right)
2677 if (Vector.IsHardwareAccelerated)
2679 if (typeof(T) == typeof(byte))
2681 byte* dataPtr = stackalloc byte[Count];
2682 for (int g = 0; g < Count; g++)
2684 dataPtr[g] = ScalarLessThan(left[g], right[g]) ? (byte)(object)left[g] : (byte)(object)right[g];
2686 return new Vector<T>(dataPtr);
2688 else if (typeof(T) == typeof(sbyte))
2690 sbyte* dataPtr = stackalloc sbyte[Count];
2691 for (int g = 0; g < Count; g++)
2693 dataPtr[g] = ScalarLessThan(left[g], right[g]) ? (sbyte)(object)left[g] : (sbyte)(object)right[g];
2695 return new Vector<T>(dataPtr);
2697 else if (typeof(T) == typeof(ushort))
2699 ushort* dataPtr = stackalloc ushort[Count];
2700 for (int g = 0; g < Count; g++)
2702 dataPtr[g] = ScalarLessThan(left[g], right[g]) ? (ushort)(object)left[g] : (ushort)(object)right[g];
2704 return new Vector<T>(dataPtr);
2706 else if (typeof(T) == typeof(short))
2708 short* dataPtr = stackalloc short[Count];
2709 for (int g = 0; g < Count; g++)
2711 dataPtr[g] = ScalarLessThan(left[g], right[g]) ? (short)(object)left[g] : (short)(object)right[g];
2713 return new Vector<T>(dataPtr);
2715 else if (typeof(T) == typeof(uint))
2717 uint* dataPtr = stackalloc uint[Count];
2718 for (int g = 0; g < Count; g++)
2720 dataPtr[g] = ScalarLessThan(left[g], right[g]) ? (uint)(object)left[g] : (uint)(object)right[g];
2722 return new Vector<T>(dataPtr);
2724 else if (typeof(T) == typeof(int))
2726 int* dataPtr = stackalloc int[Count];
2727 for (int g = 0; g < Count; g++)
2729 dataPtr[g] = ScalarLessThan(left[g], right[g]) ? (int)(object)left[g] : (int)(object)right[g];
2731 return new Vector<T>(dataPtr);
2733 else if (typeof(T) == typeof(ulong))
2735 ulong* dataPtr = stackalloc ulong[Count];
2736 for (int g = 0; g < Count; g++)
2738 dataPtr[g] = ScalarLessThan(left[g], right[g]) ? (ulong)(object)left[g] : (ulong)(object)right[g];
2740 return new Vector<T>(dataPtr);
2742 else if (typeof(T) == typeof(long))
2744 long* dataPtr = stackalloc long[Count];
2745 for (int g = 0; g < Count; g++)
2747 dataPtr[g] = ScalarLessThan(left[g], right[g]) ? (long)(object)left[g] : (long)(object)right[g];
2749 return new Vector<T>(dataPtr);
2751 else if (typeof(T) == typeof(float))
2753 float* dataPtr = stackalloc float[Count];
2754 for (int g = 0; g < Count; g++)
2756 dataPtr[g] = ScalarLessThan(left[g], right[g]) ? (float)(object)left[g] : (float)(object)right[g];
2758 return new Vector<T>(dataPtr);
2760 else if (typeof(T) == typeof(double))
2762 double* dataPtr = stackalloc double[Count];
2763 for (int g = 0; g < Count; g++)
2765 dataPtr[g] = ScalarLessThan(left[g], right[g]) ? (double)(object)left[g] : (double)(object)right[g];
2767 return new Vector<T>(dataPtr);
2769 else
2771 throw new NotSupportedException(SR.Arg_TypeNotSupported);
2774 else
2776 Vector<T> vec = new Vector<T>();
2777 if (typeof(T) == typeof(byte))
2779 vec.register.byte_0 = left.register.byte_0 < right.register.byte_0 ? left.register.byte_0 : right.register.byte_0;
2780 vec.register.byte_1 = left.register.byte_1 < right.register.byte_1 ? left.register.byte_1 : right.register.byte_1;
2781 vec.register.byte_2 = left.register.byte_2 < right.register.byte_2 ? left.register.byte_2 : right.register.byte_2;
2782 vec.register.byte_3 = left.register.byte_3 < right.register.byte_3 ? left.register.byte_3 : right.register.byte_3;
2783 vec.register.byte_4 = left.register.byte_4 < right.register.byte_4 ? left.register.byte_4 : right.register.byte_4;
2784 vec.register.byte_5 = left.register.byte_5 < right.register.byte_5 ? left.register.byte_5 : right.register.byte_5;
2785 vec.register.byte_6 = left.register.byte_6 < right.register.byte_6 ? left.register.byte_6 : right.register.byte_6;
2786 vec.register.byte_7 = left.register.byte_7 < right.register.byte_7 ? left.register.byte_7 : right.register.byte_7;
2787 vec.register.byte_8 = left.register.byte_8 < right.register.byte_8 ? left.register.byte_8 : right.register.byte_8;
2788 vec.register.byte_9 = left.register.byte_9 < right.register.byte_9 ? left.register.byte_9 : right.register.byte_9;
2789 vec.register.byte_10 = left.register.byte_10 < right.register.byte_10 ? left.register.byte_10 : right.register.byte_10;
2790 vec.register.byte_11 = left.register.byte_11 < right.register.byte_11 ? left.register.byte_11 : right.register.byte_11;
2791 vec.register.byte_12 = left.register.byte_12 < right.register.byte_12 ? left.register.byte_12 : right.register.byte_12;
2792 vec.register.byte_13 = left.register.byte_13 < right.register.byte_13 ? left.register.byte_13 : right.register.byte_13;
2793 vec.register.byte_14 = left.register.byte_14 < right.register.byte_14 ? left.register.byte_14 : right.register.byte_14;
2794 vec.register.byte_15 = left.register.byte_15 < right.register.byte_15 ? left.register.byte_15 : right.register.byte_15;
2795 return vec;
2797 else if (typeof(T) == typeof(sbyte))
2799 vec.register.sbyte_0 = left.register.sbyte_0 < right.register.sbyte_0 ? left.register.sbyte_0 : right.register.sbyte_0;
2800 vec.register.sbyte_1 = left.register.sbyte_1 < right.register.sbyte_1 ? left.register.sbyte_1 : right.register.sbyte_1;
2801 vec.register.sbyte_2 = left.register.sbyte_2 < right.register.sbyte_2 ? left.register.sbyte_2 : right.register.sbyte_2;
2802 vec.register.sbyte_3 = left.register.sbyte_3 < right.register.sbyte_3 ? left.register.sbyte_3 : right.register.sbyte_3;
2803 vec.register.sbyte_4 = left.register.sbyte_4 < right.register.sbyte_4 ? left.register.sbyte_4 : right.register.sbyte_4;
2804 vec.register.sbyte_5 = left.register.sbyte_5 < right.register.sbyte_5 ? left.register.sbyte_5 : right.register.sbyte_5;
2805 vec.register.sbyte_6 = left.register.sbyte_6 < right.register.sbyte_6 ? left.register.sbyte_6 : right.register.sbyte_6;
2806 vec.register.sbyte_7 = left.register.sbyte_7 < right.register.sbyte_7 ? left.register.sbyte_7 : right.register.sbyte_7;
2807 vec.register.sbyte_8 = left.register.sbyte_8 < right.register.sbyte_8 ? left.register.sbyte_8 : right.register.sbyte_8;
2808 vec.register.sbyte_9 = left.register.sbyte_9 < right.register.sbyte_9 ? left.register.sbyte_9 : right.register.sbyte_9;
2809 vec.register.sbyte_10 = left.register.sbyte_10 < right.register.sbyte_10 ? left.register.sbyte_10 : right.register.sbyte_10;
2810 vec.register.sbyte_11 = left.register.sbyte_11 < right.register.sbyte_11 ? left.register.sbyte_11 : right.register.sbyte_11;
2811 vec.register.sbyte_12 = left.register.sbyte_12 < right.register.sbyte_12 ? left.register.sbyte_12 : right.register.sbyte_12;
2812 vec.register.sbyte_13 = left.register.sbyte_13 < right.register.sbyte_13 ? left.register.sbyte_13 : right.register.sbyte_13;
2813 vec.register.sbyte_14 = left.register.sbyte_14 < right.register.sbyte_14 ? left.register.sbyte_14 : right.register.sbyte_14;
2814 vec.register.sbyte_15 = left.register.sbyte_15 < right.register.sbyte_15 ? left.register.sbyte_15 : right.register.sbyte_15;
2815 return vec;
2817 else if (typeof(T) == typeof(ushort))
2819 vec.register.uint16_0 = left.register.uint16_0 < right.register.uint16_0 ? left.register.uint16_0 : right.register.uint16_0;
2820 vec.register.uint16_1 = left.register.uint16_1 < right.register.uint16_1 ? left.register.uint16_1 : right.register.uint16_1;
2821 vec.register.uint16_2 = left.register.uint16_2 < right.register.uint16_2 ? left.register.uint16_2 : right.register.uint16_2;
2822 vec.register.uint16_3 = left.register.uint16_3 < right.register.uint16_3 ? left.register.uint16_3 : right.register.uint16_3;
2823 vec.register.uint16_4 = left.register.uint16_4 < right.register.uint16_4 ? left.register.uint16_4 : right.register.uint16_4;
2824 vec.register.uint16_5 = left.register.uint16_5 < right.register.uint16_5 ? left.register.uint16_5 : right.register.uint16_5;
2825 vec.register.uint16_6 = left.register.uint16_6 < right.register.uint16_6 ? left.register.uint16_6 : right.register.uint16_6;
2826 vec.register.uint16_7 = left.register.uint16_7 < right.register.uint16_7 ? left.register.uint16_7 : right.register.uint16_7;
2827 return vec;
2829 else if (typeof(T) == typeof(short))
2831 vec.register.int16_0 = left.register.int16_0 < right.register.int16_0 ? left.register.int16_0 : right.register.int16_0;
2832 vec.register.int16_1 = left.register.int16_1 < right.register.int16_1 ? left.register.int16_1 : right.register.int16_1;
2833 vec.register.int16_2 = left.register.int16_2 < right.register.int16_2 ? left.register.int16_2 : right.register.int16_2;
2834 vec.register.int16_3 = left.register.int16_3 < right.register.int16_3 ? left.register.int16_3 : right.register.int16_3;
2835 vec.register.int16_4 = left.register.int16_4 < right.register.int16_4 ? left.register.int16_4 : right.register.int16_4;
2836 vec.register.int16_5 = left.register.int16_5 < right.register.int16_5 ? left.register.int16_5 : right.register.int16_5;
2837 vec.register.int16_6 = left.register.int16_6 < right.register.int16_6 ? left.register.int16_6 : right.register.int16_6;
2838 vec.register.int16_7 = left.register.int16_7 < right.register.int16_7 ? left.register.int16_7 : right.register.int16_7;
2839 return vec;
2841 else if (typeof(T) == typeof(uint))
2843 vec.register.uint32_0 = left.register.uint32_0 < right.register.uint32_0 ? left.register.uint32_0 : right.register.uint32_0;
2844 vec.register.uint32_1 = left.register.uint32_1 < right.register.uint32_1 ? left.register.uint32_1 : right.register.uint32_1;
2845 vec.register.uint32_2 = left.register.uint32_2 < right.register.uint32_2 ? left.register.uint32_2 : right.register.uint32_2;
2846 vec.register.uint32_3 = left.register.uint32_3 < right.register.uint32_3 ? left.register.uint32_3 : right.register.uint32_3;
2847 return vec;
2849 else if (typeof(T) == typeof(int))
2851 vec.register.int32_0 = left.register.int32_0 < right.register.int32_0 ? left.register.int32_0 : right.register.int32_0;
2852 vec.register.int32_1 = left.register.int32_1 < right.register.int32_1 ? left.register.int32_1 : right.register.int32_1;
2853 vec.register.int32_2 = left.register.int32_2 < right.register.int32_2 ? left.register.int32_2 : right.register.int32_2;
2854 vec.register.int32_3 = left.register.int32_3 < right.register.int32_3 ? left.register.int32_3 : right.register.int32_3;
2855 return vec;
2857 else if (typeof(T) == typeof(ulong))
2859 vec.register.uint64_0 = left.register.uint64_0 < right.register.uint64_0 ? left.register.uint64_0 : right.register.uint64_0;
2860 vec.register.uint64_1 = left.register.uint64_1 < right.register.uint64_1 ? left.register.uint64_1 : right.register.uint64_1;
2861 return vec;
2863 else if (typeof(T) == typeof(long))
2865 vec.register.int64_0 = left.register.int64_0 < right.register.int64_0 ? left.register.int64_0 : right.register.int64_0;
2866 vec.register.int64_1 = left.register.int64_1 < right.register.int64_1 ? left.register.int64_1 : right.register.int64_1;
2867 return vec;
2869 else if (typeof(T) == typeof(float))
2871 vec.register.single_0 = left.register.single_0 < right.register.single_0 ? left.register.single_0 : right.register.single_0;
2872 vec.register.single_1 = left.register.single_1 < right.register.single_1 ? left.register.single_1 : right.register.single_1;
2873 vec.register.single_2 = left.register.single_2 < right.register.single_2 ? left.register.single_2 : right.register.single_2;
2874 vec.register.single_3 = left.register.single_3 < right.register.single_3 ? left.register.single_3 : right.register.single_3;
2875 return vec;
2877 else if (typeof(T) == typeof(double))
2879 vec.register.double_0 = left.register.double_0 < right.register.double_0 ? left.register.double_0 : right.register.double_0;
2880 vec.register.double_1 = left.register.double_1 < right.register.double_1 ? left.register.double_1 : right.register.double_1;
2881 return vec;
2883 else
2885 throw new NotSupportedException(SR.Arg_TypeNotSupported);
2890 [Intrinsic]
2891 internal static unsafe Vector<T> Max(Vector<T> left, Vector<T> right)
2893 if (Vector.IsHardwareAccelerated)
2895 if (typeof(T) == typeof(byte))
2897 byte* dataPtr = stackalloc byte[Count];
2898 for (int g = 0; g < Count; g++)
2900 dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? (byte)(object)left[g] : (byte)(object)right[g];
2902 return new Vector<T>(dataPtr);
2904 else if (typeof(T) == typeof(sbyte))
2906 sbyte* dataPtr = stackalloc sbyte[Count];
2907 for (int g = 0; g < Count; g++)
2909 dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? (sbyte)(object)left[g] : (sbyte)(object)right[g];
2911 return new Vector<T>(dataPtr);
2913 else if (typeof(T) == typeof(ushort))
2915 ushort* dataPtr = stackalloc ushort[Count];
2916 for (int g = 0; g < Count; g++)
2918 dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? (ushort)(object)left[g] : (ushort)(object)right[g];
2920 return new Vector<T>(dataPtr);
2922 else if (typeof(T) == typeof(short))
2924 short* dataPtr = stackalloc short[Count];
2925 for (int g = 0; g < Count; g++)
2927 dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? (short)(object)left[g] : (short)(object)right[g];
2929 return new Vector<T>(dataPtr);
2931 else if (typeof(T) == typeof(uint))
2933 uint* dataPtr = stackalloc uint[Count];
2934 for (int g = 0; g < Count; g++)
2936 dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? (uint)(object)left[g] : (uint)(object)right[g];
2938 return new Vector<T>(dataPtr);
2940 else if (typeof(T) == typeof(int))
2942 int* dataPtr = stackalloc int[Count];
2943 for (int g = 0; g < Count; g++)
2945 dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? (int)(object)left[g] : (int)(object)right[g];
2947 return new Vector<T>(dataPtr);
2949 else if (typeof(T) == typeof(ulong))
2951 ulong* dataPtr = stackalloc ulong[Count];
2952 for (int g = 0; g < Count; g++)
2954 dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? (ulong)(object)left[g] : (ulong)(object)right[g];
2956 return new Vector<T>(dataPtr);
2958 else if (typeof(T) == typeof(long))
2960 long* dataPtr = stackalloc long[Count];
2961 for (int g = 0; g < Count; g++)
2963 dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? (long)(object)left[g] : (long)(object)right[g];
2965 return new Vector<T>(dataPtr);
2967 else if (typeof(T) == typeof(float))
2969 float* dataPtr = stackalloc float[Count];
2970 for (int g = 0; g < Count; g++)
2972 dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? (float)(object)left[g] : (float)(object)right[g];
2974 return new Vector<T>(dataPtr);
2976 else if (typeof(T) == typeof(double))
2978 double* dataPtr = stackalloc double[Count];
2979 for (int g = 0; g < Count; g++)
2981 dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? (double)(object)left[g] : (double)(object)right[g];
2983 return new Vector<T>(dataPtr);
2985 else
2987 throw new NotSupportedException(SR.Arg_TypeNotSupported);
2990 else
2992 Vector<T> vec = new Vector<T>();
2993 if (typeof(T) == typeof(byte))
2995 vec.register.byte_0 = left.register.byte_0 > right.register.byte_0 ? left.register.byte_0 : right.register.byte_0;
2996 vec.register.byte_1 = left.register.byte_1 > right.register.byte_1 ? left.register.byte_1 : right.register.byte_1;
2997 vec.register.byte_2 = left.register.byte_2 > right.register.byte_2 ? left.register.byte_2 : right.register.byte_2;
2998 vec.register.byte_3 = left.register.byte_3 > right.register.byte_3 ? left.register.byte_3 : right.register.byte_3;
2999 vec.register.byte_4 = left.register.byte_4 > right.register.byte_4 ? left.register.byte_4 : right.register.byte_4;
3000 vec.register.byte_5 = left.register.byte_5 > right.register.byte_5 ? left.register.byte_5 : right.register.byte_5;
3001 vec.register.byte_6 = left.register.byte_6 > right.register.byte_6 ? left.register.byte_6 : right.register.byte_6;
3002 vec.register.byte_7 = left.register.byte_7 > right.register.byte_7 ? left.register.byte_7 : right.register.byte_7;
3003 vec.register.byte_8 = left.register.byte_8 > right.register.byte_8 ? left.register.byte_8 : right.register.byte_8;
3004 vec.register.byte_9 = left.register.byte_9 > right.register.byte_9 ? left.register.byte_9 : right.register.byte_9;
3005 vec.register.byte_10 = left.register.byte_10 > right.register.byte_10 ? left.register.byte_10 : right.register.byte_10;
3006 vec.register.byte_11 = left.register.byte_11 > right.register.byte_11 ? left.register.byte_11 : right.register.byte_11;
3007 vec.register.byte_12 = left.register.byte_12 > right.register.byte_12 ? left.register.byte_12 : right.register.byte_12;
3008 vec.register.byte_13 = left.register.byte_13 > right.register.byte_13 ? left.register.byte_13 : right.register.byte_13;
3009 vec.register.byte_14 = left.register.byte_14 > right.register.byte_14 ? left.register.byte_14 : right.register.byte_14;
3010 vec.register.byte_15 = left.register.byte_15 > right.register.byte_15 ? left.register.byte_15 : right.register.byte_15;
3011 return vec;
3013 else if (typeof(T) == typeof(sbyte))
3015 vec.register.sbyte_0 = left.register.sbyte_0 > right.register.sbyte_0 ? left.register.sbyte_0 : right.register.sbyte_0;
3016 vec.register.sbyte_1 = left.register.sbyte_1 > right.register.sbyte_1 ? left.register.sbyte_1 : right.register.sbyte_1;
3017 vec.register.sbyte_2 = left.register.sbyte_2 > right.register.sbyte_2 ? left.register.sbyte_2 : right.register.sbyte_2;
3018 vec.register.sbyte_3 = left.register.sbyte_3 > right.register.sbyte_3 ? left.register.sbyte_3 : right.register.sbyte_3;
3019 vec.register.sbyte_4 = left.register.sbyte_4 > right.register.sbyte_4 ? left.register.sbyte_4 : right.register.sbyte_4;
3020 vec.register.sbyte_5 = left.register.sbyte_5 > right.register.sbyte_5 ? left.register.sbyte_5 : right.register.sbyte_5;
3021 vec.register.sbyte_6 = left.register.sbyte_6 > right.register.sbyte_6 ? left.register.sbyte_6 : right.register.sbyte_6;
3022 vec.register.sbyte_7 = left.register.sbyte_7 > right.register.sbyte_7 ? left.register.sbyte_7 : right.register.sbyte_7;
3023 vec.register.sbyte_8 = left.register.sbyte_8 > right.register.sbyte_8 ? left.register.sbyte_8 : right.register.sbyte_8;
3024 vec.register.sbyte_9 = left.register.sbyte_9 > right.register.sbyte_9 ? left.register.sbyte_9 : right.register.sbyte_9;
3025 vec.register.sbyte_10 = left.register.sbyte_10 > right.register.sbyte_10 ? left.register.sbyte_10 : right.register.sbyte_10;
3026 vec.register.sbyte_11 = left.register.sbyte_11 > right.register.sbyte_11 ? left.register.sbyte_11 : right.register.sbyte_11;
3027 vec.register.sbyte_12 = left.register.sbyte_12 > right.register.sbyte_12 ? left.register.sbyte_12 : right.register.sbyte_12;
3028 vec.register.sbyte_13 = left.register.sbyte_13 > right.register.sbyte_13 ? left.register.sbyte_13 : right.register.sbyte_13;
3029 vec.register.sbyte_14 = left.register.sbyte_14 > right.register.sbyte_14 ? left.register.sbyte_14 : right.register.sbyte_14;
3030 vec.register.sbyte_15 = left.register.sbyte_15 > right.register.sbyte_15 ? left.register.sbyte_15 : right.register.sbyte_15;
3031 return vec;
3033 else if (typeof(T) == typeof(ushort))
3035 vec.register.uint16_0 = left.register.uint16_0 > right.register.uint16_0 ? left.register.uint16_0 : right.register.uint16_0;
3036 vec.register.uint16_1 = left.register.uint16_1 > right.register.uint16_1 ? left.register.uint16_1 : right.register.uint16_1;
3037 vec.register.uint16_2 = left.register.uint16_2 > right.register.uint16_2 ? left.register.uint16_2 : right.register.uint16_2;
3038 vec.register.uint16_3 = left.register.uint16_3 > right.register.uint16_3 ? left.register.uint16_3 : right.register.uint16_3;
3039 vec.register.uint16_4 = left.register.uint16_4 > right.register.uint16_4 ? left.register.uint16_4 : right.register.uint16_4;
3040 vec.register.uint16_5 = left.register.uint16_5 > right.register.uint16_5 ? left.register.uint16_5 : right.register.uint16_5;
3041 vec.register.uint16_6 = left.register.uint16_6 > right.register.uint16_6 ? left.register.uint16_6 : right.register.uint16_6;
3042 vec.register.uint16_7 = left.register.uint16_7 > right.register.uint16_7 ? left.register.uint16_7 : right.register.uint16_7;
3043 return vec;
3045 else if (typeof(T) == typeof(short))
3047 vec.register.int16_0 = left.register.int16_0 > right.register.int16_0 ? left.register.int16_0 : right.register.int16_0;
3048 vec.register.int16_1 = left.register.int16_1 > right.register.int16_1 ? left.register.int16_1 : right.register.int16_1;
3049 vec.register.int16_2 = left.register.int16_2 > right.register.int16_2 ? left.register.int16_2 : right.register.int16_2;
3050 vec.register.int16_3 = left.register.int16_3 > right.register.int16_3 ? left.register.int16_3 : right.register.int16_3;
3051 vec.register.int16_4 = left.register.int16_4 > right.register.int16_4 ? left.register.int16_4 : right.register.int16_4;
3052 vec.register.int16_5 = left.register.int16_5 > right.register.int16_5 ? left.register.int16_5 : right.register.int16_5;
3053 vec.register.int16_6 = left.register.int16_6 > right.register.int16_6 ? left.register.int16_6 : right.register.int16_6;
3054 vec.register.int16_7 = left.register.int16_7 > right.register.int16_7 ? left.register.int16_7 : right.register.int16_7;
3055 return vec;
3057 else if (typeof(T) == typeof(uint))
3059 vec.register.uint32_0 = left.register.uint32_0 > right.register.uint32_0 ? left.register.uint32_0 : right.register.uint32_0;
3060 vec.register.uint32_1 = left.register.uint32_1 > right.register.uint32_1 ? left.register.uint32_1 : right.register.uint32_1;
3061 vec.register.uint32_2 = left.register.uint32_2 > right.register.uint32_2 ? left.register.uint32_2 : right.register.uint32_2;
3062 vec.register.uint32_3 = left.register.uint32_3 > right.register.uint32_3 ? left.register.uint32_3 : right.register.uint32_3;
3063 return vec;
3065 else if (typeof(T) == typeof(int))
3067 vec.register.int32_0 = left.register.int32_0 > right.register.int32_0 ? left.register.int32_0 : right.register.int32_0;
3068 vec.register.int32_1 = left.register.int32_1 > right.register.int32_1 ? left.register.int32_1 : right.register.int32_1;
3069 vec.register.int32_2 = left.register.int32_2 > right.register.int32_2 ? left.register.int32_2 : right.register.int32_2;
3070 vec.register.int32_3 = left.register.int32_3 > right.register.int32_3 ? left.register.int32_3 : right.register.int32_3;
3071 return vec;
3073 else if (typeof(T) == typeof(ulong))
3075 vec.register.uint64_0 = left.register.uint64_0 > right.register.uint64_0 ? left.register.uint64_0 : right.register.uint64_0;
3076 vec.register.uint64_1 = left.register.uint64_1 > right.register.uint64_1 ? left.register.uint64_1 : right.register.uint64_1;
3077 return vec;
3079 else if (typeof(T) == typeof(long))
3081 vec.register.int64_0 = left.register.int64_0 > right.register.int64_0 ? left.register.int64_0 : right.register.int64_0;
3082 vec.register.int64_1 = left.register.int64_1 > right.register.int64_1 ? left.register.int64_1 : right.register.int64_1;
3083 return vec;
3085 else if (typeof(T) == typeof(float))
3087 vec.register.single_0 = left.register.single_0 > right.register.single_0 ? left.register.single_0 : right.register.single_0;
3088 vec.register.single_1 = left.register.single_1 > right.register.single_1 ? left.register.single_1 : right.register.single_1;
3089 vec.register.single_2 = left.register.single_2 > right.register.single_2 ? left.register.single_2 : right.register.single_2;
3090 vec.register.single_3 = left.register.single_3 > right.register.single_3 ? left.register.single_3 : right.register.single_3;
3091 return vec;
3093 else if (typeof(T) == typeof(double))
3095 vec.register.double_0 = left.register.double_0 > right.register.double_0 ? left.register.double_0 : right.register.double_0;
3096 vec.register.double_1 = left.register.double_1 > right.register.double_1 ? left.register.double_1 : right.register.double_1;
3097 return vec;
3099 else
3101 throw new NotSupportedException(SR.Arg_TypeNotSupported);
3106 [Intrinsic]
3107 internal static T Dot(Vector<T> left, Vector<T> right)
3109 if (Vector.IsHardwareAccelerated)
3111 T product = default;
3112 for (int g = 0; g < Count; g++)
3114 product = ScalarAdd(product, ScalarMultiply(left[g], right[g]));
3116 return product;
3118 else
3120 if (typeof(T) == typeof(byte))
3122 byte product = 0;
3123 product += (byte)(left.register.byte_0 * right.register.byte_0);
3124 product += (byte)(left.register.byte_1 * right.register.byte_1);
3125 product += (byte)(left.register.byte_2 * right.register.byte_2);
3126 product += (byte)(left.register.byte_3 * right.register.byte_3);
3127 product += (byte)(left.register.byte_4 * right.register.byte_4);
3128 product += (byte)(left.register.byte_5 * right.register.byte_5);
3129 product += (byte)(left.register.byte_6 * right.register.byte_6);
3130 product += (byte)(left.register.byte_7 * right.register.byte_7);
3131 product += (byte)(left.register.byte_8 * right.register.byte_8);
3132 product += (byte)(left.register.byte_9 * right.register.byte_9);
3133 product += (byte)(left.register.byte_10 * right.register.byte_10);
3134 product += (byte)(left.register.byte_11 * right.register.byte_11);
3135 product += (byte)(left.register.byte_12 * right.register.byte_12);
3136 product += (byte)(left.register.byte_13 * right.register.byte_13);
3137 product += (byte)(left.register.byte_14 * right.register.byte_14);
3138 product += (byte)(left.register.byte_15 * right.register.byte_15);
3139 return (T)(object)product;
3141 else if (typeof(T) == typeof(sbyte))
3143 sbyte product = 0;
3144 product += (sbyte)(left.register.sbyte_0 * right.register.sbyte_0);
3145 product += (sbyte)(left.register.sbyte_1 * right.register.sbyte_1);
3146 product += (sbyte)(left.register.sbyte_2 * right.register.sbyte_2);
3147 product += (sbyte)(left.register.sbyte_3 * right.register.sbyte_3);
3148 product += (sbyte)(left.register.sbyte_4 * right.register.sbyte_4);
3149 product += (sbyte)(left.register.sbyte_5 * right.register.sbyte_5);
3150 product += (sbyte)(left.register.sbyte_6 * right.register.sbyte_6);
3151 product += (sbyte)(left.register.sbyte_7 * right.register.sbyte_7);
3152 product += (sbyte)(left.register.sbyte_8 * right.register.sbyte_8);
3153 product += (sbyte)(left.register.sbyte_9 * right.register.sbyte_9);
3154 product += (sbyte)(left.register.sbyte_10 * right.register.sbyte_10);
3155 product += (sbyte)(left.register.sbyte_11 * right.register.sbyte_11);
3156 product += (sbyte)(left.register.sbyte_12 * right.register.sbyte_12);
3157 product += (sbyte)(left.register.sbyte_13 * right.register.sbyte_13);
3158 product += (sbyte)(left.register.sbyte_14 * right.register.sbyte_14);
3159 product += (sbyte)(left.register.sbyte_15 * right.register.sbyte_15);
3160 return (T)(object)product;
3162 else if (typeof(T) == typeof(ushort))
3164 ushort product = 0;
3165 product += (ushort)(left.register.uint16_0 * right.register.uint16_0);
3166 product += (ushort)(left.register.uint16_1 * right.register.uint16_1);
3167 product += (ushort)(left.register.uint16_2 * right.register.uint16_2);
3168 product += (ushort)(left.register.uint16_3 * right.register.uint16_3);
3169 product += (ushort)(left.register.uint16_4 * right.register.uint16_4);
3170 product += (ushort)(left.register.uint16_5 * right.register.uint16_5);
3171 product += (ushort)(left.register.uint16_6 * right.register.uint16_6);
3172 product += (ushort)(left.register.uint16_7 * right.register.uint16_7);
3173 return (T)(object)product;
3175 else if (typeof(T) == typeof(short))
3177 short product = 0;
3178 product += (short)(left.register.int16_0 * right.register.int16_0);
3179 product += (short)(left.register.int16_1 * right.register.int16_1);
3180 product += (short)(left.register.int16_2 * right.register.int16_2);
3181 product += (short)(left.register.int16_3 * right.register.int16_3);
3182 product += (short)(left.register.int16_4 * right.register.int16_4);
3183 product += (short)(left.register.int16_5 * right.register.int16_5);
3184 product += (short)(left.register.int16_6 * right.register.int16_6);
3185 product += (short)(left.register.int16_7 * right.register.int16_7);
3186 return (T)(object)product;
3188 else if (typeof(T) == typeof(uint))
3190 uint product = 0;
3191 product += (uint)(left.register.uint32_0 * right.register.uint32_0);
3192 product += (uint)(left.register.uint32_1 * right.register.uint32_1);
3193 product += (uint)(left.register.uint32_2 * right.register.uint32_2);
3194 product += (uint)(left.register.uint32_3 * right.register.uint32_3);
3195 return (T)(object)product;
3197 else if (typeof(T) == typeof(int))
3199 int product = 0;
3200 product += (int)(left.register.int32_0 * right.register.int32_0);
3201 product += (int)(left.register.int32_1 * right.register.int32_1);
3202 product += (int)(left.register.int32_2 * right.register.int32_2);
3203 product += (int)(left.register.int32_3 * right.register.int32_3);
3204 return (T)(object)product;
3206 else if (typeof(T) == typeof(ulong))
3208 ulong product = 0;
3209 product += (ulong)(left.register.uint64_0 * right.register.uint64_0);
3210 product += (ulong)(left.register.uint64_1 * right.register.uint64_1);
3211 return (T)(object)product;
3213 else if (typeof(T) == typeof(long))
3215 long product = 0;
3216 product += (long)(left.register.int64_0 * right.register.int64_0);
3217 product += (long)(left.register.int64_1 * right.register.int64_1);
3218 return (T)(object)product;
3220 else if (typeof(T) == typeof(float))
3222 float product = 0;
3223 product += (float)(left.register.single_0 * right.register.single_0);
3224 product += (float)(left.register.single_1 * right.register.single_1);
3225 product += (float)(left.register.single_2 * right.register.single_2);
3226 product += (float)(left.register.single_3 * right.register.single_3);
3227 return (T)(object)product;
3229 else if (typeof(T) == typeof(double))
3231 double product = 0;
3232 product += (double)(left.register.double_0 * right.register.double_0);
3233 product += (double)(left.register.double_1 * right.register.double_1);
3234 return (T)(object)product;
3236 else
3238 throw new NotSupportedException(SR.Arg_TypeNotSupported);
3243 [Intrinsic]
3244 internal static unsafe Vector<T> SquareRoot(Vector<T> value)
3246 if (Vector.IsHardwareAccelerated)
3248 if (typeof(T) == typeof(byte))
3250 byte* dataPtr = stackalloc byte[Count];
3251 for (int g = 0; g < Count; g++)
3253 dataPtr[g] = unchecked((byte)Math.Sqrt((byte)(object)value[g]));
3255 return new Vector<T>(dataPtr);
3257 else if (typeof(T) == typeof(sbyte))
3259 sbyte* dataPtr = stackalloc sbyte[Count];
3260 for (int g = 0; g < Count; g++)
3262 dataPtr[g] = unchecked((sbyte)Math.Sqrt((sbyte)(object)value[g]));
3264 return new Vector<T>(dataPtr);
3266 else if (typeof(T) == typeof(ushort))
3268 ushort* dataPtr = stackalloc ushort[Count];
3269 for (int g = 0; g < Count; g++)
3271 dataPtr[g] = unchecked((ushort)Math.Sqrt((ushort)(object)value[g]));
3273 return new Vector<T>(dataPtr);
3275 else if (typeof(T) == typeof(short))
3277 short* dataPtr = stackalloc short[Count];
3278 for (int g = 0; g < Count; g++)
3280 dataPtr[g] = unchecked((short)Math.Sqrt((short)(object)value[g]));
3282 return new Vector<T>(dataPtr);
3284 else if (typeof(T) == typeof(uint))
3286 uint* dataPtr = stackalloc uint[Count];
3287 for (int g = 0; g < Count; g++)
3289 dataPtr[g] = unchecked((uint)Math.Sqrt((uint)(object)value[g]));
3291 return new Vector<T>(dataPtr);
3293 else if (typeof(T) == typeof(int))
3295 int* dataPtr = stackalloc int[Count];
3296 for (int g = 0; g < Count; g++)
3298 dataPtr[g] = unchecked((int)Math.Sqrt((int)(object)value[g]));
3300 return new Vector<T>(dataPtr);
3302 else if (typeof(T) == typeof(ulong))
3304 ulong* dataPtr = stackalloc ulong[Count];
3305 for (int g = 0; g < Count; g++)
3307 dataPtr[g] = unchecked((ulong)Math.Sqrt((ulong)(object)value[g]));
3309 return new Vector<T>(dataPtr);
3311 else if (typeof(T) == typeof(long))
3313 long* dataPtr = stackalloc long[Count];
3314 for (int g = 0; g < Count; g++)
3316 dataPtr[g] = unchecked((long)Math.Sqrt((long)(object)value[g]));
3318 return new Vector<T>(dataPtr);
3320 else if (typeof(T) == typeof(float))
3322 float* dataPtr = stackalloc float[Count];
3323 for (int g = 0; g < Count; g++)
3325 dataPtr[g] = unchecked((float)Math.Sqrt((float)(object)value[g]));
3327 return new Vector<T>(dataPtr);
3329 else if (typeof(T) == typeof(double))
3331 double* dataPtr = stackalloc double[Count];
3332 for (int g = 0; g < Count; g++)
3334 dataPtr[g] = unchecked((double)Math.Sqrt((double)(object)value[g]));
3336 return new Vector<T>(dataPtr);
3338 else
3340 throw new NotSupportedException(SR.Arg_TypeNotSupported);
3343 else
3345 if (typeof(T) == typeof(byte))
3347 value.register.byte_0 = (byte)Math.Sqrt(value.register.byte_0);
3348 value.register.byte_1 = (byte)Math.Sqrt(value.register.byte_1);
3349 value.register.byte_2 = (byte)Math.Sqrt(value.register.byte_2);
3350 value.register.byte_3 = (byte)Math.Sqrt(value.register.byte_3);
3351 value.register.byte_4 = (byte)Math.Sqrt(value.register.byte_4);
3352 value.register.byte_5 = (byte)Math.Sqrt(value.register.byte_5);
3353 value.register.byte_6 = (byte)Math.Sqrt(value.register.byte_6);
3354 value.register.byte_7 = (byte)Math.Sqrt(value.register.byte_7);
3355 value.register.byte_8 = (byte)Math.Sqrt(value.register.byte_8);
3356 value.register.byte_9 = (byte)Math.Sqrt(value.register.byte_9);
3357 value.register.byte_10 = (byte)Math.Sqrt(value.register.byte_10);
3358 value.register.byte_11 = (byte)Math.Sqrt(value.register.byte_11);
3359 value.register.byte_12 = (byte)Math.Sqrt(value.register.byte_12);
3360 value.register.byte_13 = (byte)Math.Sqrt(value.register.byte_13);
3361 value.register.byte_14 = (byte)Math.Sqrt(value.register.byte_14);
3362 value.register.byte_15 = (byte)Math.Sqrt(value.register.byte_15);
3363 return value;
3365 else if (typeof(T) == typeof(sbyte))
3367 value.register.sbyte_0 = (sbyte)Math.Sqrt(value.register.sbyte_0);
3368 value.register.sbyte_1 = (sbyte)Math.Sqrt(value.register.sbyte_1);
3369 value.register.sbyte_2 = (sbyte)Math.Sqrt(value.register.sbyte_2);
3370 value.register.sbyte_3 = (sbyte)Math.Sqrt(value.register.sbyte_3);
3371 value.register.sbyte_4 = (sbyte)Math.Sqrt(value.register.sbyte_4);
3372 value.register.sbyte_5 = (sbyte)Math.Sqrt(value.register.sbyte_5);
3373 value.register.sbyte_6 = (sbyte)Math.Sqrt(value.register.sbyte_6);
3374 value.register.sbyte_7 = (sbyte)Math.Sqrt(value.register.sbyte_7);
3375 value.register.sbyte_8 = (sbyte)Math.Sqrt(value.register.sbyte_8);
3376 value.register.sbyte_9 = (sbyte)Math.Sqrt(value.register.sbyte_9);
3377 value.register.sbyte_10 = (sbyte)Math.Sqrt(value.register.sbyte_10);
3378 value.register.sbyte_11 = (sbyte)Math.Sqrt(value.register.sbyte_11);
3379 value.register.sbyte_12 = (sbyte)Math.Sqrt(value.register.sbyte_12);
3380 value.register.sbyte_13 = (sbyte)Math.Sqrt(value.register.sbyte_13);
3381 value.register.sbyte_14 = (sbyte)Math.Sqrt(value.register.sbyte_14);
3382 value.register.sbyte_15 = (sbyte)Math.Sqrt(value.register.sbyte_15);
3383 return value;
3385 else if (typeof(T) == typeof(ushort))
3387 value.register.uint16_0 = (ushort)Math.Sqrt(value.register.uint16_0);
3388 value.register.uint16_1 = (ushort)Math.Sqrt(value.register.uint16_1);
3389 value.register.uint16_2 = (ushort)Math.Sqrt(value.register.uint16_2);
3390 value.register.uint16_3 = (ushort)Math.Sqrt(value.register.uint16_3);
3391 value.register.uint16_4 = (ushort)Math.Sqrt(value.register.uint16_4);
3392 value.register.uint16_5 = (ushort)Math.Sqrt(value.register.uint16_5);
3393 value.register.uint16_6 = (ushort)Math.Sqrt(value.register.uint16_6);
3394 value.register.uint16_7 = (ushort)Math.Sqrt(value.register.uint16_7);
3395 return value;
3397 else if (typeof(T) == typeof(short))
3399 value.register.int16_0 = (short)Math.Sqrt(value.register.int16_0);
3400 value.register.int16_1 = (short)Math.Sqrt(value.register.int16_1);
3401 value.register.int16_2 = (short)Math.Sqrt(value.register.int16_2);
3402 value.register.int16_3 = (short)Math.Sqrt(value.register.int16_3);
3403 value.register.int16_4 = (short)Math.Sqrt(value.register.int16_4);
3404 value.register.int16_5 = (short)Math.Sqrt(value.register.int16_5);
3405 value.register.int16_6 = (short)Math.Sqrt(value.register.int16_6);
3406 value.register.int16_7 = (short)Math.Sqrt(value.register.int16_7);
3407 return value;
3409 else if (typeof(T) == typeof(uint))
3411 value.register.uint32_0 = (uint)Math.Sqrt(value.register.uint32_0);
3412 value.register.uint32_1 = (uint)Math.Sqrt(value.register.uint32_1);
3413 value.register.uint32_2 = (uint)Math.Sqrt(value.register.uint32_2);
3414 value.register.uint32_3 = (uint)Math.Sqrt(value.register.uint32_3);
3415 return value;
3417 else if (typeof(T) == typeof(int))
3419 value.register.int32_0 = (int)Math.Sqrt(value.register.int32_0);
3420 value.register.int32_1 = (int)Math.Sqrt(value.register.int32_1);
3421 value.register.int32_2 = (int)Math.Sqrt(value.register.int32_2);
3422 value.register.int32_3 = (int)Math.Sqrt(value.register.int32_3);
3423 return value;
3425 else if (typeof(T) == typeof(ulong))
3427 value.register.uint64_0 = (ulong)Math.Sqrt(value.register.uint64_0);
3428 value.register.uint64_1 = (ulong)Math.Sqrt(value.register.uint64_1);
3429 return value;
3431 else if (typeof(T) == typeof(long))
3433 value.register.int64_0 = (long)Math.Sqrt(value.register.int64_0);
3434 value.register.int64_1 = (long)Math.Sqrt(value.register.int64_1);
3435 return value;
3437 else if (typeof(T) == typeof(float))
3439 value.register.single_0 = (float)Math.Sqrt(value.register.single_0);
3440 value.register.single_1 = (float)Math.Sqrt(value.register.single_1);
3441 value.register.single_2 = (float)Math.Sqrt(value.register.single_2);
3442 value.register.single_3 = (float)Math.Sqrt(value.register.single_3);
3443 return value;
3445 else if (typeof(T) == typeof(double))
3447 value.register.double_0 = (double)Math.Sqrt(value.register.double_0);
3448 value.register.double_1 = (double)Math.Sqrt(value.register.double_1);
3449 return value;
3451 else
3453 throw new NotSupportedException(SR.Arg_TypeNotSupported);
3457 #endregion Internal Math Methods
3459 #region Helper Methods
3460 [MethodImpl(MethodImplOptions.AggressiveInlining)]
3461 private static bool ScalarEquals(T left, T right)
3463 if (typeof(T) == typeof(byte))
3465 return (byte)(object)left == (byte)(object)right;
3467 else if (typeof(T) == typeof(sbyte))
3469 return (sbyte)(object)left == (sbyte)(object)right;
3471 else if (typeof(T) == typeof(ushort))
3473 return (ushort)(object)left == (ushort)(object)right;
3475 else if (typeof(T) == typeof(short))
3477 return (short)(object)left == (short)(object)right;
3479 else if (typeof(T) == typeof(uint))
3481 return (uint)(object)left == (uint)(object)right;
3483 else if (typeof(T) == typeof(int))
3485 return (int)(object)left == (int)(object)right;
3487 else if (typeof(T) == typeof(ulong))
3489 return (ulong)(object)left == (ulong)(object)right;
3491 else if (typeof(T) == typeof(long))
3493 return (long)(object)left == (long)(object)right;
3495 else if (typeof(T) == typeof(float))
3497 return (float)(object)left == (float)(object)right;
3499 else if (typeof(T) == typeof(double))
3501 return (double)(object)left == (double)(object)right;
3503 else
3505 throw new NotSupportedException(SR.Arg_TypeNotSupported);
3509 [MethodImpl(MethodImplOptions.AggressiveInlining)]
3510 private static bool ScalarLessThan(T left, T right)
3512 if (typeof(T) == typeof(byte))
3514 return (byte)(object)left < (byte)(object)right;
3516 else if (typeof(T) == typeof(sbyte))
3518 return (sbyte)(object)left < (sbyte)(object)right;
3520 else if (typeof(T) == typeof(ushort))
3522 return (ushort)(object)left < (ushort)(object)right;
3524 else if (typeof(T) == typeof(short))
3526 return (short)(object)left < (short)(object)right;
3528 else if (typeof(T) == typeof(uint))
3530 return (uint)(object)left < (uint)(object)right;
3532 else if (typeof(T) == typeof(int))
3534 return (int)(object)left < (int)(object)right;
3536 else if (typeof(T) == typeof(ulong))
3538 return (ulong)(object)left < (ulong)(object)right;
3540 else if (typeof(T) == typeof(long))
3542 return (long)(object)left < (long)(object)right;
3544 else if (typeof(T) == typeof(float))
3546 return (float)(object)left < (float)(object)right;
3548 else if (typeof(T) == typeof(double))
3550 return (double)(object)left < (double)(object)right;
3552 else
3554 throw new NotSupportedException(SR.Arg_TypeNotSupported);
3558 [MethodImpl(MethodImplOptions.AggressiveInlining)]
3559 private static bool ScalarGreaterThan(T left, T right)
3561 if (typeof(T) == typeof(byte))
3563 return (byte)(object)left > (byte)(object)right;
3565 else if (typeof(T) == typeof(sbyte))
3567 return (sbyte)(object)left > (sbyte)(object)right;
3569 else if (typeof(T) == typeof(ushort))
3571 return (ushort)(object)left > (ushort)(object)right;
3573 else if (typeof(T) == typeof(short))
3575 return (short)(object)left > (short)(object)right;
3577 else if (typeof(T) == typeof(uint))
3579 return (uint)(object)left > (uint)(object)right;
3581 else if (typeof(T) == typeof(int))
3583 return (int)(object)left > (int)(object)right;
3585 else if (typeof(T) == typeof(ulong))
3587 return (ulong)(object)left > (ulong)(object)right;
3589 else if (typeof(T) == typeof(long))
3591 return (long)(object)left > (long)(object)right;
3593 else if (typeof(T) == typeof(float))
3595 return (float)(object)left > (float)(object)right;
3597 else if (typeof(T) == typeof(double))
3599 return (double)(object)left > (double)(object)right;
3601 else
3603 throw new NotSupportedException(SR.Arg_TypeNotSupported);
3607 [MethodImpl(MethodImplOptions.AggressiveInlining)]
3608 private static T ScalarAdd(T left, T right)
3610 if (typeof(T) == typeof(byte))
3612 return (T)(object)unchecked((byte)((byte)(object)left + (byte)(object)right));
3614 else if (typeof(T) == typeof(sbyte))
3616 return (T)(object)unchecked((sbyte)((sbyte)(object)left + (sbyte)(object)right));
3618 else if (typeof(T) == typeof(ushort))
3620 return (T)(object)unchecked((ushort)((ushort)(object)left + (ushort)(object)right));
3622 else if (typeof(T) == typeof(short))
3624 return (T)(object)unchecked((short)((short)(object)left + (short)(object)right));
3626 else if (typeof(T) == typeof(uint))
3628 return (T)(object)unchecked((uint)((uint)(object)left + (uint)(object)right));
3630 else if (typeof(T) == typeof(int))
3632 return (T)(object)unchecked((int)((int)(object)left + (int)(object)right));
3634 else if (typeof(T) == typeof(ulong))
3636 return (T)(object)unchecked((ulong)((ulong)(object)left + (ulong)(object)right));
3638 else if (typeof(T) == typeof(long))
3640 return (T)(object)unchecked((long)((long)(object)left + (long)(object)right));
3642 else if (typeof(T) == typeof(float))
3644 return (T)(object)unchecked((float)((float)(object)left + (float)(object)right));
3646 else if (typeof(T) == typeof(double))
3648 return (T)(object)unchecked((double)((double)(object)left + (double)(object)right));
3650 else
3652 throw new NotSupportedException(SR.Arg_TypeNotSupported);
3656 [MethodImpl(MethodImplOptions.AggressiveInlining)]
3657 private static T ScalarSubtract(T left, T right)
3659 if (typeof(T) == typeof(byte))
3661 return (T)(object)(byte)((byte)(object)left - (byte)(object)right);
3663 else if (typeof(T) == typeof(sbyte))
3665 return (T)(object)(sbyte)((sbyte)(object)left - (sbyte)(object)right);
3667 else if (typeof(T) == typeof(ushort))
3669 return (T)(object)(ushort)((ushort)(object)left - (ushort)(object)right);
3671 else if (typeof(T) == typeof(short))
3673 return (T)(object)(short)((short)(object)left - (short)(object)right);
3675 else if (typeof(T) == typeof(uint))
3677 return (T)(object)(uint)((uint)(object)left - (uint)(object)right);
3679 else if (typeof(T) == typeof(int))
3681 return (T)(object)(int)((int)(object)left - (int)(object)right);
3683 else if (typeof(T) == typeof(ulong))
3685 return (T)(object)(ulong)((ulong)(object)left - (ulong)(object)right);
3687 else if (typeof(T) == typeof(long))
3689 return (T)(object)(long)((long)(object)left - (long)(object)right);
3691 else if (typeof(T) == typeof(float))
3693 return (T)(object)(float)((float)(object)left - (float)(object)right);
3695 else if (typeof(T) == typeof(double))
3697 return (T)(object)(double)((double)(object)left - (double)(object)right);
3699 else
3701 throw new NotSupportedException(SR.Arg_TypeNotSupported);
3705 [MethodImpl(MethodImplOptions.AggressiveInlining)]
3706 private static T ScalarMultiply(T left, T right)
3708 if (typeof(T) == typeof(byte))
3710 return (T)(object)unchecked((byte)((byte)(object)left * (byte)(object)right));
3712 else if (typeof(T) == typeof(sbyte))
3714 return (T)(object)unchecked((sbyte)((sbyte)(object)left * (sbyte)(object)right));
3716 else if (typeof(T) == typeof(ushort))
3718 return (T)(object)unchecked((ushort)((ushort)(object)left * (ushort)(object)right));
3720 else if (typeof(T) == typeof(short))
3722 return (T)(object)unchecked((short)((short)(object)left * (short)(object)right));
3724 else if (typeof(T) == typeof(uint))
3726 return (T)(object)unchecked((uint)((uint)(object)left * (uint)(object)right));
3728 else if (typeof(T) == typeof(int))
3730 return (T)(object)unchecked((int)((int)(object)left * (int)(object)right));
3732 else if (typeof(T) == typeof(ulong))
3734 return (T)(object)unchecked((ulong)((ulong)(object)left * (ulong)(object)right));
3736 else if (typeof(T) == typeof(long))
3738 return (T)(object)unchecked((long)((long)(object)left * (long)(object)right));
3740 else if (typeof(T) == typeof(float))
3742 return (T)(object)unchecked((float)((float)(object)left * (float)(object)right));
3744 else if (typeof(T) == typeof(double))
3746 return (T)(object)unchecked((double)((double)(object)left * (double)(object)right));
3748 else
3750 throw new NotSupportedException(SR.Arg_TypeNotSupported);
3754 [MethodImpl(MethodImplOptions.AggressiveInlining)]
3755 private static T ScalarDivide(T left, T right)
3757 if (typeof(T) == typeof(byte))
3759 return (T)(object)(byte)((byte)(object)left / (byte)(object)right);
3761 else if (typeof(T) == typeof(sbyte))
3763 return (T)(object)(sbyte)((sbyte)(object)left / (sbyte)(object)right);
3765 else if (typeof(T) == typeof(ushort))
3767 return (T)(object)(ushort)((ushort)(object)left / (ushort)(object)right);
3769 else if (typeof(T) == typeof(short))
3771 return (T)(object)(short)((short)(object)left / (short)(object)right);
3773 else if (typeof(T) == typeof(uint))
3775 return (T)(object)(uint)((uint)(object)left / (uint)(object)right);
3777 else if (typeof(T) == typeof(int))
3779 return (T)(object)(int)((int)(object)left / (int)(object)right);
3781 else if (typeof(T) == typeof(ulong))
3783 return (T)(object)(ulong)((ulong)(object)left / (ulong)(object)right);
3785 else if (typeof(T) == typeof(long))
3787 return (T)(object)(long)((long)(object)left / (long)(object)right);
3789 else if (typeof(T) == typeof(float))
3791 return (T)(object)(float)((float)(object)left / (float)(object)right);
3793 else if (typeof(T) == typeof(double))
3795 return (T)(object)(double)((double)(object)left / (double)(object)right);
3797 else
3799 throw new NotSupportedException(SR.Arg_TypeNotSupported);
3803 [MethodImpl(MethodImplOptions.AggressiveInlining)]
3804 private static T GetOneValue()
3806 if (typeof(T) == typeof(byte))
3808 byte value = 1;
3809 return (T)(object)value;
3811 else if (typeof(T) == typeof(sbyte))
3813 sbyte value = 1;
3814 return (T)(object)value;
3816 else if (typeof(T) == typeof(ushort))
3818 ushort value = 1;
3819 return (T)(object)value;
3821 else if (typeof(T) == typeof(short))
3823 short value = 1;
3824 return (T)(object)value;
3826 else if (typeof(T) == typeof(uint))
3828 uint value = 1;
3829 return (T)(object)value;
3831 else if (typeof(T) == typeof(int))
3833 int value = 1;
3834 return (T)(object)value;
3836 else if (typeof(T) == typeof(ulong))
3838 ulong value = 1;
3839 return (T)(object)value;
3841 else if (typeof(T) == typeof(long))
3843 long value = 1;
3844 return (T)(object)value;
3846 else if (typeof(T) == typeof(float))
3848 float value = 1;
3849 return (T)(object)value;
3851 else if (typeof(T) == typeof(double))
3853 double value = 1;
3854 return (T)(object)value;
3856 else
3858 throw new NotSupportedException(SR.Arg_TypeNotSupported);
3862 [MethodImpl(MethodImplOptions.AggressiveInlining)]
3863 private static T GetAllBitsSetValue()
3865 if (typeof(T) == typeof(byte))
3867 return (T)(object)ConstantHelper.GetByteWithAllBitsSet();
3869 else if (typeof(T) == typeof(sbyte))
3871 return (T)(object)ConstantHelper.GetSByteWithAllBitsSet();
3873 else if (typeof(T) == typeof(ushort))
3875 return (T)(object)ConstantHelper.GetUInt16WithAllBitsSet();
3877 else if (typeof(T) == typeof(short))
3879 return (T)(object)ConstantHelper.GetInt16WithAllBitsSet();
3881 else if (typeof(T) == typeof(uint))
3883 return (T)(object)ConstantHelper.GetUInt32WithAllBitsSet();
3885 else if (typeof(T) == typeof(int))
3887 return (T)(object)ConstantHelper.GetInt32WithAllBitsSet();
3889 else if (typeof(T) == typeof(ulong))
3891 return (T)(object)ConstantHelper.GetUInt64WithAllBitsSet();
3893 else if (typeof(T) == typeof(long))
3895 return (T)(object)ConstantHelper.GetInt64WithAllBitsSet();
3897 else if (typeof(T) == typeof(float))
3899 return (T)(object)ConstantHelper.GetSingleWithAllBitsSet();
3901 else if (typeof(T) == typeof(double))
3903 return (T)(object)ConstantHelper.GetDoubleWithAllBitsSet();
3905 else
3907 throw new NotSupportedException(SR.Arg_TypeNotSupported);
3910 #endregion
3913 [Intrinsic]
3914 public static partial class Vector
3916 #region Widen/Narrow
3917 /// <summary>
3918 /// Widens a Vector{Byte} into two Vector{UInt16}'s.
3919 /// <param name="source">The source vector whose elements are widened into the outputs.</param>
3920 /// <param name="low">The first output vector, whose elements will contain the widened elements from lower indices in the source vector.</param>
3921 /// <param name="high">The second output vector, whose elements will contain the widened elements from higher indices in the source vector.</param>
3922 /// </summary>
3923 [CLSCompliant(false)]
3924 [Intrinsic]
3925 public static unsafe void Widen(Vector<byte> source, out Vector<ushort> low, out Vector<ushort> high)
3927 int elements = Vector<byte>.Count;
3928 ushort* lowPtr = stackalloc ushort[elements / 2];
3929 for (int i = 0; i < elements / 2; i++)
3931 lowPtr[i] = (ushort)source[i];
3933 ushort* highPtr = stackalloc ushort[elements / 2];
3934 for (int i = 0; i < elements / 2; i++)
3936 highPtr[i] = (ushort)source[i + (elements / 2)];
3939 low = new Vector<ushort>(lowPtr);
3940 high = new Vector<ushort>(highPtr);
3943 /// <summary>
3944 /// Widens a Vector{UInt16} into two Vector{UInt32}'s.
3945 /// <param name="source">The source vector whose elements are widened into the outputs.</param>
3946 /// <param name="low">The first output vector, whose elements will contain the widened elements from lower indices in the source vector.</param>
3947 /// <param name="high">The second output vector, whose elements will contain the widened elements from higher indices in the source vector.</param>
3948 /// </summary>
3949 [CLSCompliant(false)]
3950 [Intrinsic]
3951 public static unsafe void Widen(Vector<ushort> source, out Vector<uint> low, out Vector<uint> high)
3953 int elements = Vector<ushort>.Count;
3954 uint* lowPtr = stackalloc uint[elements / 2];
3955 for (int i = 0; i < elements / 2; i++)
3957 lowPtr[i] = (uint)source[i];
3959 uint* highPtr = stackalloc uint[elements / 2];
3960 for (int i = 0; i < elements / 2; i++)
3962 highPtr[i] = (uint)source[i + (elements / 2)];
3965 low = new Vector<uint>(lowPtr);
3966 high = new Vector<uint>(highPtr);
3969 /// <summary>
3970 /// Widens a Vector{UInt32} into two Vector{UInt64}'s.
3971 /// <param name="source">The source vector whose elements are widened into the outputs.</param>
3972 /// <param name="low">The first output vector, whose elements will contain the widened elements from lower indices in the source vector.</param>
3973 /// <param name="high">The second output vector, whose elements will contain the widened elements from higher indices in the source vector.</param>
3974 /// </summary>
3975 [CLSCompliant(false)]
3976 [Intrinsic]
3977 public static unsafe void Widen(Vector<uint> source, out Vector<ulong> low, out Vector<ulong> high)
3979 int elements = Vector<uint>.Count;
3980 ulong* lowPtr = stackalloc ulong[elements / 2];
3981 for (int i = 0; i < elements / 2; i++)
3983 lowPtr[i] = (ulong)source[i];
3985 ulong* highPtr = stackalloc ulong[elements / 2];
3986 for (int i = 0; i < elements / 2; i++)
3988 highPtr[i] = (ulong)source[i + (elements / 2)];
3991 low = new Vector<ulong>(lowPtr);
3992 high = new Vector<ulong>(highPtr);
3995 /// <summary>
3996 /// Widens a Vector{SByte} into two Vector{Int16}'s.
3997 /// <param name="source">The source vector whose elements are widened into the outputs.</param>
3998 /// <param name="low">The first output vector, whose elements will contain the widened elements from lower indices in the source vector.</param>
3999 /// <param name="high">The second output vector, whose elements will contain the widened elements from higher indices in the source vector.</param>
4000 /// </summary>
4001 [CLSCompliant(false)]
4002 [Intrinsic]
4003 public static unsafe void Widen(Vector<sbyte> source, out Vector<short> low, out Vector<short> high)
4005 int elements = Vector<sbyte>.Count;
4006 short* lowPtr = stackalloc short[elements / 2];
4007 for (int i = 0; i < elements / 2; i++)
4009 lowPtr[i] = (short)source[i];
4011 short* highPtr = stackalloc short[elements / 2];
4012 for (int i = 0; i < elements / 2; i++)
4014 highPtr[i] = (short)source[i + (elements / 2)];
4017 low = new Vector<short>(lowPtr);
4018 high = new Vector<short>(highPtr);
4021 /// <summary>
4022 /// Widens a Vector{Int16} into two Vector{Int32}'s.
4023 /// <param name="source">The source vector whose elements are widened into the outputs.</param>
4024 /// <param name="low">The first output vector, whose elements will contain the widened elements from lower indices in the source vector.</param>
4025 /// <param name="high">The second output vector, whose elements will contain the widened elements from higher indices in the source vector.</param>
4026 /// </summary>
4027 [Intrinsic]
4028 public static unsafe void Widen(Vector<short> source, out Vector<int> low, out Vector<int> high)
4030 int elements = Vector<short>.Count;
4031 int* lowPtr = stackalloc int[elements / 2];
4032 for (int i = 0; i < elements / 2; i++)
4034 lowPtr[i] = (int)source[i];
4036 int* highPtr = stackalloc int[elements / 2];
4037 for (int i = 0; i < elements / 2; i++)
4039 highPtr[i] = (int)source[i + (elements / 2)];
4042 low = new Vector<int>(lowPtr);
4043 high = new Vector<int>(highPtr);
4046 /// <summary>
4047 /// Widens a Vector{Int32} into two Vector{Int64}'s.
4048 /// <param name="source">The source vector whose elements are widened into the outputs.</param>
4049 /// <param name="low">The first output vector, whose elements will contain the widened elements from lower indices in the source vector.</param>
4050 /// <param name="high">The second output vector, whose elements will contain the widened elements from higher indices in the source vector.</param>
4051 /// </summary>
4052 [Intrinsic]
4053 public static unsafe void Widen(Vector<int> source, out Vector<long> low, out Vector<long> high)
4055 int elements = Vector<int>.Count;
4056 long* lowPtr = stackalloc long[elements / 2];
4057 for (int i = 0; i < elements / 2; i++)
4059 lowPtr[i] = (long)source[i];
4061 long* highPtr = stackalloc long[elements / 2];
4062 for (int i = 0; i < elements / 2; i++)
4064 highPtr[i] = (long)source[i + (elements / 2)];
4067 low = new Vector<long>(lowPtr);
4068 high = new Vector<long>(highPtr);
4071 /// <summary>
4072 /// Widens a Vector{Single} into two Vector{Double}'s.
4073 /// <param name="source">The source vector whose elements are widened into the outputs.</param>
4074 /// <param name="low">The first output vector, whose elements will contain the widened elements from lower indices in the source vector.</param>
4075 /// <param name="high">The second output vector, whose elements will contain the widened elements from higher indices in the source vector.</param>
4076 /// </summary>
4077 [Intrinsic]
4078 public static unsafe void Widen(Vector<float> source, out Vector<double> low, out Vector<double> high)
4080 int elements = Vector<float>.Count;
4081 double* lowPtr = stackalloc double[elements / 2];
4082 for (int i = 0; i < elements / 2; i++)
4084 lowPtr[i] = (double)source[i];
4086 double* highPtr = stackalloc double[elements / 2];
4087 for (int i = 0; i < elements / 2; i++)
4089 highPtr[i] = (double)source[i + (elements / 2)];
4092 low = new Vector<double>(lowPtr);
4093 high = new Vector<double>(highPtr);
4096 /// <summary>
4097 /// Narrows two Vector{UInt16}'s into one Vector{Byte}.
4098 /// <param name="low">The first source vector, whose elements become the lower-index elements of the return value.</param>
4099 /// <param name="high">The second source vector, whose elements become the higher-index elements of the return value.</param>
4100 /// <returns>A Vector{Byte} containing elements narrowed from the source vectors.</returns>
4101 /// </summary>
4102 [CLSCompliant(false)]
4103 [Intrinsic]
4104 public static unsafe Vector<byte> Narrow(Vector<ushort> low, Vector<ushort> high)
4106 unchecked
4108 int elements = Vector<byte>.Count;
4109 byte* retPtr = stackalloc byte[elements];
4110 for (int i = 0; i < elements / 2; i++)
4112 retPtr[i] = (byte)low[i];
4114 for (int i = 0; i < elements / 2; i++)
4116 retPtr[i + (elements / 2)] = (byte)high[i];
4119 return new Vector<byte>(retPtr);
4123 /// <summary>
4124 /// Narrows two Vector{UInt32}'s into one Vector{UInt16}.
4125 /// <param name="low">The first source vector, whose elements become the lower-index elements of the return value.</param>
4126 /// <param name="high">The second source vector, whose elements become the higher-index elements of the return value.</param>
4127 /// <returns>A Vector{UInt16} containing elements narrowed from the source vectors.</returns>
4128 /// </summary>
4129 [CLSCompliant(false)]
4130 [Intrinsic]
4131 public static unsafe Vector<ushort> Narrow(Vector<uint> low, Vector<uint> high)
4133 unchecked
4135 int elements = Vector<ushort>.Count;
4136 ushort* retPtr = stackalloc ushort[elements];
4137 for (int i = 0; i < elements / 2; i++)
4139 retPtr[i] = (ushort)low[i];
4141 for (int i = 0; i < elements / 2; i++)
4143 retPtr[i + (elements / 2)] = (ushort)high[i];
4146 return new Vector<ushort>(retPtr);
4150 /// <summary>
4151 /// Narrows two Vector{UInt64}'s into one Vector{UInt32}.
4152 /// <param name="low">The first source vector, whose elements become the lower-index elements of the return value.</param>
4153 /// <param name="high">The second source vector, whose elements become the higher-index elements of the return value.</param>
4154 /// <returns>A Vector{UInt32} containing elements narrowed from the source vectors.</returns>
4155 /// </summary>
4156 [CLSCompliant(false)]
4157 [Intrinsic]
4158 public static unsafe Vector<uint> Narrow(Vector<ulong> low, Vector<ulong> high)
4160 unchecked
4162 int elements = Vector<uint>.Count;
4163 uint* retPtr = stackalloc uint[elements];
4164 for (int i = 0; i < elements / 2; i++)
4166 retPtr[i] = (uint)low[i];
4168 for (int i = 0; i < elements / 2; i++)
4170 retPtr[i + (elements / 2)] = (uint)high[i];
4173 return new Vector<uint>(retPtr);
4177 /// <summary>
4178 /// Narrows two Vector{Int16}'s into one Vector{SByte}.
4179 /// <param name="low">The first source vector, whose elements become the lower-index elements of the return value.</param>
4180 /// <param name="high">The second source vector, whose elements become the higher-index elements of the return value.</param>
4181 /// <returns>A Vector{SByte} containing elements narrowed from the source vectors.</returns>
4182 /// </summary>
4183 [CLSCompliant(false)]
4184 [Intrinsic]
4185 public static unsafe Vector<sbyte> Narrow(Vector<short> low, Vector<short> high)
4187 unchecked
4189 int elements = Vector<sbyte>.Count;
4190 sbyte* retPtr = stackalloc sbyte[elements];
4191 for (int i = 0; i < elements / 2; i++)
4193 retPtr[i] = (sbyte)low[i];
4195 for (int i = 0; i < elements / 2; i++)
4197 retPtr[i + (elements / 2)] = (sbyte)high[i];
4200 return new Vector<sbyte>(retPtr);
4204 /// <summary>
4205 /// Narrows two Vector{Int32}'s into one Vector{Int16}.
4206 /// <param name="low">The first source vector, whose elements become the lower-index elements of the return value.</param>
4207 /// <param name="high">The second source vector, whose elements become the higher-index elements of the return value.</param>
4208 /// <returns>A Vector{Int16} containing elements narrowed from the source vectors.</returns>
4209 /// </summary>
4210 [Intrinsic]
4211 public static unsafe Vector<short> Narrow(Vector<int> low, Vector<int> high)
4213 unchecked
4215 int elements = Vector<short>.Count;
4216 short* retPtr = stackalloc short[elements];
4217 for (int i = 0; i < elements / 2; i++)
4219 retPtr[i] = (short)low[i];
4221 for (int i = 0; i < elements / 2; i++)
4223 retPtr[i + (elements / 2)] = (short)high[i];
4226 return new Vector<short>(retPtr);
4230 /// <summary>
4231 /// Narrows two Vector{Int64}'s into one Vector{Int32}.
4232 /// <param name="low">The first source vector, whose elements become the lower-index elements of the return value.</param>
4233 /// <param name="high">The second source vector, whose elements become the higher-index elements of the return value.</param>
4234 /// <returns>A Vector{Int32} containing elements narrowed from the source vectors.</returns>
4235 /// </summary>
4236 [Intrinsic]
4237 public static unsafe Vector<int> Narrow(Vector<long> low, Vector<long> high)
4239 unchecked
4241 int elements = Vector<int>.Count;
4242 int* retPtr = stackalloc int[elements];
4243 for (int i = 0; i < elements / 2; i++)
4245 retPtr[i] = (int)low[i];
4247 for (int i = 0; i < elements / 2; i++)
4249 retPtr[i + (elements / 2)] = (int)high[i];
4252 return new Vector<int>(retPtr);
4256 /// <summary>
4257 /// Narrows two Vector{Double}'s into one Vector{Single}.
4258 /// <param name="low">The first source vector, whose elements become the lower-index elements of the return value.</param>
4259 /// <param name="high">The second source vector, whose elements become the higher-index elements of the return value.</param>
4260 /// <returns>A Vector{Single} containing elements narrowed from the source vectors.</returns>
4261 /// </summary>
4262 [Intrinsic]
4263 public static unsafe Vector<float> Narrow(Vector<double> low, Vector<double> high)
4265 unchecked
4267 int elements = Vector<float>.Count;
4268 float* retPtr = stackalloc float[elements];
4269 for (int i = 0; i < elements / 2; i++)
4271 retPtr[i] = (float)low[i];
4273 for (int i = 0; i < elements / 2; i++)
4275 retPtr[i + (elements / 2)] = (float)high[i];
4278 return new Vector<float>(retPtr);
4282 #endregion Widen/Narrow
4284 #region Same-Size Conversion
4285 /// <summary>
4286 /// Converts a Vector{Int32} to a Vector{Single}.
4287 /// </summary>
4288 /// <param name="value">The source vector.</param>
4289 /// <returns>The converted vector.</returns>
4290 [Intrinsic]
4291 public static unsafe Vector<float> ConvertToSingle(Vector<int> value)
4293 unchecked
4295 int elements = Vector<float>.Count;
4296 float* retPtr = stackalloc float[elements];
4297 for (int i = 0; i < elements; i++)
4299 retPtr[i] = (float)value[i];
4302 return new Vector<float>(retPtr);
4306 /// <summary>
4307 /// Converts a Vector{UInt32} to a Vector{Single}.
4308 /// </summary>
4309 /// <param name="value">The source vector.</param>
4310 /// <returns>The converted vector.</returns>
4311 [CLSCompliant(false)]
4312 [Intrinsic]
4313 public static unsafe Vector<float> ConvertToSingle(Vector<uint> value)
4315 unchecked
4317 int elements = Vector<float>.Count;
4318 float* retPtr = stackalloc float[elements];
4319 for (int i = 0; i < elements; i++)
4321 retPtr[i] = (float)value[i];
4324 return new Vector<float>(retPtr);
4328 /// <summary>
4329 /// Converts a Vector{Int64} to a Vector{Double}.
4330 /// </summary>
4331 /// <param name="value">The source vector.</param>
4332 /// <returns>The converted vector.</returns>
4333 [Intrinsic]
4334 public static unsafe Vector<double> ConvertToDouble(Vector<long> value)
4336 unchecked
4338 int elements = Vector<double>.Count;
4339 double* retPtr = stackalloc double[elements];
4340 for (int i = 0; i < elements; i++)
4342 retPtr[i] = (double)value[i];
4345 return new Vector<double>(retPtr);
4349 /// <summary>
4350 /// Converts a Vector{UInt64} to a Vector{Double}.
4351 /// </summary>
4352 /// <param name="value">The source vector.</param>
4353 /// <returns>The converted vector.</returns>
4354 [CLSCompliant(false)]
4355 [Intrinsic]
4356 public static unsafe Vector<double> ConvertToDouble(Vector<ulong> value)
4358 unchecked
4360 int elements = Vector<double>.Count;
4361 double* retPtr = stackalloc double[elements];
4362 for (int i = 0; i < elements; i++)
4364 retPtr[i] = (double)value[i];
4367 return new Vector<double>(retPtr);
4371 /// <summary>
4372 /// Converts a Vector{Single} to a Vector{Int32}.
4373 /// </summary>
4374 /// <param name="value">The source vector.</param>
4375 /// <returns>The converted vector.</returns>
4376 [Intrinsic]
4377 public static unsafe Vector<int> ConvertToInt32(Vector<float> value)
4379 unchecked
4381 int elements = Vector<int>.Count;
4382 int* retPtr = stackalloc int[elements];
4383 for (int i = 0; i < elements; i++)
4385 retPtr[i] = (int)value[i];
4388 return new Vector<int>(retPtr);
4392 /// <summary>
4393 /// Converts a Vector{Single} to a Vector{UInt32}.
4394 /// </summary>
4395 /// <param name="value">The source vector.</param>
4396 /// <returns>The converted vector.</returns>
4397 [CLSCompliant(false)]
4398 [Intrinsic]
4399 public static unsafe Vector<uint> ConvertToUInt32(Vector<float> value)
4401 unchecked
4403 int elements = Vector<uint>.Count;
4404 uint* retPtr = stackalloc uint[elements];
4405 for (int i = 0; i < elements; i++)
4407 retPtr[i] = (uint)value[i];
4410 return new Vector<uint>(retPtr);
4414 /// <summary>
4415 /// Converts a Vector{Double} to a Vector{Int64}.
4416 /// </summary>
4417 /// <param name="value">The source vector.</param>
4418 /// <returns>The converted vector.</returns>
4419 [Intrinsic]
4420 public static unsafe Vector<long> ConvertToInt64(Vector<double> value)
4422 unchecked
4424 int elements = Vector<long>.Count;
4425 long* retPtr = stackalloc long[elements];
4426 for (int i = 0; i < elements; i++)
4428 retPtr[i] = (long)value[i];
4431 return new Vector<long>(retPtr);
4435 /// <summary>
4436 /// Converts a Vector{Double} to a Vector{UInt64}.
4437 /// </summary>
4438 /// <param name="value">The source vector.</param>
4439 /// <returns>The converted vector.</returns>
4440 [CLSCompliant(false)]
4441 [Intrinsic]
4442 public static unsafe Vector<ulong> ConvertToUInt64(Vector<double> value)
4444 unchecked
4446 int elements = Vector<ulong>.Count;
4447 ulong* retPtr = stackalloc ulong[elements];
4448 for (int i = 0; i < elements; i++)
4450 retPtr[i] = (ulong)value[i];
4453 return new Vector<ulong>(retPtr);
4457 #endregion Same-Size Conversion
4459 #region Throw Helpers
4460 [DoesNotReturn]
4461 internal static void ThrowInsufficientNumberOfElementsException(int requiredElementCount)
4463 throw new IndexOutOfRangeException(SR.Format(SR.Arg_InsufficientNumberOfElements, requiredElementCount, "values"));
4465 #endregion