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
;
11 using Internal
.Runtime
.CompilerServices
;
13 #pragma warning disable SA1121 // explicitly using type aliases instead of built-in types
15 using nint
= System
.Int64
;
17 using nint
= System
.Int32
;
20 namespace System
.Numerics
22 /* Note: The following patterns are used throughout the code here and are described here
25 * if (typeof(T) == typeof(int)) { ... }
26 * else if (typeof(T) == typeof(float)) { ... }
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.
33 * if (Vector.IsHardwareAccelerated) { ... }
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 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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.
52 public struct Vector
<T
> : IEquatable
<Vector
<T
>>, IFormattable where T
: struct
55 private Register register
;
58 #region Static Members
60 /// Returns the number of elements stored in the vector. This value is hardware dependent.
62 public static int Count
67 ThrowHelper
.ThrowForUnsupportedVectorBaseType
<T
>();
68 return Unsafe
.SizeOf
<Vector
<T
>>() / Unsafe
.SizeOf
<T
>();
73 /// Returns a vector containing all zeroes.
75 public static Vector
<T
> Zero
80 private static readonly Vector
<T
> s_zero
= new Vector
<T
>();
83 /// Returns a vector containing all ones.
85 public static Vector
<T
> One
90 private static readonly Vector
<T
> s_one
= new Vector
<T
>(GetOneValue());
92 internal static Vector
<T
> AllOnes
97 private static readonly Vector
<T
> s_allOnes
= new Vector
<T
>(GetAllBitsSetValue());
98 #endregion Static Members
102 /// Constructs a vector whose components are all <code>value</code>
105 public unsafe Vector(T
value)
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;
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;
313 /// Constructs a vector from the given array. The size of the given array must be at least Vector'T.Count.
316 public unsafe Vector(T
[] values
) : this(values
, 0) { }
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.
323 public unsafe Vector(T
[] values
, int index
)
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
;
349 /// Constructs a vector from the given <see cref="ReadOnlySpan{Byte}"/>. The span must contain at least <see cref="Vector{Byte}.Count"/> elements.
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
));
363 /// Constructs a vector from the given <see cref="ReadOnlySpan{T}"/>. The span must contain at least <see cref="Vector{T}.Count"/> elements.
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
)));
376 /// Constructs a vector from the given <see cref="Span{T}"/>. The span must contain at least <see cref="Vector{T}.Count"/> elements.
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
391 /// Copies the vector to the given <see cref="Span{Byte}"/>. The destination span must be at least size <see cref="Vector{Byte}.Count"/>.
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);
407 /// Copies the vector to the given <see cref="Span{T}"/>. The destination span must be at least size <see cref="Vector{T}.Count"/>.
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);
422 /// Copies the vector to the given destination array. The destination array must be at least size Vector'T.Count.
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>
428 public readonly void CopyTo(T
[] destination
)
430 CopyTo(destination
, 0);
434 /// Copies the vector to the given destination array. The destination array must be at least size Vector'T.Count.
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>
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);
462 /// Returns the element at the given index.
464 public readonly unsafe T
this[int index
]
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
);
479 /// Returns a boolean indicating whether the given Object is equal to this vector instance.
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 [MethodImplAttribute(MethodImplOptions
.AggressiveInlining
)]
484 public override readonly bool Equals(object? obj
)
486 if (!(obj
is Vector
<T
>))
490 return Equals((Vector
<T
>)obj
);
494 /// Returns a boolean indicating whether the given vector is equal to this vector instance.
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>
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
]))
514 if (typeof(T
) == typeof(byte))
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))
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))
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))
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))
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))
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))
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))
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))
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))
617 this.register
.double_0
== other
.register
.double_0
618 && this.register
.double_1
== other
.register
.double_1
;
622 throw new NotSupportedException(SR
.Arg_TypeNotSupported
);
628 /// Returns the hash code for this instance.
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
));
665 throw new NotSupportedException(SR
.Arg_TypeNotSupported
);
668 return hashCode
.ToHashCode();
672 /// Returns a String representing this vector.
674 /// <returns>The string representation.</returns>
675 public override readonly string ToString()
677 return ToString("G", CultureInfo
.CurrentCulture
);
681 /// Returns a String representing this vector, using the specified format string to format individual elements.
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
);
691 /// Returns a String representing this vector, using the specified format string to format individual elements
692 /// and the given IFormatProvider.
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
;
702 for (int g
= 0; g
< Count
- 1; g
++)
704 sb
.Append(((IFormattable
)this[g
]).ToString(format
, formatProvider
));
705 sb
.Append(separator
);
708 // Append last element w/out separator
709 sb
.Append(((IFormattable
)this[Count
- 1]).ToString(format
, formatProvider
));
711 return sb
.ToString();
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"/>.
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
)
728 Unsafe
.WriteUnaligned
<Vector
<T
>>(ref MemoryMarshal
.GetReference(destination
), this);
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"/>.
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
)
745 Unsafe
.WriteUnaligned
<Vector
<T
>>(ref Unsafe
.As
<T
, byte>(ref MemoryMarshal
.GetReference(destination
)), this);
748 #endregion Public Instance Methods
750 #region Arithmetic Operators
752 /// Adds two vectors together.
754 /// <param name="left">The first source vector.</param>
755 /// <param name="right">The second source vector.</param>
756 /// <returns>The summed vector.</returns>
758 public static unsafe Vector
<T
> operator +(Vector
<T
> left
, Vector
<T
> right
)
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
);
856 throw new NotSupportedException(SR
.Arg_TypeNotSupported
);
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
);
964 /// Subtracts the second vector from the first.
966 /// <param name="left">The first source vector.</param>
967 /// <param name="right">The second source vector.</param>
968 /// <returns>The difference vector.</returns>
970 public static unsafe Vector
<T
> operator -(Vector
<T
> left
, Vector
<T
> right
)
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
);
1068 throw new NotSupportedException(SR
.Arg_TypeNotSupported
);
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
);
1175 // This method is intrinsic only for certain types. It cannot access fields directly unless we are sure the context is unaccelerated.
1177 /// Multiplies two vectors together.
1179 /// <param name="left">The first source vector.</param>
1180 /// <param name="right">The second source vector.</param>
1181 /// <returns>The product vector.</returns>
1183 public static unsafe Vector
<T
> operator *(Vector
<T
> left
, Vector
<T
> right
)
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
);
1281 throw new NotSupportedException(SR
.Arg_TypeNotSupported
);
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
);
1389 /// Multiplies a vector by the given scalar.
1391 /// <param name="value">The source vector.</param>
1392 /// <param name="factor">The scalar value.</param>
1393 /// <returns>The scaled vector.</returns>
1394 [MethodImplAttribute(MethodImplOptions
.AggressiveInlining
)]
1395 public static Vector
<T
> operator *(Vector
<T
> value, T factor
) =>
1396 new Vector
<T
>(factor
) * value;
1399 /// Multiplies a vector by the given scalar.
1401 /// <param name="factor">The scalar value.</param>
1402 /// <param name="value">The source vector.</param>
1403 /// <returns>The scaled vector.</returns>
1404 [MethodImplAttribute(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.
1410 /// Divides the first vector by the second.
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>
1416 public static unsafe Vector
<T
> operator /(Vector
<T
> left
, Vector
<T
> right
)
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
);
1514 throw new NotSupportedException(SR
.Arg_TypeNotSupported
);
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
);
1622 /// Negates a given vector.
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
1631 /// Returns a new vector by performing a bitwise-and operation on each of the elements in the given vectors.
1633 /// <param name="left">The first source vector.</param>
1634 /// <param name="right">The second source vector.</param>
1635 /// <returns>The resultant vector.</returns>
1637 public static unsafe Vector
<T
> operator &(Vector
<T
> left
, Vector
<T
> right
)
1639 Vector
<T
> result
= new Vector
<T
>();
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
];
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
;
1662 /// Returns a new vector by performing a bitwise-or operation on each of the elements in the given vectors.
1664 /// <param name="left">The first source vector.</param>
1665 /// <param name="right">The second source vector.</param>
1666 /// <returns>The resultant vector.</returns>
1668 public static unsafe Vector
<T
> operator |(Vector
<T
> left
, Vector
<T
> right
)
1670 Vector
<T
> result
= new Vector
<T
>();
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
];
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
;
1693 /// Returns a new vector by performing a bitwise-exclusive-or operation on each of the elements in the given vectors.
1695 /// <param name="left">The first source vector.</param>
1696 /// <param name="right">The second source vector.</param>
1697 /// <returns>The resultant vector.</returns>
1699 public static unsafe Vector
<T
> operator ^
(Vector
<T
> left
, Vector
<T
> right
)
1701 Vector
<T
> result
= new Vector
<T
>();
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
];
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
;
1724 /// Returns a new vector whose elements are obtained by taking the one's complement of the given vector's elements.
1726 /// <param name="value">The source vector.</param>
1727 /// <returns>The one's complement vector.</returns>
1728 [MethodImplAttribute(MethodImplOptions
.AggressiveInlining
)]
1729 public static Vector
<T
> operator ~
(Vector
<T
> value) =>
1731 #endregion Bitwise Operators
1733 #region Logical Operators
1735 /// Returns a boolean indicating whether each pair of elements in the given vectors are equal.
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>
1741 [MethodImplAttribute(MethodImplOptions
.AggressiveInlining
)]
1742 public static bool operator ==(Vector
<T
> left
, Vector
<T
> right
) =>
1746 /// Returns a boolean indicating whether any single pair of elements in the given vectors are not equal.
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>
1752 [MethodImplAttribute(MethodImplOptions
.AggressiveInlining
)]
1753 public static bool operator !=(Vector
<T
> left
, Vector
<T
> right
) => !(left
== right
);
1754 #endregion Logical Operators
1758 /// Reinterprets the bits of the given vector into those of another type.
1760 /// <param name="value">The source vector</param>
1761 /// <returns>The reinterpreted vector.</returns>
1763 public static explicit operator Vector
<byte>(Vector
<T
> value) =>
1764 new Vector
<byte>(ref value.register
);
1767 /// Reinterprets the bits of the given vector into those of another type.
1769 /// <param name="value">The source vector</param>
1770 /// <returns>The reinterpreted vector.</returns>
1771 [CLSCompliant(false)]
1773 public static explicit operator Vector
<sbyte>(Vector
<T
> value) =>
1774 new Vector
<sbyte>(ref value.register
);
1777 /// Reinterprets the bits of the given vector into those of another type.
1779 /// <param name="value">The source vector</param>
1780 /// <returns>The reinterpreted vector.</returns>
1781 [CLSCompliant(false)]
1783 public static explicit operator Vector
<ushort>(Vector
<T
> value) =>
1784 new Vector
<ushort>(ref value.register
);
1787 /// Reinterprets the bits of the given vector into those of another type.
1789 /// <param name="value">The source vector</param>
1790 /// <returns>The reinterpreted vector.</returns>
1792 public static explicit operator Vector
<short>(Vector
<T
> value) =>
1793 new Vector
<short>(ref value.register
);
1796 /// Reinterprets the bits of the given vector into those of another type.
1798 /// <param name="value">The source vector</param>
1799 /// <returns>The reinterpreted vector.</returns>
1800 [CLSCompliant(false)]
1802 public static explicit operator Vector
<uint>(Vector
<T
> value) =>
1803 new Vector
<uint>(ref value.register
);
1806 /// Reinterprets the bits of the given vector into those of another type.
1808 /// <param name="value">The source vector</param>
1809 /// <returns>The reinterpreted vector.</returns>
1811 public static explicit operator Vector
<int>(Vector
<T
> value) =>
1812 new Vector
<int>(ref value.register
);
1815 /// Reinterprets the bits of the given vector into those of another type.
1817 /// <param name="value">The source vector</param>
1818 /// <returns>The reinterpreted vector.</returns>
1819 [CLSCompliant(false)]
1821 public static explicit operator Vector
<ulong>(Vector
<T
> value) =>
1822 new Vector
<ulong>(ref value.register
);
1825 /// Reinterprets the bits of the given vector into those of another type.
1827 /// <param name="value">The source vector</param>
1828 /// <returns>The reinterpreted vector.</returns>
1830 public static explicit operator Vector
<long>(Vector
<T
> value) =>
1831 new Vector
<long>(ref value.register
);
1834 /// Reinterprets the bits of the given vector into those of another type.
1836 /// <param name="value">The source vector</param>
1837 /// <returns>The reinterpreted vector.</returns>
1839 public static explicit operator Vector
<float>(Vector
<T
> value) =>
1840 new Vector
<float>(ref value.register
);
1843 /// Reinterprets the bits of the given vector into those of another type.
1845 /// <param name="value">The source vector</param>
1846 /// <returns>The reinterpreted vector.</returns>
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
1855 [MethodImplAttribute(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
);
1952 throw new NotSupportedException(SR
.Arg_TypeNotSupported
);
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
);
2066 throw new NotSupportedException(SR
.Arg_TypeNotSupported
);
2072 [MethodImplAttribute(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
);
2169 throw new NotSupportedException(SR
.Arg_TypeNotSupported
);
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
);
2283 throw new NotSupportedException(SR
.Arg_TypeNotSupported
);
2289 [MethodImplAttribute(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
);
2386 throw new NotSupportedException(SR
.Arg_TypeNotSupported
);
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
);
2500 throw new NotSupportedException(SR
.Arg_TypeNotSupported
);
2506 internal static Vector
<T
> GreaterThanOrEqual(Vector
<T
> left
, Vector
<T
> right
)
2508 return Equals(left
, right
) | GreaterThan(left
, right
);
2512 internal static Vector
<T
> LessThanOrEqual(Vector
<T
> left
, Vector
<T
> right
)
2514 return Equals(left
, right
) | LessThan(left
, right
);
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
2526 internal static unsafe Vector
<T
> Abs(Vector
<T
> value)
2528 if (typeof(T
) == typeof(byte))
2532 else if (typeof(T
) == typeof(ushort))
2536 else if (typeof(T
) == typeof(uint))
2540 else if (typeof(T
) == typeof(ulong))
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
);
2602 throw new NotSupportedException(SR
.Arg_TypeNotSupported
);
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
));
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
));
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
));
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
));
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
));
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
));
2669 throw new NotSupportedException(SR
.Arg_TypeNotSupported
);
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
);
2771 throw new NotSupportedException(SR
.Arg_TypeNotSupported
);
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
2885 throw new NotSupportedException(SR
.Arg_TypeNotSupported
);
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
);
2987 throw new NotSupportedException(SR
.Arg_TypeNotSupported
);
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
3101 throw new NotSupportedException(SR
.Arg_TypeNotSupported
);
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
]));
3120 if (typeof(T
) == typeof(byte))
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))
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))
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))
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))
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))
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))
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))
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))
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))
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
;
3238 throw new NotSupportedException(SR
.Arg_TypeNotSupported
);
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
);
3340 throw new NotSupportedException(SR
.Arg_TypeNotSupported
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
3453 throw new NotSupportedException(SR
.Arg_TypeNotSupported
);
3457 #endregion Internal Math Methods
3459 #region Helper Methods
3460 [MethodImplAttribute(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
;
3505 throw new NotSupportedException(SR
.Arg_TypeNotSupported
);
3509 [MethodImplAttribute(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
;
3554 throw new NotSupportedException(SR
.Arg_TypeNotSupported
);
3558 [MethodImplAttribute(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
;
3603 throw new NotSupportedException(SR
.Arg_TypeNotSupported
);
3607 [MethodImplAttribute(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
));
3652 throw new NotSupportedException(SR
.Arg_TypeNotSupported
);
3656 [MethodImplAttribute(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
);
3701 throw new NotSupportedException(SR
.Arg_TypeNotSupported
);
3705 [MethodImplAttribute(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
));
3750 throw new NotSupportedException(SR
.Arg_TypeNotSupported
);
3754 [MethodImplAttribute(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
);
3799 throw new NotSupportedException(SR
.Arg_TypeNotSupported
);
3803 [MethodImplAttribute(MethodImplOptions
.AggressiveInlining
)]
3804 private static T
GetOneValue()
3806 if (typeof(T
) == typeof(byte))
3809 return (T
)(object)value;
3811 else if (typeof(T
) == typeof(sbyte))
3814 return (T
)(object)value;
3816 else if (typeof(T
) == typeof(ushort))
3819 return (T
)(object)value;
3821 else if (typeof(T
) == typeof(short))
3824 return (T
)(object)value;
3826 else if (typeof(T
) == typeof(uint))
3829 return (T
)(object)value;
3831 else if (typeof(T
) == typeof(int))
3834 return (T
)(object)value;
3836 else if (typeof(T
) == typeof(ulong))
3839 return (T
)(object)value;
3841 else if (typeof(T
) == typeof(long))
3844 return (T
)(object)value;
3846 else if (typeof(T
) == typeof(float))
3849 return (T
)(object)value;
3851 else if (typeof(T
) == typeof(double))
3854 return (T
)(object)value;
3858 throw new NotSupportedException(SR
.Arg_TypeNotSupported
);
3862 [MethodImplAttribute(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();
3907 throw new NotSupportedException(SR
.Arg_TypeNotSupported
);
3914 public static partial class Vector
3916 #region Widen/Narrow
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>
3923 [CLSCompliant(false)]
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
);
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>
3949 [CLSCompliant(false)]
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
);
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>
3975 [CLSCompliant(false)]
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
);
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>
4001 [CLSCompliant(false)]
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
);
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>
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
);
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>
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
);
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>
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
);
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>
4102 [CLSCompliant(false)]
4104 public static unsafe Vector
<byte> Narrow(Vector
<ushort> low
, Vector
<ushort> high
)
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
);
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>
4129 [CLSCompliant(false)]
4131 public static unsafe Vector
<ushort> Narrow(Vector
<uint> low
, Vector
<uint> high
)
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
);
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>
4156 [CLSCompliant(false)]
4158 public static unsafe Vector
<uint> Narrow(Vector
<ulong> low
, Vector
<ulong> high
)
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
);
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>
4183 [CLSCompliant(false)]
4185 public static unsafe Vector
<sbyte> Narrow(Vector
<short> low
, Vector
<short> high
)
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
);
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>
4211 public static unsafe Vector
<short> Narrow(Vector
<int> low
, Vector
<int> high
)
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
);
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>
4237 public static unsafe Vector
<int> Narrow(Vector
<long> low
, Vector
<long> high
)
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
);
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>
4263 public static unsafe Vector
<float> Narrow(Vector
<double> low
, Vector
<double> high
)
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
4286 /// Converts a Vector{Int32} to a Vector{Single}.
4288 /// <param name="value">The source vector.</param>
4289 /// <returns>The converted vector.</returns>
4291 public static unsafe Vector
<float> ConvertToSingle(Vector
<int> value)
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
);
4307 /// Converts a Vector{UInt32} to a Vector{Single}.
4309 /// <param name="value">The source vector.</param>
4310 /// <returns>The converted vector.</returns>
4311 [CLSCompliant(false)]
4313 public static unsafe Vector
<float> ConvertToSingle(Vector
<uint> value)
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
);
4329 /// Converts a Vector{Int64} to a Vector{Double}.
4331 /// <param name="value">The source vector.</param>
4332 /// <returns>The converted vector.</returns>
4334 public static unsafe Vector
<double> ConvertToDouble(Vector
<long> value)
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
);
4350 /// Converts a Vector{UInt64} to a Vector{Double}.
4352 /// <param name="value">The source vector.</param>
4353 /// <returns>The converted vector.</returns>
4354 [CLSCompliant(false)]
4356 public static unsafe Vector
<double> ConvertToDouble(Vector
<ulong> value)
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
);
4372 /// Converts a Vector{Single} to a Vector{Int32}.
4374 /// <param name="value">The source vector.</param>
4375 /// <returns>The converted vector.</returns>
4377 public static unsafe Vector
<int> ConvertToInt32(Vector
<float> value)
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
);
4393 /// Converts a Vector{Single} to a Vector{UInt32}.
4395 /// <param name="value">The source vector.</param>
4396 /// <returns>The converted vector.</returns>
4397 [CLSCompliant(false)]
4399 public static unsafe Vector
<uint> ConvertToUInt32(Vector
<float> value)
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
);
4415 /// Converts a Vector{Double} to a Vector{Int64}.
4417 /// <param name="value">The source vector.</param>
4418 /// <returns>The converted vector.</returns>
4420 public static unsafe Vector
<long> ConvertToInt64(Vector
<double> value)
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
);
4436 /// Converts a Vector{Double} to a Vector{UInt64}.
4438 /// <param name="value">The source vector.</param>
4439 /// <returns>The converted vector.</returns>
4440 [CLSCompliant(false)]
4442 public static unsafe Vector
<ulong> ConvertToUInt64(Vector
<double> value)
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
4461 internal static void ThrowInsufficientNumberOfElementsException(int requiredElementCount
)
4463 throw new IndexOutOfRangeException(SR
.Format(SR
.Arg_InsufficientNumberOfElements
, requiredElementCount
, "values"));