diff --git a/src/System.Numerics.Vectors/src/System.Numerics.Vectors.csproj b/src/System.Numerics.Vectors/src/System.Numerics.Vectors.csproj
index c17b0876c5af..9f7e3eabb372 100644
--- a/src/System.Numerics.Vectors/src/System.Numerics.Vectors.csproj
+++ b/src/System.Numerics.Vectors/src/System.Numerics.Vectors.csproj
@@ -7,6 +7,8 @@
true
true
true
+ true
+ $(DefineConstants);HAS_INTRINSICS
netstandard1.0;portable-net45+win8+wp8+wpa81
net46-Debug;net46-Release;netcoreapp-Unix-Debug;netcoreapp-Unix-Release;netcoreapp-Windows_NT-Debug;netcoreapp-Windows_NT-Release;netfx-Windows_NT-Debug;netfx-Windows_NT-Release;netstandard-Debug;netstandard-Release;netstandard1.0-Debug;netstandard1.0-Release;uap-Windows_NT-Debug;uap-Windows_NT-Release;uapaot-Windows_NT-Debug;uapaot-Windows_NT-Release
@@ -62,6 +64,9 @@
+
+
+
diff --git a/src/System.Numerics.Vectors/src/System/Numerics/Matrix4x4.cs b/src/System.Numerics.Vectors/src/System/Numerics/Matrix4x4.cs
index 16931d6d369e..0420cece86b2 100644
--- a/src/System.Numerics.Vectors/src/System/Numerics/Matrix4x4.cs
+++ b/src/System.Numerics.Vectors/src/System/Numerics/Matrix4x4.cs
@@ -3,12 +3,17 @@
// See the LICENSE file in the project root for more information.
using System.Globalization;
+using System.Runtime.InteropServices;
+#if HAS_INTRINSICS
+using System.Runtime.Intrinsics.X86;
+#endif
namespace System.Numerics
{
///
/// A structure encapsulating a 4x4 matrix.
///
+ [StructLayout(LayoutKind.Sequential)]
public struct Matrix4x4 : IEquatable
{
#region Public Fields
@@ -1755,8 +1760,29 @@ public static Matrix4x4 Transform(Matrix4x4 value, Quaternion rotation)
///
/// The source matrix.
/// The transposed matrix.
- public static Matrix4x4 Transpose(Matrix4x4 matrix)
+ public static unsafe Matrix4x4 Transpose(Matrix4x4 matrix)
{
+#if HAS_INTRINSICS
+ if (Sse.IsSupported)
+ {
+ var row1 = Sse.LoadVector128(&matrix.M11);
+ var row2 = Sse.LoadVector128(&matrix.M21);
+ var row3 = Sse.LoadVector128(&matrix.M31);
+ var row4 = Sse.LoadVector128(&matrix.M41);
+
+ var l12 = Sse.UnpackLow(row1, row2);
+ var l34 = Sse.UnpackLow(row3, row4);
+ var h12 = Sse.UnpackHigh(row1, row2);
+ var h34 = Sse.UnpackHigh(row3, row4);
+
+ Sse.Store(&matrix.M11, Sse.MoveLowToHigh(l12, l34));
+ Sse.Store(&matrix.M21, Sse.MoveHighToLow(l34, l12));
+ Sse.Store(&matrix.M31, Sse.MoveLowToHigh(h12, h34));
+ Sse.Store(&matrix.M41, Sse.MoveHighToLow(h34, h12));
+
+ return matrix;
+ }
+#endif
Matrix4x4 result;
result.M11 = matrix.M11;
@@ -1786,8 +1812,19 @@ public static Matrix4x4 Transpose(Matrix4x4 matrix)
/// The second source matrix.
/// The relative weight of the second source matrix.
/// The interpolated matrix.
- public static Matrix4x4 Lerp(Matrix4x4 matrix1, Matrix4x4 matrix2, float amount)
+ public static unsafe Matrix4x4 Lerp(Matrix4x4 matrix1, Matrix4x4 matrix2, float amount)
{
+#if HAS_INTRINSICS
+ if (Sse.IsSupported)
+ {
+ var amountVec = Sse.SetAllVector128(amount);
+ Sse.Store(&matrix1.M11, VectorMath.Lerp(Sse.LoadVector128(&matrix1.M11), Sse.LoadVector128(&matrix2.M11), amountVec));
+ Sse.Store(&matrix1.M21, VectorMath.Lerp(Sse.LoadVector128(&matrix1.M21), Sse.LoadVector128(&matrix2.M21), amountVec));
+ Sse.Store(&matrix1.M31, VectorMath.Lerp(Sse.LoadVector128(&matrix1.M31), Sse.LoadVector128(&matrix2.M31), amountVec));
+ Sse.Store(&matrix1.M41, VectorMath.Lerp(Sse.LoadVector128(&matrix1.M41), Sse.LoadVector128(&matrix2.M41), amountVec));
+ return matrix1;
+ }
+#endif
Matrix4x4 result;
// First row
@@ -1822,29 +1859,7 @@ public static Matrix4x4 Lerp(Matrix4x4 matrix1, Matrix4x4 matrix2, float amount)
///
/// The source matrix.
/// The negated matrix.
- public static Matrix4x4 Negate(Matrix4x4 value)
- {
- Matrix4x4 result;
-
- result.M11 = -value.M11;
- result.M12 = -value.M12;
- result.M13 = -value.M13;
- result.M14 = -value.M14;
- result.M21 = -value.M21;
- result.M22 = -value.M22;
- result.M23 = -value.M23;
- result.M24 = -value.M24;
- result.M31 = -value.M31;
- result.M32 = -value.M32;
- result.M33 = -value.M33;
- result.M34 = -value.M34;
- result.M41 = -value.M41;
- result.M42 = -value.M42;
- result.M43 = -value.M43;
- result.M44 = -value.M44;
-
- return result;
- }
+ public static Matrix4x4 Negate(Matrix4x4 value) => -value;
///
/// Adds two matrices together.
@@ -1852,29 +1867,7 @@ public static Matrix4x4 Negate(Matrix4x4 value)
/// The first source matrix.
/// The second source matrix.
/// The resulting matrix.
- public static Matrix4x4 Add(Matrix4x4 value1, Matrix4x4 value2)
- {
- Matrix4x4 result;
-
- result.M11 = value1.M11 + value2.M11;
- result.M12 = value1.M12 + value2.M12;
- result.M13 = value1.M13 + value2.M13;
- result.M14 = value1.M14 + value2.M14;
- result.M21 = value1.M21 + value2.M21;
- result.M22 = value1.M22 + value2.M22;
- result.M23 = value1.M23 + value2.M23;
- result.M24 = value1.M24 + value2.M24;
- result.M31 = value1.M31 + value2.M31;
- result.M32 = value1.M32 + value2.M32;
- result.M33 = value1.M33 + value2.M33;
- result.M34 = value1.M34 + value2.M34;
- result.M41 = value1.M41 + value2.M41;
- result.M42 = value1.M42 + value2.M42;
- result.M43 = value1.M43 + value2.M43;
- result.M44 = value1.M44 + value2.M44;
-
- return result;
- }
+ public static Matrix4x4 Add(Matrix4x4 value1, Matrix4x4 value2) => value1 + value2;
///
/// Subtracts the second matrix from the first.
@@ -1882,29 +1875,7 @@ public static Matrix4x4 Add(Matrix4x4 value1, Matrix4x4 value2)
/// The first source matrix.
/// The second source matrix.
/// The result of the subtraction.
- public static Matrix4x4 Subtract(Matrix4x4 value1, Matrix4x4 value2)
- {
- Matrix4x4 result;
-
- result.M11 = value1.M11 - value2.M11;
- result.M12 = value1.M12 - value2.M12;
- result.M13 = value1.M13 - value2.M13;
- result.M14 = value1.M14 - value2.M14;
- result.M21 = value1.M21 - value2.M21;
- result.M22 = value1.M22 - value2.M22;
- result.M23 = value1.M23 - value2.M23;
- result.M24 = value1.M24 - value2.M24;
- result.M31 = value1.M31 - value2.M31;
- result.M32 = value1.M32 - value2.M32;
- result.M33 = value1.M33 - value2.M33;
- result.M34 = value1.M34 - value2.M34;
- result.M41 = value1.M41 - value2.M41;
- result.M42 = value1.M42 - value2.M42;
- result.M43 = value1.M43 - value2.M43;
- result.M44 = value1.M44 - value2.M44;
-
- return result;
- }
+ public static Matrix4x4 Subtract(Matrix4x4 value1, Matrix4x4 value2) => value1 - value2;
///
/// Multiplies a matrix by another matrix.
@@ -1912,36 +1883,7 @@ public static Matrix4x4 Subtract(Matrix4x4 value1, Matrix4x4 value2)
/// The first source matrix.
/// The second source matrix.
/// The result of the multiplication.
- public static Matrix4x4 Multiply(Matrix4x4 value1, Matrix4x4 value2)
- {
- Matrix4x4 result;
-
- // First row
- result.M11 = value1.M11 * value2.M11 + value1.M12 * value2.M21 + value1.M13 * value2.M31 + value1.M14 * value2.M41;
- result.M12 = value1.M11 * value2.M12 + value1.M12 * value2.M22 + value1.M13 * value2.M32 + value1.M14 * value2.M42;
- result.M13 = value1.M11 * value2.M13 + value1.M12 * value2.M23 + value1.M13 * value2.M33 + value1.M14 * value2.M43;
- result.M14 = value1.M11 * value2.M14 + value1.M12 * value2.M24 + value1.M13 * value2.M34 + value1.M14 * value2.M44;
-
- // Second row
- result.M21 = value1.M21 * value2.M11 + value1.M22 * value2.M21 + value1.M23 * value2.M31 + value1.M24 * value2.M41;
- result.M22 = value1.M21 * value2.M12 + value1.M22 * value2.M22 + value1.M23 * value2.M32 + value1.M24 * value2.M42;
- result.M23 = value1.M21 * value2.M13 + value1.M22 * value2.M23 + value1.M23 * value2.M33 + value1.M24 * value2.M43;
- result.M24 = value1.M21 * value2.M14 + value1.M22 * value2.M24 + value1.M23 * value2.M34 + value1.M24 * value2.M44;
-
- // Third row
- result.M31 = value1.M31 * value2.M11 + value1.M32 * value2.M21 + value1.M33 * value2.M31 + value1.M34 * value2.M41;
- result.M32 = value1.M31 * value2.M12 + value1.M32 * value2.M22 + value1.M33 * value2.M32 + value1.M34 * value2.M42;
- result.M33 = value1.M31 * value2.M13 + value1.M32 * value2.M23 + value1.M33 * value2.M33 + value1.M34 * value2.M43;
- result.M34 = value1.M31 * value2.M14 + value1.M32 * value2.M24 + value1.M33 * value2.M34 + value1.M34 * value2.M44;
-
- // Fourth row
- result.M41 = value1.M41 * value2.M11 + value1.M42 * value2.M21 + value1.M43 * value2.M31 + value1.M44 * value2.M41;
- result.M42 = value1.M41 * value2.M12 + value1.M42 * value2.M22 + value1.M43 * value2.M32 + value1.M44 * value2.M42;
- result.M43 = value1.M41 * value2.M13 + value1.M42 * value2.M23 + value1.M43 * value2.M33 + value1.M44 * value2.M43;
- result.M44 = value1.M41 * value2.M14 + value1.M42 * value2.M24 + value1.M43 * value2.M34 + value1.M44 * value2.M44;
-
- return result;
- }
+ public static Matrix4x4 Multiply(Matrix4x4 value1, Matrix4x4 value2) => value1 * value2;
///
/// Multiplies a matrix by a scalar value.
@@ -1949,37 +1891,27 @@ public static Matrix4x4 Multiply(Matrix4x4 value1, Matrix4x4 value2)
/// The source matrix.
/// The scaling factor.
/// The scaled matrix.
- public static Matrix4x4 Multiply(Matrix4x4 value1, float value2)
- {
- Matrix4x4 result;
-
- result.M11 = value1.M11 * value2;
- result.M12 = value1.M12 * value2;
- result.M13 = value1.M13 * value2;
- result.M14 = value1.M14 * value2;
- result.M21 = value1.M21 * value2;
- result.M22 = value1.M22 * value2;
- result.M23 = value1.M23 * value2;
- result.M24 = value1.M24 * value2;
- result.M31 = value1.M31 * value2;
- result.M32 = value1.M32 * value2;
- result.M33 = value1.M33 * value2;
- result.M34 = value1.M34 * value2;
- result.M41 = value1.M41 * value2;
- result.M42 = value1.M42 * value2;
- result.M43 = value1.M43 * value2;
- result.M44 = value1.M44 * value2;
-
- return result;
- }
+ public static Matrix4x4 Multiply(Matrix4x4 value1, float value2) => value1 * value2;
///
/// Returns a new matrix with the negated elements of the given matrix.
///
/// The source matrix.
/// The negated matrix.
- public static Matrix4x4 operator -(Matrix4x4 value)
+ public static unsafe Matrix4x4 operator -(Matrix4x4 value)
{
+#if HAS_INTRINSICS
+ if (Sse.IsSupported)
+ {
+ var zero = Sse.SetZeroVector128();
+ Sse.Store(&value.M11, Sse.Subtract(zero, Sse.LoadVector128(&value.M11)));
+ Sse.Store(&value.M21, Sse.Subtract(zero, Sse.LoadVector128(&value.M21)));
+ Sse.Store(&value.M31, Sse.Subtract(zero, Sse.LoadVector128(&value.M31)));
+ Sse.Store(&value.M41, Sse.Subtract(zero, Sse.LoadVector128(&value.M41)));
+
+ return value;
+ }
+#endif
Matrix4x4 m;
m.M11 = -value.M11;
@@ -2008,8 +1940,18 @@ public static Matrix4x4 Multiply(Matrix4x4 value1, float value2)
/// The first source matrix.
/// The second source matrix.
/// The resulting matrix.
- public static Matrix4x4 operator +(Matrix4x4 value1, Matrix4x4 value2)
+ 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(&value1.M11)));
+ Sse.Store(&value1.M21, Sse.Add(Sse.LoadVector128(&value1.M21), Sse.LoadVector128(&value1.M21)));
+ Sse.Store(&value1.M31, Sse.Add(Sse.LoadVector128(&value1.M31), Sse.LoadVector128(&value1.M31)));
+ Sse.Store(&value1.M41, Sse.Add(Sse.LoadVector128(&value1.M41), Sse.LoadVector128(&value1.M41)));
+ return value1;
+ }
+#endif
Matrix4x4 m;
m.M11 = value1.M11 + value2.M11;
@@ -2038,8 +1980,18 @@ public static Matrix4x4 Multiply(Matrix4x4 value1, float value2)
/// The first source matrix.
/// The second source matrix.
/// The result of the subtraction.
- public static Matrix4x4 operator -(Matrix4x4 value1, Matrix4x4 value2)
+ 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(&value1.M11)));
+ Sse.Store(&value1.M21, Sse.Subtract(Sse.LoadVector128(&value1.M21), Sse.LoadVector128(&value1.M21)));
+ Sse.Store(&value1.M31, Sse.Subtract(Sse.LoadVector128(&value1.M31), Sse.LoadVector128(&value1.M31)));
+ Sse.Store(&value1.M41, Sse.Subtract(Sse.LoadVector128(&value1.M41), Sse.LoadVector128(&value1.M41)));
+ return value1;
+ }
+#endif
Matrix4x4 m;
m.M11 = value1.M11 - value2.M11;
@@ -2068,8 +2020,44 @@ public static Matrix4x4 Multiply(Matrix4x4 value1, float value2)
/// The first source matrix.
/// The second source matrix.
/// The result of the multiplication.
- public static Matrix4x4 operator *(Matrix4x4 value1, Matrix4x4 value2)
+ public static unsafe Matrix4x4 operator *(Matrix4x4 value1, Matrix4x4 value2)
{
+#if HAS_INTRINSICS
+ if (Sse.IsSupported)
+ {
+ var row = Sse.LoadVector128(&value1.M11);
+ Sse.Store(&value1.M11,
+ Sse.Add(Sse.Add(Sse.Multiply(Sse.Shuffle(row, row, 0x00), Sse.LoadVector128(&value2.M11)),
+ Sse.Multiply(Sse.Shuffle(row, row, 0x55), Sse.LoadVector128(&value2.M21))),
+ Sse.Add(Sse.Multiply(Sse.Shuffle(row, row, 0xAA), Sse.LoadVector128(&value2.M31)),
+ Sse.Multiply(Sse.Shuffle(row, row, 0xFF), Sse.LoadVector128(&value2.M41)))));
+
+ // 0x00 is _MM_SHUFFLE(0,0,0,0), 0x55 is _MM_SHUFFLE(1,1,1,1), etc.
+ // TODO: Replace with a method once it's added to the API.
+
+ row = Sse.LoadVector128(&value1.M21);
+ Sse.Store(&value1.M21,
+ Sse.Add(Sse.Add(Sse.Multiply(Sse.Shuffle(row, row, 0x00), Sse.LoadVector128(&value2.M11)),
+ Sse.Multiply(Sse.Shuffle(row, row, 0x55), Sse.LoadVector128(&value2.M21))),
+ Sse.Add(Sse.Multiply(Sse.Shuffle(row, row, 0xAA), Sse.LoadVector128(&value2.M31)),
+ Sse.Multiply(Sse.Shuffle(row, row, 0xFF), Sse.LoadVector128(&value2.M41)))));
+
+ row = Sse.LoadVector128(&value1.M31);
+ Sse.Store(&value1.M31,
+ Sse.Add(Sse.Add(Sse.Multiply(Sse.Shuffle(row, row, 0x00), Sse.LoadVector128(&value2.M11)),
+ Sse.Multiply(Sse.Shuffle(row, row, 0x55), Sse.LoadVector128(&value2.M21))),
+ Sse.Add(Sse.Multiply(Sse.Shuffle(row, row, 0xAA), Sse.LoadVector128(&value2.M31)),
+ Sse.Multiply(Sse.Shuffle(row, row, 0xFF), Sse.LoadVector128(&value2.M41)))));
+
+ row = Sse.LoadVector128(&value1.M41);
+ Sse.Store(&value1.M41,
+ Sse.Add(Sse.Add(Sse.Multiply(Sse.Shuffle(row, row, 0x00), Sse.LoadVector128(&value2.M11)),
+ Sse.Multiply(Sse.Shuffle(row, row, 0x55), Sse.LoadVector128(&value2.M21))),
+ Sse.Add(Sse.Multiply(Sse.Shuffle(row, row, 0xAA), Sse.LoadVector128(&value2.M31)),
+ Sse.Multiply(Sse.Shuffle(row, row, 0xFF), Sse.LoadVector128(&value2.M41)))));
+ return value1;
+ }
+#endif
Matrix4x4 m;
// First row
@@ -2105,8 +2093,19 @@ public static Matrix4x4 Multiply(Matrix4x4 value1, float value2)
/// The source matrix.
/// The scaling factor.
/// The scaled matrix.
- public static Matrix4x4 operator *(Matrix4x4 value1, float value2)
+ public static unsafe Matrix4x4 operator *(Matrix4x4 value1, float value2)
{
+#if HAS_INTRINSICS
+ if (Sse.IsSupported)
+ {
+ var value2Vec = Sse.SetAllVector128(value2);
+ Sse.Store(&value1.M11, Sse.Multiply(Sse.LoadVector128(&value1.M11), value2Vec));
+ Sse.Store(&value1.M21, Sse.Multiply(Sse.LoadVector128(&value1.M21), value2Vec));
+ Sse.Store(&value1.M31, Sse.Multiply(Sse.LoadVector128(&value1.M31), value2Vec));
+ Sse.Store(&value1.M41, Sse.Multiply(Sse.LoadVector128(&value1.M41), value2Vec));
+ return value1;
+ }
+#endif
Matrix4x4 m;
m.M11 = value1.M11 * value2;
@@ -2134,13 +2133,22 @@ public static Matrix4x4 Multiply(Matrix4x4 value1, float value2)
/// The first matrix to compare.
/// The second matrix to compare.
/// True if the given matrices are equal; False otherwise.
- public static bool operator ==(Matrix4x4 value1, Matrix4x4 value2)
+ public static unsafe bool operator ==(Matrix4x4 value1, Matrix4x4 value2)
{
+#if HAS_INTRINSICS
+ if (Sse.IsSupported)
+ {
+ return
+ VectorMath.Equal(Sse.LoadVector128(&value1.M11), Sse.LoadVector128(&value2.M11)) &&
+ VectorMath.Equal(Sse.LoadVector128(&value1.M21), Sse.LoadVector128(&value2.M21)) &&
+ 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 && value1.M34 == value2.M34 &&
- value1.M41 == value2.M41 && value1.M42 == value2.M42 && value1.M43 == value2.M43);
+ 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 &&
+ value1.M34 == value2.M34 && value1.M41 == value2.M41 && value1.M42 == value2.M42 && value1.M43 == value2.M43);
}
///
@@ -2149,8 +2157,18 @@ public static Matrix4x4 Multiply(Matrix4x4 value1, float value2)
/// The first matrix to compare.
/// The second matrix to compare.
/// True if the given matrices are not equal; False if they are equal.
- public static bool operator !=(Matrix4x4 value1, Matrix4x4 value2)
+ public static unsafe bool operator !=(Matrix4x4 value1, Matrix4x4 value2)
{
+#if HAS_INTRINSICS
+ if (Sse.IsSupported)
+ {
+ return
+ VectorMath.NotEqual(Sse.LoadVector128(&value1.M11), Sse.LoadVector128(&value2.M11)) ||
+ VectorMath.NotEqual(Sse.LoadVector128(&value1.M21), Sse.LoadVector128(&value2.M21)) ||
+ 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 ||
@@ -2162,29 +2180,14 @@ public static Matrix4x4 Multiply(Matrix4x4 value1, float value2)
///
/// The matrix to compare this instance to.
/// True if the matrices are equal; False otherwise.
- public bool Equals(Matrix4x4 other)
- {
- return (M11 == other.M11 && M22 == other.M22 && M33 == other.M33 && M44 == other.M44 && // Check diagonal element first for early out.
- M12 == other.M12 && M13 == other.M13 && M14 == other.M14 &&
- M21 == other.M21 && M23 == other.M23 && M24 == other.M24 &&
- M31 == other.M31 && M32 == other.M32 && M34 == other.M34 &&
- M41 == other.M41 && M42 == other.M42 && M43 == other.M43);
- }
+ public bool Equals(Matrix4x4 other) => this == other;
///
/// Returns a boolean indicating whether the given Object is equal to this matrix instance.
///
/// The Object to compare against.
/// True if the Object is equal to this matrix; False otherwise.
- public override bool Equals(object obj)
- {
- if (obj is Matrix4x4)
- {
- return Equals((Matrix4x4)obj);
- }
-
- return false;
- }
+ public override bool Equals(object obj) => (obj is Matrix4x4 other) && (this == other);
///
/// Returns a String representing this matrix instance.
diff --git a/src/System.Numerics.Vectors/src/System/Numerics/VectorMath.cs b/src/System.Numerics.Vectors/src/System/Numerics/VectorMath.cs
new file mode 100644
index 000000000000..cec1e3a71bed
--- /dev/null
+++ b/src/System.Numerics.Vectors/src/System/Numerics/VectorMath.cs
@@ -0,0 +1,30 @@
+// 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;
+
+namespace System.Numerics
+{
+ internal static class VectorMath
+ {
+ public static Vector128 Lerp(Vector128 a, Vector128 b, Vector128 t)
+ {
+ Debug.Assert(Sse.IsSupported);
+ return Sse.Add(a, Sse.Multiply(Sse.Subtract(b, a), t));
+ }
+
+ public static bool Equal(Vector128 vector1, Vector128 vector2)
+ {
+ Debug.Assert(Sse.IsSupported);
+ return Sse.MoveMask(Sse.CompareNotEqual(vector1, vector2)) == 0;
+ }
+
+ public static bool NotEqual(Vector128 vector1, Vector128 vector2)
+ {
+ Debug.Assert(Sse.IsSupported);
+ return Sse.MoveMask(Sse.CompareNotEqual(vector1, vector2)) != 0;
+ }
+ }
+}