if (metadataType.IsIntrinsic)
{
string name = metadataType.Name;
- if ((name == "Vector`1" || name == "Vector") &&
- metadataType.Namespace == "System.Numerics")
+ if (((name == "Vector") || (name == "Vector`1") || (name == "Vector2") || (name == "Vector3") || (name == "Vector4")) &&
+ (metadataType.Namespace == "System.Numerics"))
return true;
}
}
LPCUTF8 namespaceName;
LPCUTF8 className = methodTable->GetFullyQualifiedNameInfo(&namespaceName);
- if (strcmp(className, "Vector`1") == 0 || strcmp(className, "Vector") == 0)
+ if (strncmp(className, "Vector", 6) == 0)
{
- assert(strcmp(namespaceName, "System.Numerics") == 0);
+ className += 6;
- result = true;
+ if ((className[0] == '\0') || (strcmp(className, "`1") == 0) || (strcmp(className, "2") == 0) || (strcmp(className, "3") == 0) || (strcmp(className, "4") == 0))
+ {
+ assert(strcmp(namespaceName, "System.Numerics") == 0);
+ result = true;
+ }
}
}
EE_TO_JIT_TRANSITION_LEAF();
<Compile Include="$(MSBuildThisFileDirectory)System\Number.NumberToFloatingPointBits.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Number.Parsing.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Numerics\BitOperations.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Numerics\Matrix3x2.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Numerics\Matrix4x4.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Numerics\Plane.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Numerics\Quaternion.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Numerics\Vector2.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Numerics\Vector2_Intrinsics.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Numerics\Vector3.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Numerics\Vector3_Intrinsics.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Numerics\Vector4.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Numerics\Vector4_Intrinsics.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Numerics\VectorMath.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\NullReferenceException.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Object.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\ObjectDisposedException.cs" />
using System.Globalization;
using System.Runtime.InteropServices;
-#if HAS_INTRINSICS
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
-#endif
namespace System.Numerics
{
/// <returns>The transposed matrix.</returns>
public static unsafe Matrix4x4 Transpose(Matrix4x4 matrix)
{
-#if HAS_INTRINSICS
if (Sse.IsSupported)
{
var row1 = Sse.LoadVector128(&matrix.M11);
return matrix;
}
-#endif
+
Matrix4x4 result;
result.M11 = matrix.M11;
/// <returns>The interpolated matrix.</returns>
public static unsafe Matrix4x4 Lerp(Matrix4x4 matrix1, Matrix4x4 matrix2, float amount)
{
-#if HAS_INTRINSICS
if (Sse.IsSupported)
{
Vector128<float> amountVec = Vector128.Create(amount);
Sse.Store(&matrix1.M41, VectorMath.Lerp(Sse.LoadVector128(&matrix1.M41), Sse.LoadVector128(&matrix2.M41), amountVec));
return matrix1;
}
-#endif
+
Matrix4x4 result;
// First row
/// <returns>The negated matrix.</returns>
public static unsafe Matrix4x4 operator -(Matrix4x4 value)
{
-#if HAS_INTRINSICS
if (Sse.IsSupported)
{
Vector128<float> zero = Vector128<float>.Zero;
return value;
}
-#endif
+
Matrix4x4 m;
m.M11 = -value.M11;
/// <returns>The resulting matrix.</returns>
public static unsafe Matrix4x4 operator +(Matrix4x4 value1, Matrix4x4 value2)
{
-#if HAS_INTRINSICS
if (Sse.IsSupported)
{
Sse.Store(&value1.M11, Sse.Add(Sse.LoadVector128(&value1.M11), Sse.LoadVector128(&value2.M11)));
Sse.Store(&value1.M41, Sse.Add(Sse.LoadVector128(&value1.M41), Sse.LoadVector128(&value2.M41)));
return value1;
}
-#endif
+
Matrix4x4 m;
m.M11 = value1.M11 + value2.M11;
/// <returns>The result of the subtraction.</returns>
public static unsafe Matrix4x4 operator -(Matrix4x4 value1, Matrix4x4 value2)
{
-#if HAS_INTRINSICS
if (Sse.IsSupported)
{
Sse.Store(&value1.M11, Sse.Subtract(Sse.LoadVector128(&value1.M11), Sse.LoadVector128(&value2.M11)));
Sse.Store(&value1.M41, Sse.Subtract(Sse.LoadVector128(&value1.M41), Sse.LoadVector128(&value2.M41)));
return value1;
}
-#endif
+
Matrix4x4 m;
m.M11 = value1.M11 - value2.M11;
/// <returns>The result of the multiplication.</returns>
public static unsafe Matrix4x4 operator *(Matrix4x4 value1, Matrix4x4 value2)
{
-#if HAS_INTRINSICS
if (Sse.IsSupported)
{
var row = Sse.LoadVector128(&value1.M11);
Sse.Multiply(Sse.Shuffle(row, row, 0xFF), Sse.LoadVector128(&value2.M41)))));
return value1;
}
-#endif
+
Matrix4x4 m;
// First row
/// <returns>The scaled matrix.</returns>
public static unsafe Matrix4x4 operator *(Matrix4x4 value1, float value2)
{
-#if HAS_INTRINSICS
if (Sse.IsSupported)
{
Vector128<float> value2Vec = Vector128.Create(value2);
Sse.Store(&value1.M41, Sse.Multiply(Sse.LoadVector128(&value1.M41), value2Vec));
return value1;
}
-#endif
+
Matrix4x4 m;
m.M11 = value1.M11 * value2;
/// <returns>True if the given matrices are equal; False otherwise.</returns>
public static unsafe bool operator ==(Matrix4x4 value1, Matrix4x4 value2)
{
-#if HAS_INTRINSICS
if (Sse.IsSupported)
{
return
VectorMath.Equal(Sse.LoadVector128(&value1.M31), Sse.LoadVector128(&value2.M31)) &&
VectorMath.Equal(Sse.LoadVector128(&value1.M41), Sse.LoadVector128(&value2.M41));
}
-#endif
+
return (value1.M11 == value2.M11 && value1.M22 == value2.M22 && value1.M33 == value2.M33 && value1.M44 == value2.M44 && // Check diagonal element first for early out.
value1.M12 == value2.M12 && value1.M13 == value2.M13 && value1.M14 == value2.M14 && value1.M21 == value2.M21 &&
value1.M23 == value2.M23 && value1.M24 == value2.M24 && value1.M31 == value2.M31 && value1.M32 == value2.M32 &&
/// <returns>True if the given matrices are not equal; False if they are equal.</returns>
public static unsafe bool operator !=(Matrix4x4 value1, Matrix4x4 value2)
{
-#if HAS_INTRINSICS
if (Sse.IsSupported)
{
return
VectorMath.NotEqual(Sse.LoadVector128(&value1.M31), Sse.LoadVector128(&value2.M31)) ||
VectorMath.NotEqual(Sse.LoadVector128(&value1.M41), Sse.LoadVector128(&value2.M41));
}
-#endif
+
return (value1.M11 != value2.M11 || value1.M12 != value2.M12 || value1.M13 != value2.M13 || value1.M14 != value2.M14 ||
value1.M21 != value2.M21 || value1.M22 != value2.M22 || value1.M23 != value2.M23 || value1.M24 != value2.M24 ||
value1.M31 != value2.M31 || value1.M32 != value2.M32 || value1.M33 != value2.M33 || value1.M34 != value2.M34 ||
/// <summary>
/// A structure encapsulating two single precision floating point values and provides hardware accelerated methods.
/// </summary>
+ [Intrinsic]
public partial struct Vector2 : IEquatable<Vector2>, IFormattable
{
#region Public Static Properties
/// <summary>
/// A structure encapsulating three single precision floating point values and provides hardware accelerated methods.
/// </summary>
+ [Intrinsic]
public partial struct Vector3 : IEquatable<Vector3>, IFormattable
{
#region Public Static Properties
/// <summary>
/// A structure encapsulating four single precision floating point values and provides hardware accelerated methods.
/// </summary>
+ [Intrinsic]
public partial struct Vector4 : IEquatable<Vector4>, IFormattable
{
#region Public Static Properties
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+
using System.Diagnostics;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System.Diagnostics;
+using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.Intrinsics.X86;
using Internal.Runtime.CompilerServices;
return vector.As<T, ulong>();
}
+ /// <summary>Reinterprets a <see cref="Vector2" /> as a new <see cref="Vector128{Single}" />.</summary>
+ /// <param name="value">The vector to reinterpret.</param>
+ /// <returns><paramref name="value" /> reinterpreted as a new <see cref="Vector128{Single}" />.</returns>
+ public static Vector128<float> AsVector128(this Vector2 value)
+ {
+ return new Vector4(value, 0.0f, 0.0f).AsVector128();
+ }
+
+ /// <summary>Reinterprets a <see cref="Vector3" /> as a new <see cref="Vector128{Single}" />.</summary>
+ /// <param name="value">The vector to reinterpret.</param>
+ /// <returns><paramref name="value" /> reinterpreted as a new <see cref="Vector128{Single}" />.</returns>
+ public static Vector128<float> AsVector128(this Vector3 value)
+ {
+ return new Vector4(value, 0.0f).AsVector128();
+ }
+
+ /// <summary>Reinterprets a <see cref="Vector4" /> as a new <see cref="Vector128{Single}" />.</summary>
+ /// <param name="value">The vector to reinterpret.</param>
+ /// <returns><paramref name="value" /> reinterpreted as a new <see cref="Vector128{Single}" />.</returns>
+ public static Vector128<float> AsVector128(this Vector4 value)
+ {
+ return Unsafe.As<Vector4, Vector128<float>>(ref value);
+ }
+
+ /// <summary>Reinterprets a <see cref="Vector{T}" /> as a new <see cref="Vector128{T}" />.</summary>
+ /// <typeparam name="T">The type of the vectors.</typeparam>
+ /// <param name="value">The vector to reinterpret.</param>
+ /// <returns><paramref name="value" /> reinterpreted as a new <see cref="Vector128{T}" />.</returns>
+ /// <exception cref="NotSupportedException">The type of <paramref name="value" /> (<typeparamref name="T" />) is not supported.</exception>
+ public static Vector128<T> AsVector128<T>(this Vector<T> value)
+ where T : struct
+ {
+ Debug.Assert(Vector<T>.Count >= Vector128<T>.Count);
+ ThrowHelper.ThrowForUnsupportedVectorBaseType<T>();
+ return Unsafe.As<Vector<T>, Vector128<T>>(ref value);
+ }
+
+ /// <summary>Reinterprets a <see cref="Vector128{Single}" /> as a new <see cref="Vector2" />.</summary>
+ /// <param name="value">The vector to reinterpret.</param>
+ /// <returns><paramref name="value" /> reinterpreted as a new <see cref="Vector2" />.</returns>
+ public static Vector2 AsVector2(this Vector128<float> value)
+ {
+ return Unsafe.As<Vector128<float>, Vector2>(ref value);
+ }
+
+ /// <summary>Reinterprets a <see cref="Vector128{Single}" /> as a new <see cref="Vector3" />.</summary>
+ /// <param name="value">The vector to reinterpret.</param>
+ /// <returns><paramref name="value" /> reinterpreted as a new <see cref="Vector3" />.</returns>
+ public static Vector3 AsVector3(this Vector128<float> value)
+ {
+ throw new PlatformNotSupportedException();
+ }
+
+ /// <summary>Reinterprets a <see cref="Vector128{Single}" /> as a new <see cref="Vector4" />.</summary>
+ /// <param name="value">The vector to reinterpret.</param>
+ /// <returns><paramref name="value" /> reinterpreted as a new <see cref="Vector4" />.</returns>
+ public static Vector4 AsVector4(this Vector128<float> value)
+ {
+ return Unsafe.As<Vector128<float>, Vector4>(ref value);
+ }
+
+ /// <summary>Reinterprets a <see cref="Vector128{T}" /> as a new <see cref="Vector{T}" />.</summary>
+ /// <typeparam name="T">The type of the vectors.</typeparam>
+ /// <param name="value">The vector to reinterpret.</param>
+ /// <returns><paramref name="value" /> reinterpreted as a new <see cref="Vector{T}" />.</returns>
+ /// <exception cref="NotSupportedException">The type of <paramref name="value" /> (<typeparamref name="T" />) is not supported.</exception>
+ public static Vector<T> AsVector<T>(this Vector128<T> value)
+ where T : struct
+ {
+ Debug.Assert(Vector<T>.Count >= Vector128<T>.Count);
+ ThrowHelper.ThrowForUnsupportedVectorBaseType<T>();
+
+ Vector<T> result = default;
+ Unsafe.WriteUnaligned(ref Unsafe.As<Vector<T>, byte>(ref result), value);
+ return result;
+ }
+
/// <summary>Creates a new <see cref="Vector128{Byte}" /> instance with all elements initialized to the specified value.</summary>
/// <param name="value">The value that all elements will be initialized to.</param>
/// <returns>A new <see cref="Vector128{Byte}" /> with all elements initialized to <paramref name="value" />.</returns>
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System.Diagnostics;
+using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.Intrinsics.X86;
using Internal.Runtime.CompilerServices;
return vector.As<T, ulong>();
}
+ /// <summary>Reinterprets a <see cref="Vector{T}" /> as a new <see cref="Vector256{T}" />.</summary>
+ /// <typeparam name="T">The type of the vectors.</typeparam>
+ /// <param name="value">The vector to reinterpret.</param>
+ /// <returns><paramref name="value" /> reinterpreted as a new <see cref="Vector256{T}" />.</returns>
+ /// <exception cref="NotSupportedException">The type of <paramref name="value" /> (<typeparamref name="T" />) is not supported.</exception>
+ public static Vector256<T> AsVector256<T>(this Vector<T> value)
+ where T : struct
+ {
+ Debug.Assert(Vector256<T>.Count >= Vector<T>.Count);
+ ThrowHelper.ThrowForUnsupportedVectorBaseType<T>();
+
+ Vector256<T> result = default;
+ Unsafe.WriteUnaligned(ref Unsafe.As<Vector256<T>, byte>(ref result), value);
+ return result;
+ }
+
+ /// <summary>Reinterprets a <see cref="Vector256{T}" /> as a new <see cref="Vector{T}" />.</summary>
+ /// <typeparam name="T">The type of the vectors.</typeparam>
+ /// <param name="value">The vector to reinterpret.</param>
+ /// <returns><paramref name="value" /> reinterpreted as a new <see cref="Vector{T}" />.</returns>
+ /// <exception cref="NotSupportedException">The type of <paramref name="value" /> (<typeparamref name="T" />) is not supported.</exception>
+ public static Vector<T> AsVector<T>(this Vector256<T> value)
+ where T : struct
+ {
+ Debug.Assert(Vector256<T>.Count >= Vector<T>.Count);
+ ThrowHelper.ThrowForUnsupportedVectorBaseType<T>();
+ return Unsafe.As<Vector256<T>, Vector<T>>(ref value);
+ }
+
/// <summary>Creates a new <see cref="Vector256{Byte}" /> instance with all elements initialized to the specified value.</summary>
/// <param name="value">The value that all elements will be initialized to.</param>
/// <returns>A new <see cref="Vector256{Byte}" /> with all elements initialized to <paramref name="value" />.</returns>