--- /dev/null
+// 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;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void AddByte()
+ {
+ var test = new SimpleBinaryOpTest__AddByte();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works
+ test.RunBasicScenario();
+
+ // Validates calling via reflection works
+ test.RunReflectionScenario();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works
+ test.RunLclVarScenario();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__AddByte
+ {
+ private const int VectorSize = 32;
+ private const int ElementCount = VectorSize / sizeof(Byte);
+
+ private static Byte[] _data1 = new Byte[ElementCount];
+ private static Byte[] _data2 = new Byte[ElementCount];
+
+ private static Vector256<Byte> _clsVar1;
+ private static Vector256<Byte> _clsVar2;
+
+ private Vector256<Byte> _fld1;
+ private Vector256<Byte> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Byte> _dataTable;
+
+ static SimpleBinaryOpTest__AddByte()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _clsVar1), ref Unsafe.As<Byte, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _clsVar2), ref Unsafe.As<Byte, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__AddByte()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _fld1), ref Unsafe.As<Byte, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _fld2), ref Unsafe.As<Byte, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Byte>(_data1, _data2, new Byte[ElementCount]);
+ }
+
+ public bool IsSupported => Avx2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario()
+ {
+ var result = Avx2.Add(
+ Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector256<Byte>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+ }
+
+ public void RunReflectionScenario()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.Add), new Type[] { typeof(Vector256<Byte>), typeof(Vector256<Byte>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector256<Byte>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Byte>)(result));
+ ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx2.Add(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray);
+ }
+
+ public void RunLclVarScenario()
+ {
+ var left = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Add(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArray);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__AddByte();
+ var result = Avx2.Add(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArray);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx2.Add(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArray);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Byte> left, Vector256<Byte> right, Byte[] result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray1 = new Byte[ElementCount];
+ Byte[] inArray2 = new Byte[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+
+ ValidateResult(inArray1, inArray2, result, method);
+ }
+
+ private void ValidateResult(Byte[] left, Byte[] right, Byte[] result, [CallerMemberName] string method = "")
+ {
+ if ((byte)(left[0] + right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((byte)(left[i] + right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.Add)}<Byte>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
--- /dev/null
+// 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;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void AddInt16()
+ {
+ var test = new SimpleBinaryOpTest__AddInt16();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works
+ test.RunBasicScenario();
+
+ // Validates calling via reflection works
+ test.RunReflectionScenario();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works
+ test.RunLclVarScenario();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__AddInt16
+ {
+ private const int VectorSize = 32;
+ private const int ElementCount = VectorSize / sizeof(Int16);
+
+ private static Int16[] _data1 = new Int16[ElementCount];
+ private static Int16[] _data2 = new Int16[ElementCount];
+
+ private static Vector256<Int16> _clsVar1;
+ private static Vector256<Int16> _clsVar2;
+
+ private Vector256<Int16> _fld1;
+ private Vector256<Int16> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int16> _dataTable;
+
+ static SimpleBinaryOpTest__AddInt16()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MaxValue)); _data2[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _clsVar1), ref Unsafe.As<Int16, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _clsVar2), ref Unsafe.As<Int16, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__AddInt16()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MaxValue)); _data2[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _fld1), ref Unsafe.As<Int16, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _fld2), ref Unsafe.As<Int16, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MaxValue)); _data2[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int16>(_data1, _data2, new Int16[ElementCount]);
+ }
+
+ public bool IsSupported => Avx2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario()
+ {
+ var result = Avx2.Add(
+ Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+ }
+
+ public void RunReflectionScenario()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.Add), new Type[] { typeof(Vector256<Int16>), typeof(Vector256<Int16>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result));
+ ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx2.Add(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray);
+ }
+
+ public void RunLclVarScenario()
+ {
+ var left = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Add(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArray);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__AddInt16();
+ var result = Avx2.Add(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArray);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx2.Add(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArray);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int16> left, Vector256<Int16> right, Int16[] result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray1 = new Int16[ElementCount];
+ Int16[] inArray2 = new Int16[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+
+ ValidateResult(inArray1, inArray2, result, method);
+ }
+
+ private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "")
+ {
+ if ((short)(left[0] + right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((short)(left[i] + right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.Add)}<Int16>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
--- /dev/null
+// 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;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void AddInt32()
+ {
+ var test = new SimpleBinaryOpTest__AddInt32();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works
+ test.RunBasicScenario();
+
+ // Validates calling via reflection works
+ test.RunReflectionScenario();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works
+ test.RunLclVarScenario();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__AddInt32
+ {
+ private const int VectorSize = 32;
+ private const int ElementCount = VectorSize / sizeof(Int32);
+
+ private static Int32[] _data1 = new Int32[ElementCount];
+ private static Int32[] _data2 = new Int32[ElementCount];
+
+ private static Vector256<Int32> _clsVar1;
+ private static Vector256<Int32> _clsVar2;
+
+ private Vector256<Int32> _fld1;
+ private Vector256<Int32> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int32> _dataTable;
+
+ static SimpleBinaryOpTest__AddInt32()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (int)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (int)(random.Next(int.MinValue, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _clsVar1), ref Unsafe.As<Int32, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _clsVar2), ref Unsafe.As<Int32, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__AddInt32()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (int)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (int)(random.Next(int.MinValue, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _fld1), ref Unsafe.As<Int32, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _fld2), ref Unsafe.As<Int32, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (int)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (int)(random.Next(int.MinValue, int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int32>(_data1, _data2, new Int32[ElementCount]);
+ }
+
+ public bool IsSupported => Avx2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario()
+ {
+ var result = Avx2.Add(
+ Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+ }
+
+ public void RunReflectionScenario()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.Add), new Type[] { typeof(Vector256<Int32>), typeof(Vector256<Int32>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result));
+ ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx2.Add(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray);
+ }
+
+ public void RunLclVarScenario()
+ {
+ var left = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Add(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArray);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__AddInt32();
+ var result = Avx2.Add(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArray);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx2.Add(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArray);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int32> left, Vector256<Int32> right, Int32[] result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray1 = new Int32[ElementCount];
+ Int32[] inArray2 = new Int32[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+
+ ValidateResult(inArray1, inArray2, result, method);
+ }
+
+ private void ValidateResult(Int32[] left, Int32[] right, Int32[] result, [CallerMemberName] string method = "")
+ {
+ if ((int)(left[0] + right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((int)(left[i] + right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.Add)}<Int32>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
--- /dev/null
+// 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;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void AddInt64()
+ {
+ var test = new SimpleBinaryOpTest__AddInt64();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works
+ test.RunBasicScenario();
+
+ // Validates calling via reflection works
+ test.RunReflectionScenario();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works
+ test.RunLclVarScenario();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__AddInt64
+ {
+ private const int VectorSize = 32;
+ private const int ElementCount = VectorSize / sizeof(Int64);
+
+ private static Int64[] _data1 = new Int64[ElementCount];
+ private static Int64[] _data2 = new Int64[ElementCount];
+
+ private static Vector256<Int64> _clsVar1;
+ private static Vector256<Int64> _clsVar2;
+
+ private Vector256<Int64> _fld1;
+ private Vector256<Int64> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int64> _dataTable;
+
+ static SimpleBinaryOpTest__AddInt64()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (long)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (long)(random.Next(int.MinValue, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _clsVar1), ref Unsafe.As<Int64, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _clsVar2), ref Unsafe.As<Int64, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__AddInt64()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (long)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (long)(random.Next(int.MinValue, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _fld1), ref Unsafe.As<Int64, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _fld2), ref Unsafe.As<Int64, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (long)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (long)(random.Next(int.MinValue, int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int64>(_data1, _data2, new Int64[ElementCount]);
+ }
+
+ public bool IsSupported => Avx2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario()
+ {
+ var result = Avx2.Add(
+ Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector256<Int64>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+ }
+
+ public void RunReflectionScenario()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.Add), new Type[] { typeof(Vector256<Int64>), typeof(Vector256<Int64>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector256<Int64>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result));
+ ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx2.Add(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray);
+ }
+
+ public void RunLclVarScenario()
+ {
+ var left = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Add(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArray);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__AddInt64();
+ var result = Avx2.Add(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArray);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx2.Add(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArray);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int64> left, Vector256<Int64> right, Int64[] result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray1 = new Int64[ElementCount];
+ Int64[] inArray2 = new Int64[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+
+ ValidateResult(inArray1, inArray2, result, method);
+ }
+
+ private void ValidateResult(Int64[] left, Int64[] right, Int64[] result, [CallerMemberName] string method = "")
+ {
+ if ((long)(left[0] + right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((long)(left[i] + right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.Add)}<Int64>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
--- /dev/null
+// 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;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void AddSByte()
+ {
+ var test = new SimpleBinaryOpTest__AddSByte();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works
+ test.RunBasicScenario();
+
+ // Validates calling via reflection works
+ test.RunReflectionScenario();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works
+ test.RunLclVarScenario();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__AddSByte
+ {
+ private const int VectorSize = 32;
+ private const int ElementCount = VectorSize / sizeof(SByte);
+
+ private static SByte[] _data1 = new SByte[ElementCount];
+ private static SByte[] _data2 = new SByte[ElementCount];
+
+ private static Vector256<SByte> _clsVar1;
+ private static Vector256<SByte> _clsVar2;
+
+ private Vector256<SByte> _fld1;
+ private Vector256<SByte> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<SByte> _dataTable;
+
+ static SimpleBinaryOpTest__AddSByte()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); _data2[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _clsVar1), ref Unsafe.As<SByte, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _clsVar2), ref Unsafe.As<SByte, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__AddSByte()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); _data2[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _fld1), ref Unsafe.As<SByte, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _fld2), ref Unsafe.As<SByte, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); _data2[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<SByte>(_data1, _data2, new SByte[ElementCount]);
+ }
+
+ public bool IsSupported => Avx2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario()
+ {
+ var result = Avx2.Add(
+ Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+ }
+
+ public void RunReflectionScenario()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.Add), new Type[] { typeof(Vector256<SByte>), typeof(Vector256<SByte>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<SByte>)(result));
+ ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx2.Add(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray);
+ }
+
+ public void RunLclVarScenario()
+ {
+ var left = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Add(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArray);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__AddSByte();
+ var result = Avx2.Add(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArray);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx2.Add(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArray);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<SByte> left, Vector256<SByte> right, SByte[] result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray1 = new SByte[ElementCount];
+ SByte[] inArray2 = new SByte[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+
+ ValidateResult(inArray1, inArray2, result, method);
+ }
+
+ private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "")
+ {
+ if ((sbyte)(left[0] + right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((sbyte)(left[i] + right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.Add)}<SByte>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
--- /dev/null
+// 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;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void AddUInt16()
+ {
+ var test = new SimpleBinaryOpTest__AddUInt16();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works
+ test.RunBasicScenario();
+
+ // Validates calling via reflection works
+ test.RunReflectionScenario();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works
+ test.RunLclVarScenario();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__AddUInt16
+ {
+ private const int VectorSize = 32;
+ private const int ElementCount = VectorSize / sizeof(UInt16);
+
+ private static UInt16[] _data1 = new UInt16[ElementCount];
+ private static UInt16[] _data2 = new UInt16[ElementCount];
+
+ private static Vector256<UInt16> _clsVar1;
+ private static Vector256<UInt16> _clsVar2;
+
+ private Vector256<UInt16> _fld1;
+ private Vector256<UInt16> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<UInt16> _dataTable;
+
+ static SimpleBinaryOpTest__AddUInt16()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (ushort)(random.Next(0, ushort.MaxValue)); _data2[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _clsVar1), ref Unsafe.As<UInt16, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _clsVar2), ref Unsafe.As<UInt16, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__AddUInt16()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (ushort)(random.Next(0, ushort.MaxValue)); _data2[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _fld1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _fld2), ref Unsafe.As<UInt16, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (ushort)(random.Next(0, ushort.MaxValue)); _data2[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt16>(_data1, _data2, new UInt16[ElementCount]);
+ }
+
+ public bool IsSupported => Avx2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario()
+ {
+ var result = Avx2.Add(
+ Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+ }
+
+ public void RunReflectionScenario()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.Add), new Type[] { typeof(Vector256<UInt16>), typeof(Vector256<UInt16>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx2.Add(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray);
+ }
+
+ public void RunLclVarScenario()
+ {
+ var left = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Add(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArray);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__AddUInt16();
+ var result = Avx2.Add(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArray);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx2.Add(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArray);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt16> left, Vector256<UInt16> right, UInt16[] result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray1 = new UInt16[ElementCount];
+ UInt16[] inArray2 = new UInt16[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+
+ ValidateResult(inArray1, inArray2, result, method);
+ }
+
+ private void ValidateResult(UInt16[] left, UInt16[] right, UInt16[] result, [CallerMemberName] string method = "")
+ {
+ if ((ushort)(left[0] + right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((ushort)(left[i] + right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.Add)}<UInt16>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
--- /dev/null
+// 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;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void AddUInt32()
+ {
+ var test = new SimpleBinaryOpTest__AddUInt32();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works
+ test.RunBasicScenario();
+
+ // Validates calling via reflection works
+ test.RunReflectionScenario();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works
+ test.RunLclVarScenario();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__AddUInt32
+ {
+ private const int VectorSize = 32;
+ private const int ElementCount = VectorSize / sizeof(UInt32);
+
+ private static UInt32[] _data1 = new UInt32[ElementCount];
+ private static UInt32[] _data2 = new UInt32[ElementCount];
+
+ private static Vector256<UInt32> _clsVar1;
+ private static Vector256<UInt32> _clsVar2;
+
+ private Vector256<UInt32> _fld1;
+ private Vector256<UInt32> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<UInt32> _dataTable;
+
+ static SimpleBinaryOpTest__AddUInt32()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (uint)(random.Next(0, int.MaxValue)); _data2[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _clsVar1), ref Unsafe.As<UInt32, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _clsVar2), ref Unsafe.As<UInt32, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__AddUInt32()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (uint)(random.Next(0, int.MaxValue)); _data2[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _fld1), ref Unsafe.As<UInt32, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _fld2), ref Unsafe.As<UInt32, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (uint)(random.Next(0, int.MaxValue)); _data2[i] = (uint)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt32>(_data1, _data2, new UInt32[ElementCount]);
+ }
+
+ public bool IsSupported => Avx2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario()
+ {
+ var result = Avx2.Add(
+ Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+ }
+
+ public void RunReflectionScenario()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.Add), new Type[] { typeof(Vector256<UInt32>), typeof(Vector256<UInt32>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result));
+ ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx2.Add(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray);
+ }
+
+ public void RunLclVarScenario()
+ {
+ var left = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Add(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArray);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__AddUInt32();
+ var result = Avx2.Add(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArray);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx2.Add(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArray);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt32> left, Vector256<UInt32> right, UInt32[] result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray1 = new UInt32[ElementCount];
+ UInt32[] inArray2 = new UInt32[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+
+ ValidateResult(inArray1, inArray2, result, method);
+ }
+
+ private void ValidateResult(UInt32[] left, UInt32[] right, UInt32[] result, [CallerMemberName] string method = "")
+ {
+ if ((uint)(left[0] + right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((uint)(left[i] + right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.Add)}<UInt32>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
--- /dev/null
+// 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;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void AddUInt64()
+ {
+ var test = new SimpleBinaryOpTest__AddUInt64();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works
+ test.RunBasicScenario();
+
+ // Validates calling via reflection works
+ test.RunReflectionScenario();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works
+ test.RunLclVarScenario();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__AddUInt64
+ {
+ private const int VectorSize = 32;
+ private const int ElementCount = VectorSize / sizeof(UInt64);
+
+ private static UInt64[] _data1 = new UInt64[ElementCount];
+ private static UInt64[] _data2 = new UInt64[ElementCount];
+
+ private static Vector256<UInt64> _clsVar1;
+ private static Vector256<UInt64> _clsVar2;
+
+ private Vector256<UInt64> _fld1;
+ private Vector256<UInt64> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<UInt64> _dataTable;
+
+ static SimpleBinaryOpTest__AddUInt64()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (ulong)(random.Next(0, int.MaxValue)); _data2[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _clsVar1), ref Unsafe.As<UInt64, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _clsVar2), ref Unsafe.As<UInt64, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__AddUInt64()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (ulong)(random.Next(0, int.MaxValue)); _data2[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _fld1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _fld2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (ulong)(random.Next(0, int.MaxValue)); _data2[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt64>(_data1, _data2, new UInt64[ElementCount]);
+ }
+
+ public bool IsSupported => Avx2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario()
+ {
+ var result = Avx2.Add(
+ Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+ }
+
+ public void RunReflectionScenario()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.Add), new Type[] { typeof(Vector256<UInt64>), typeof(Vector256<UInt64>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result));
+ ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx2.Add(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray);
+ }
+
+ public void RunLclVarScenario()
+ {
+ var left = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Add(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArray);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__AddUInt64();
+ var result = Avx2.Add(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArray);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx2.Add(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArray);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt64> left, Vector256<UInt64> right, UInt64[] result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray1 = new UInt64[ElementCount];
+ UInt64[] inArray2 = new UInt64[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+
+ ValidateResult(inArray1, inArray2, result, method);
+ }
+
+ private void ValidateResult(UInt64[] left, UInt64[] right, UInt64[] result, [CallerMemberName] string method = "")
+ {
+ if ((ulong)(left[0] + right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((ulong)(left[i] + right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.Add)}<UInt64>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
- <OutputType>Exe</OutputType>
- <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
- <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
- <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
- </PropertyGroup>
- <!-- Default configurations to help VS understand the configurations -->
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "></PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
- <ItemGroup>
- <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
- <Visible>False</Visible>
- </CodeAnalysisDependentAssemblyPaths>
- </ItemGroup>
- <PropertyGroup>
- <DebugType>None</DebugType>
- <Optimize></Optimize>
- </PropertyGroup>
- <ItemGroup>
- <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="Add.cs" />
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
- <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
-</Project>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
- <OutputType>Exe</OutputType>
- <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
- <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
- <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
- </PropertyGroup>
- <!-- Default configurations to help VS understand the configurations -->
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "></PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
- <ItemGroup>
- <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
- <Visible>False</Visible>
- </CodeAnalysisDependentAssemblyPaths>
- </ItemGroup>
- <PropertyGroup>
- <DebugType>None</DebugType>
- <Optimize>True</Optimize>
- </PropertyGroup>
- <ItemGroup>
- <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="Add.cs" />
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
- <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
-</Project>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "></PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType>None</DebugType>
+ <Optimize></Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Add.Byte.cs" />
+ <Compile Include="Add.Int16.cs" />
+ <Compile Include="Add.Int32.cs" />
+ <Compile Include="Add.Int64.cs" />
+ <Compile Include="Add.SByte.cs" />
+ <Compile Include="Add.UInt16.cs" />
+ <Compile Include="Add.UInt32.cs" />
+ <Compile Include="Add.UInt64.cs" />
+ <Compile Include="Program.Avx2.cs" />
+ <Compile Include="..\Shared\Program.cs" />
+ <Compile Include="..\Shared\SimpleBinOpTest_DataTable.cs" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
+</Project>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "></PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType>None</DebugType>
+ <Optimize>True</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Add.Byte.cs" />
+ <Compile Include="Add.Int16.cs" />
+ <Compile Include="Add.Int32.cs" />
+ <Compile Include="Add.Int64.cs" />
+ <Compile Include="Add.SByte.cs" />
+ <Compile Include="Add.UInt16.cs" />
+ <Compile Include="Add.UInt32.cs" />
+ <Compile Include="Add.UInt64.cs" />
+ <Compile Include="Program.Avx2.cs" />
+ <Compile Include="..\Shared\Program.cs" />
+ <Compile Include="..\Shared\SimpleBinOpTest_DataTable.cs" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
+</Project>
--- /dev/null
+// 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;
+using System.Collections.Generic;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ static Program()
+ {
+ TestList = new Dictionary<string, Action>() {
+ ["Add.Byte"] = AddByte,
+ ["Add.Int16"] = AddInt16,
+ ["Add.Int32"] = AddInt32,
+ ["Add.Int64"] = AddInt64,
+ ["Add.SByte"] = AddSByte,
+ ["Add.UInt16"] = AddUInt16,
+ ["Add.UInt32"] = AddUInt32,
+ ["Add.UInt64"] = AddUInt64,
+ };
+ }
+ }
+}
("SimpleBinOpTest.template", new string[] { "Avx", "Multiply", "Single", "Vector256", "32", "(float)(random.NextDouble())", "BitConverter.SingleToInt32Bits(left[0] * right[0]) != BitConverter.SingleToInt32Bits(result[0])", "BitConverter.SingleToInt32Bits(left[i] * right[i]) != BitConverter.SingleToInt32Bits(result[i])"}),
};
+private static readonly (string templateFileName, string[] templateData)[] Avx2Inputs = new []
+{
+ // TemplateName Isa, Method, BaseType, VectorType, VectorSize, NextValue, ValidateFirstResult, ValidateRemainingResults
+ ("SimpleBinOpTest.template", new string[] { "Avx2", "Add", "Byte", "Vector256", "32", "(byte)(random.Next(0, byte.MaxValue))", "(byte)(left[0] + right[0]) != result[0]", "(byte)(left[i] + right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Avx2", "Add", "Int16", "Vector256", "32", "(short)(random.Next(short.MinValue, short.MaxValue))", "(short)(left[0] + right[0]) != result[0]", "(short)(left[i] + right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Avx2", "Add", "Int32", "Vector256", "32", "(int)(random.Next(int.MinValue, int.MaxValue))", "(int)(left[0] + right[0]) != result[0]", "(int)(left[i] + right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Avx2", "Add", "Int64", "Vector256", "32", "(long)(random.Next(int.MinValue, int.MaxValue))", "(long)(left[0] + right[0]) != result[0]", "(long)(left[i] + right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Avx2", "Add", "SByte", "Vector256", "32", "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", "(sbyte)(left[0] + right[0]) != result[0]", "(sbyte)(left[i] + right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Avx2", "Add", "UInt16", "Vector256", "32", "(ushort)(random.Next(0, ushort.MaxValue))", "(ushort)(left[0] + right[0]) != result[0]", "(ushort)(left[i] + right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Avx2", "Add", "UInt32", "Vector256", "32", "(uint)(random.Next(0, int.MaxValue))", "(uint)(left[0] + right[0]) != result[0]", "(uint)(left[i] + right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Avx2", "Add", "UInt64", "Vector256", "32", "(ulong)(random.Next(0, int.MaxValue))", "(ulong)(left[0] + right[0]) != result[0]", "(ulong)(left[i] + right[i]) != result[i]"}),
+};
+
private static void ProcessInputs(string isa, (string templateFileName, string[] templateData)[] inputs)
{
var testListFileName = Path.Combine("..", isa, $"Program.{isa}.cs");
ProcessInputs("Sse2", Sse2Inputs);
ProcessInputs("Avx", AvxInputs);
+ProcessInputs("Avx2", Avx2Inputs);