<Compile Include="ExtendToVector256.UInt16.cs" />
<Compile Include="ExtendToVector256.UInt32.cs" />
<Compile Include="ExtendToVector256.UInt64.cs" />
+ <Compile Include="ExtractVector128.Byte.1.Store.cs" />
+ <Compile Include="ExtractVector128.SByte.1.Store.cs" />
+ <Compile Include="ExtractVector128.Int16.1.Store.cs" />
+ <Compile Include="ExtractVector128.UInt16.1.Store.cs" />
+ <Compile Include="ExtractVector128.Int32.1.Store.cs" />
+ <Compile Include="ExtractVector128.UInt32.1.Store.cs" />
+ <Compile Include="ExtractVector128.Int64.1.Store.cs" />
+ <Compile Include="ExtractVector128.UInt64.1.Store.cs" />
+ <Compile Include="ExtractVector128.Single.1.Store.cs" />
+ <Compile Include="ExtractVector128.Double.1.Store.cs" />
+ <Compile Include="InsertVector128.Byte.1.Load.cs" />
+ <Compile Include="InsertVector128.SByte.1.Load.cs" />
+ <Compile Include="InsertVector128.Int16.1.Load.cs" />
+ <Compile Include="InsertVector128.UInt16.1.Load.cs" />
+ <Compile Include="InsertVector128.Int32.1.Load.cs" />
+ <Compile Include="InsertVector128.UInt32.1.Load.cs" />
+ <Compile Include="InsertVector128.Int64.1.Load.cs" />
+ <Compile Include="InsertVector128.UInt64.1.Load.cs" />
+ <Compile Include="InsertVector128.Single.1.Load.cs" />
+ <Compile Include="InsertVector128.Double.1.Load.cs" />
<Compile Include="Floor.Double.cs" />
<Compile Include="Floor.Single.cs" />
<Compile Include="GetLowerHalf.Byte.cs" />
<Compile Include="ExtendToVector256.UInt16.cs" />
<Compile Include="ExtendToVector256.UInt32.cs" />
<Compile Include="ExtendToVector256.UInt64.cs" />
+ <Compile Include="ExtractVector128.Byte.1.Store.cs" />
+ <Compile Include="ExtractVector128.SByte.1.Store.cs" />
+ <Compile Include="ExtractVector128.Int16.1.Store.cs" />
+ <Compile Include="ExtractVector128.UInt16.1.Store.cs" />
+ <Compile Include="ExtractVector128.Int32.1.Store.cs" />
+ <Compile Include="ExtractVector128.UInt32.1.Store.cs" />
+ <Compile Include="ExtractVector128.Int64.1.Store.cs" />
+ <Compile Include="ExtractVector128.UInt64.1.Store.cs" />
+ <Compile Include="ExtractVector128.Single.1.Store.cs" />
+ <Compile Include="ExtractVector128.Double.1.Store.cs" />
+ <Compile Include="InsertVector128.Byte.1.Load.cs" />
+ <Compile Include="InsertVector128.SByte.1.Load.cs" />
+ <Compile Include="InsertVector128.Int16.1.Load.cs" />
+ <Compile Include="InsertVector128.UInt16.1.Load.cs" />
+ <Compile Include="InsertVector128.Int32.1.Load.cs" />
+ <Compile Include="InsertVector128.UInt32.1.Load.cs" />
+ <Compile Include="InsertVector128.Int64.1.Load.cs" />
+ <Compile Include="InsertVector128.UInt64.1.Load.cs" />
+ <Compile Include="InsertVector128.Single.1.Load.cs" />
+ <Compile Include="InsertVector128.Double.1.Load.cs" />
<Compile Include="Floor.Double.cs" />
<Compile Include="Floor.Single.cs" />
<Compile Include="GetLowerHalf.Byte.cs" />
--- /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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Reflection;
+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 ExtractVector128Byte1Store()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Byte1Store();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // 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 SimpleUnaryOpTest__ExtractVector128Byte1Store
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Byte);
+ private const int RetElementCount = 16 / sizeof(Byte);
+
+ private static Byte[] _data = new Byte[Op1ElementCount];
+
+ private static Vector256<Byte> _clsVar;
+
+ private Vector256<Byte> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Byte, Byte> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128Byte1Store()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _clsVar), ref Unsafe.As<Byte, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128Byte1Store()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _fld), ref Unsafe.As<Byte, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Byte, Byte>(_data, new Byte[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ Avx.ExtractVector128(
+ (Byte*)_dataTable.outArrayPtr,
+ Unsafe.Read<Vector256<Byte>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ Avx.ExtractVector128(
+ (Byte*)_dataTable.outArrayPtr,
+ Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ Avx.ExtractVector128(
+ (Byte*)_dataTable.outArrayPtr,
+ Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(Byte*), typeof(Vector256<Byte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Byte*)),
+ Unsafe.Read<Vector256<Byte>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(Byte*), typeof(Vector256<Byte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Byte*)),
+ Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(Byte*), typeof(Vector256<Byte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Byte*)),
+ Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ Avx.ExtractVector128(
+ (Byte*)_dataTable.outArrayPtr,
+ _clsVar,
+ 1
+ );
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Byte>>(_dataTable.inArrayPtr);
+ Avx.ExtractVector128((Byte*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr));
+ Avx.ExtractVector128((Byte*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr));
+ Avx.ExtractVector128((Byte*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Byte1Store();
+ Avx.ExtractVector128((Byte*)_dataTable.outArrayPtr, test._fld, 1);
+ }
+
+ public void RunFldScenario()
+ {
+ Avx.ExtractVector128((Byte*)_dataTable.outArrayPtr, _fld, 1);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Byte> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray = new Byte[Op1ElementCount];
+ Byte[] outArray = new Byte[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray = new Byte[Op1ElementCount];
+ Byte[] outArray = new Byte[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Byte[] firstOp, Byte[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[16])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 16]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.ExtractVector128)}<Byte>(Vector256<Byte><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Reflection;
+using System.Linq;
+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 ExtractVector128Byte1()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Byte1();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // 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 SimpleUnaryOpTest__ExtractVector128Byte1
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Byte);
+ private const int RetElementCount = 16 / sizeof(Byte);
+
+ private static Byte[] _data = new Byte[Op1ElementCount];
+
+ private static Vector256<Byte> _clsVar;
+
+ private Vector256<Byte> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Byte, Byte> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128Byte1()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _clsVar), ref Unsafe.As<Byte, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128Byte1()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _fld), ref Unsafe.As<Byte, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Byte, Byte>(_data, new Byte[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.ExtractVector128(
+ Unsafe.Read<Vector256<Byte>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.ExtractVector128(
+ Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.ExtractVector128(
+ Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Byte>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.ExtractVector128(
+ _clsVar,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Byte>>(_dataTable.inArrayPtr);
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr));
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr));
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Byte1();
+ var result = Avx.ExtractVector128(test._fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.ExtractVector128(_fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Byte> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray = new Byte[Op1ElementCount];
+ Byte[] outArray = new Byte[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray = new Byte[Op1ElementCount];
+ Byte[] outArray = new Byte[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Byte[] firstOp, Byte[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[16])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 16]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.ExtractVector128)}<Byte>(Vector256<Byte><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Reflection;
+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 ExtractVector128Double1Store()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Double1Store();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // 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 SimpleUnaryOpTest__ExtractVector128Double1Store
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Double);
+ private const int RetElementCount = 16 / sizeof(Double);
+
+ private static Double[] _data = new Double[Op1ElementCount];
+
+ private static Vector256<Double> _clsVar;
+
+ private Vector256<Double> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Double, Double> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128Double1Store()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _clsVar), ref Unsafe.As<Double, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128Double1Store()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _fld), ref Unsafe.As<Double, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (double)(random.NextDouble()); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Double, Double>(_data, new Double[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ Avx.ExtractVector128(
+ (Double*)_dataTable.outArrayPtr,
+ Unsafe.Read<Vector256<Double>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ Avx.ExtractVector128(
+ (Double*)_dataTable.outArrayPtr,
+ Avx.LoadVector256((Double*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ Avx.ExtractVector128(
+ (Double*)_dataTable.outArrayPtr,
+ Avx.LoadAlignedVector256((Double*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(Double*), typeof(Vector256<Double>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Double*)),
+ Unsafe.Read<Vector256<Double>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(Double*), typeof(Vector256<Double>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Double*)),
+ Avx.LoadVector256((Double*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(Double*), typeof(Vector256<Double>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Double*)),
+ Avx.LoadAlignedVector256((Double*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ Avx.ExtractVector128(
+ (Double*)_dataTable.outArrayPtr,
+ _clsVar,
+ 1
+ );
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Double>>(_dataTable.inArrayPtr);
+ Avx.ExtractVector128((Double*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Double*)(_dataTable.inArrayPtr));
+ Avx.ExtractVector128((Double*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Double*)(_dataTable.inArrayPtr));
+ Avx.ExtractVector128((Double*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Double1Store();
+ Avx.ExtractVector128((Double*)_dataTable.outArrayPtr, test._fld, 1);
+ }
+
+ public void RunFldScenario()
+ {
+ Avx.ExtractVector128((Double*)_dataTable.outArrayPtr, _fld, 1);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Double> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray = new Double[Op1ElementCount];
+ Double[] outArray = new Double[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray = new Double[Op1ElementCount];
+ Double[] outArray = new Double[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Double[] firstOp, Double[] result, [CallerMemberName] string method = "")
+ {
+ if (BitConverter.DoubleToInt64Bits(result[0]) != BitConverter.DoubleToInt64Bits(firstOp[2]))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((BitConverter.DoubleToInt64Bits(result[i]) != BitConverter.DoubleToInt64Bits(firstOp[i + 2])))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.ExtractVector128)}<Double>(Vector256<Double><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Reflection;
+using System.Linq;
+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 ExtractVector128Double1()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Double1();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // 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 SimpleUnaryOpTest__ExtractVector128Double1
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Double);
+ private const int RetElementCount = 16 / sizeof(Double);
+
+ private static Double[] _data = new Double[Op1ElementCount];
+
+ private static Vector256<Double> _clsVar;
+
+ private Vector256<Double> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Double, Double> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128Double1()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _clsVar), ref Unsafe.As<Double, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128Double1()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _fld), ref Unsafe.As<Double, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (double)(random.NextDouble()); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Double, Double>(_data, new Double[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.ExtractVector128(
+ Unsafe.Read<Vector256<Double>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.ExtractVector128(
+ Avx.LoadVector256((Double*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.ExtractVector128(
+ Avx.LoadAlignedVector256((Double*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Double) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Double>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Double) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Double*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Double) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Double*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.ExtractVector128(
+ _clsVar,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Double>>(_dataTable.inArrayPtr);
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Double*)(_dataTable.inArrayPtr));
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Double*)(_dataTable.inArrayPtr));
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Double1();
+ var result = Avx.ExtractVector128(test._fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.ExtractVector128(_fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Double> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray = new Double[Op1ElementCount];
+ Double[] outArray = new Double[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray = new Double[Op1ElementCount];
+ Double[] outArray = new Double[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Double[] firstOp, Double[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[2])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 2]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.ExtractVector128)}<Double>(Vector256<Double><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Reflection;
+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 ExtractVector128Int161Store()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Int161Store();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // 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 SimpleUnaryOpTest__ExtractVector128Int161Store
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int16);
+ private const int RetElementCount = 16 / sizeof(Int16);
+
+ private static Int16[] _data = new Int16[Op1ElementCount];
+
+ private static Vector256<Int16> _clsVar;
+
+ private Vector256<Int16> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Int16, Int16> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128Int161Store()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _clsVar), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128Int161Store()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _fld), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Int16, Int16>(_data, new Int16[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ Avx.ExtractVector128(
+ (Int16*)_dataTable.outArrayPtr,
+ Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ Avx.ExtractVector128(
+ (Int16*)_dataTable.outArrayPtr,
+ Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ Avx.ExtractVector128(
+ (Int16*)_dataTable.outArrayPtr,
+ Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(Int16*), typeof(Vector256<Int16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Int16*)),
+ Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(Int16*), typeof(Vector256<Int16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Int16*)),
+ Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(Int16*), typeof(Vector256<Int16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Int16*)),
+ Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ Avx.ExtractVector128(
+ (Int16*)_dataTable.outArrayPtr,
+ _clsVar,
+ 1
+ );
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr);
+ Avx.ExtractVector128((Int16*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr));
+ Avx.ExtractVector128((Int16*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr));
+ Avx.ExtractVector128((Int16*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Int161Store();
+ Avx.ExtractVector128((Int16*)_dataTable.outArrayPtr, test._fld, 1);
+ }
+
+ public void RunFldScenario()
+ {
+ Avx.ExtractVector128((Int16*)_dataTable.outArrayPtr, _fld, 1);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int16> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray = new Int16[Op1ElementCount];
+ Int16[] outArray = new Int16[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray = new Int16[Op1ElementCount];
+ Int16[] outArray = new Int16[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[8])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 8]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.ExtractVector128)}<Int16>(Vector256<Int16><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Reflection;
+using System.Linq;
+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 ExtractVector128Int161()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Int161();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // 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 SimpleUnaryOpTest__ExtractVector128Int161
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int16);
+ private const int RetElementCount = 16 / sizeof(Int16);
+
+ private static Int16[] _data = new Int16[Op1ElementCount];
+
+ private static Vector256<Int16> _clsVar;
+
+ private Vector256<Int16> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Int16, Int16> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128Int161()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _clsVar), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128Int161()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _fld), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Int16, Int16>(_data, new Int16[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.ExtractVector128(
+ Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.ExtractVector128(
+ Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.ExtractVector128(
+ Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Int16) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Int16) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Int16) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.ExtractVector128(
+ _clsVar,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr);
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr));
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr));
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Int161();
+ var result = Avx.ExtractVector128(test._fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.ExtractVector128(_fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int16> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray = new Int16[Op1ElementCount];
+ Int16[] outArray = new Int16[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray = new Int16[Op1ElementCount];
+ Int16[] outArray = new Int16[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[8])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 8]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.ExtractVector128)}<Int16>(Vector256<Int16><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Reflection;
+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 ExtractVector128Int321Store()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Int321Store();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // 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 SimpleUnaryOpTest__ExtractVector128Int321Store
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int32);
+ private const int RetElementCount = 16 / sizeof(Int32);
+
+ private static Int32[] _data = new Int32[Op1ElementCount];
+
+ private static Vector256<Int32> _clsVar;
+
+ private Vector256<Int32> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Int32, Int32> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128Int321Store()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _clsVar), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128Int321Store()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _fld), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Int32, Int32>(_data, new Int32[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ Avx.ExtractVector128(
+ (Int32*)_dataTable.outArrayPtr,
+ Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ Avx.ExtractVector128(
+ (Int32*)_dataTable.outArrayPtr,
+ Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ Avx.ExtractVector128(
+ (Int32*)_dataTable.outArrayPtr,
+ Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(Int32*), typeof(Vector256<Int32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Int32*)),
+ Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(Int32*), typeof(Vector256<Int32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Int32*)),
+ Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(Int32*), typeof(Vector256<Int32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Int32*)),
+ Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ Avx.ExtractVector128(
+ (Int32*)_dataTable.outArrayPtr,
+ _clsVar,
+ 1
+ );
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr);
+ Avx.ExtractVector128((Int32*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr));
+ Avx.ExtractVector128((Int32*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr));
+ Avx.ExtractVector128((Int32*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Int321Store();
+ Avx.ExtractVector128((Int32*)_dataTable.outArrayPtr, test._fld, 1);
+ }
+
+ public void RunFldScenario()
+ {
+ Avx.ExtractVector128((Int32*)_dataTable.outArrayPtr, _fld, 1);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int32> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray = new Int32[Op1ElementCount];
+ Int32[] outArray = new Int32[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray = new Int32[Op1ElementCount];
+ Int32[] outArray = new Int32[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[4])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 4]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.ExtractVector128)}<Int32>(Vector256<Int32><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Reflection;
+using System.Linq;
+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 ExtractVector128Int321()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Int321();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // 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 SimpleUnaryOpTest__ExtractVector128Int321
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int32);
+ private const int RetElementCount = 16 / sizeof(Int32);
+
+ private static Int32[] _data = new Int32[Op1ElementCount];
+
+ private static Vector256<Int32> _clsVar;
+
+ private Vector256<Int32> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Int32, Int32> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128Int321()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _clsVar), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128Int321()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _fld), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Int32, Int32>(_data, new Int32[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.ExtractVector128(
+ Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.ExtractVector128(
+ Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.ExtractVector128(
+ Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Int32) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Int32) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Int32) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.ExtractVector128(
+ _clsVar,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr);
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr));
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr));
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Int321();
+ var result = Avx.ExtractVector128(test._fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.ExtractVector128(_fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int32> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray = new Int32[Op1ElementCount];
+ Int32[] outArray = new Int32[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray = new Int32[Op1ElementCount];
+ Int32[] outArray = new Int32[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[4])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 4]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.ExtractVector128)}<Int32>(Vector256<Int32><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Reflection;
+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 ExtractVector128Int641Store()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Int641Store();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // 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 SimpleUnaryOpTest__ExtractVector128Int641Store
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int64);
+ private const int RetElementCount = 16 / sizeof(Int64);
+
+ private static Int64[] _data = new Int64[Op1ElementCount];
+
+ private static Vector256<Int64> _clsVar;
+
+ private Vector256<Int64> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Int64, Int64> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128Int641Store()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _clsVar), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128Int641Store()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _fld), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Int64, Int64>(_data, new Int64[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ Avx.ExtractVector128(
+ (Int64*)_dataTable.outArrayPtr,
+ Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ Avx.ExtractVector128(
+ (Int64*)_dataTable.outArrayPtr,
+ Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ Avx.ExtractVector128(
+ (Int64*)_dataTable.outArrayPtr,
+ Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(Int64*), typeof(Vector256<Int64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Int64*)),
+ Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(Int64*), typeof(Vector256<Int64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Int64*)),
+ Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(Int64*), typeof(Vector256<Int64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Int64*)),
+ Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ Avx.ExtractVector128(
+ (Int64*)_dataTable.outArrayPtr,
+ _clsVar,
+ 1
+ );
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr);
+ Avx.ExtractVector128((Int64*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr));
+ Avx.ExtractVector128((Int64*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr));
+ Avx.ExtractVector128((Int64*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Int641Store();
+ Avx.ExtractVector128((Int64*)_dataTable.outArrayPtr, test._fld, 1);
+ }
+
+ public void RunFldScenario()
+ {
+ Avx.ExtractVector128((Int64*)_dataTable.outArrayPtr, _fld, 1);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int64> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray = new Int64[Op1ElementCount];
+ Int64[] outArray = new Int64[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray = new Int64[Op1ElementCount];
+ Int64[] outArray = new Int64[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Int64[] firstOp, Int64[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[2])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 2]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.ExtractVector128)}<Int64>(Vector256<Int64><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Reflection;
+using System.Linq;
+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 ExtractVector128Int641()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Int641();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // 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 SimpleUnaryOpTest__ExtractVector128Int641
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int64);
+ private const int RetElementCount = 16 / sizeof(Int64);
+
+ private static Int64[] _data = new Int64[Op1ElementCount];
+
+ private static Vector256<Int64> _clsVar;
+
+ private Vector256<Int64> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Int64, Int64> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128Int641()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _clsVar), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128Int641()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _fld), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Int64, Int64>(_data, new Int64[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.ExtractVector128(
+ Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.ExtractVector128(
+ Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.ExtractVector128(
+ Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Int64) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Int64) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Int64) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.ExtractVector128(
+ _clsVar,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr);
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr));
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr));
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Int641();
+ var result = Avx.ExtractVector128(test._fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.ExtractVector128(_fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int64> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray = new Int64[Op1ElementCount];
+ Int64[] outArray = new Int64[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray = new Int64[Op1ElementCount];
+ Int64[] outArray = new Int64[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Int64[] firstOp, Int64[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[2])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 2]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.ExtractVector128)}<Int64>(Vector256<Int64><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Reflection;
+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 ExtractVector128SByte1Store()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128SByte1Store();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // 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 SimpleUnaryOpTest__ExtractVector128SByte1Store
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(SByte);
+ private const int RetElementCount = 16 / sizeof(SByte);
+
+ private static SByte[] _data = new SByte[Op1ElementCount];
+
+ private static Vector256<SByte> _clsVar;
+
+ private Vector256<SByte> _fld;
+
+ private SimpleUnaryOpTest__DataTable<SByte, SByte> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128SByte1Store()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _clsVar), ref Unsafe.As<SByte, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128SByte1Store()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _fld), ref Unsafe.As<SByte, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<SByte, SByte>(_data, new SByte[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ Avx.ExtractVector128(
+ (SByte*)_dataTable.outArrayPtr,
+ Unsafe.Read<Vector256<SByte>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ Avx.ExtractVector128(
+ (SByte*)_dataTable.outArrayPtr,
+ Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ Avx.ExtractVector128(
+ (SByte*)_dataTable.outArrayPtr,
+ Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(SByte*), typeof(Vector256<SByte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(SByte*)),
+ Unsafe.Read<Vector256<SByte>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(SByte*), typeof(Vector256<SByte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(SByte*)),
+ Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(SByte*), typeof(Vector256<SByte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(SByte*)),
+ Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ Avx.ExtractVector128(
+ (SByte*)_dataTable.outArrayPtr,
+ _clsVar,
+ 1
+ );
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<SByte>>(_dataTable.inArrayPtr);
+ Avx.ExtractVector128((SByte*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr));
+ Avx.ExtractVector128((SByte*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr));
+ Avx.ExtractVector128((SByte*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128SByte1Store();
+ Avx.ExtractVector128((SByte*)_dataTable.outArrayPtr, test._fld, 1);
+ }
+
+ public void RunFldScenario()
+ {
+ Avx.ExtractVector128((SByte*)_dataTable.outArrayPtr, _fld, 1);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<SByte> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray = new SByte[Op1ElementCount];
+ SByte[] outArray = new SByte[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray = new SByte[Op1ElementCount];
+ SByte[] outArray = new SByte[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(SByte[] firstOp, SByte[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[16])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 16]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.ExtractVector128)}<SByte>(Vector256<SByte><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Reflection;
+using System.Linq;
+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 ExtractVector128SByte1()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128SByte1();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // 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 SimpleUnaryOpTest__ExtractVector128SByte1
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(SByte);
+ private const int RetElementCount = 16 / sizeof(SByte);
+
+ private static SByte[] _data = new SByte[Op1ElementCount];
+
+ private static Vector256<SByte> _clsVar;
+
+ private Vector256<SByte> _fld;
+
+ private SimpleUnaryOpTest__DataTable<SByte, SByte> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128SByte1()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _clsVar), ref Unsafe.As<SByte, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128SByte1()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _fld), ref Unsafe.As<SByte, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<SByte, SByte>(_data, new SByte[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.ExtractVector128(
+ Unsafe.Read<Vector256<SByte>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.ExtractVector128(
+ Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.ExtractVector128(
+ Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(SByte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<SByte>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(SByte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(SByte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.ExtractVector128(
+ _clsVar,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<SByte>>(_dataTable.inArrayPtr);
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr));
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr));
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128SByte1();
+ var result = Avx.ExtractVector128(test._fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.ExtractVector128(_fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<SByte> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray = new SByte[Op1ElementCount];
+ SByte[] outArray = new SByte[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray = new SByte[Op1ElementCount];
+ SByte[] outArray = new SByte[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(SByte[] firstOp, SByte[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[16])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 16]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.ExtractVector128)}<SByte>(Vector256<SByte><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Reflection;
+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 ExtractVector128Single1Store()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Single1Store();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // 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 SimpleUnaryOpTest__ExtractVector128Single1Store
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Single);
+ private const int RetElementCount = 16 / sizeof(Single);
+
+ private static Single[] _data = new Single[Op1ElementCount];
+
+ private static Vector256<Single> _clsVar;
+
+ private Vector256<Single> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Single, Single> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128Single1Store()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _clsVar), ref Unsafe.As<Single, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128Single1Store()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _fld), ref Unsafe.As<Single, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Single, Single>(_data, new Single[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ Avx.ExtractVector128(
+ (Single*)_dataTable.outArrayPtr,
+ Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ Avx.ExtractVector128(
+ (Single*)_dataTable.outArrayPtr,
+ Avx.LoadVector256((Single*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ Avx.ExtractVector128(
+ (Single*)_dataTable.outArrayPtr,
+ Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(Single*), typeof(Vector256<Single>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Single*)),
+ Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(Single*), typeof(Vector256<Single>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Single*)),
+ Avx.LoadVector256((Single*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(Single*), typeof(Vector256<Single>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Single*)),
+ Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ Avx.ExtractVector128(
+ (Single*)_dataTable.outArrayPtr,
+ _clsVar,
+ 1
+ );
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr);
+ Avx.ExtractVector128((Single*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Single*)(_dataTable.inArrayPtr));
+ Avx.ExtractVector128((Single*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr));
+ Avx.ExtractVector128((Single*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Single1Store();
+ Avx.ExtractVector128((Single*)_dataTable.outArrayPtr, test._fld, 1);
+ }
+
+ public void RunFldScenario()
+ {
+ Avx.ExtractVector128((Single*)_dataTable.outArrayPtr, _fld, 1);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Single> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Single[] inArray = new Single[Op1ElementCount];
+ Single[] outArray = new Single[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Single[] inArray = new Single[Op1ElementCount];
+ Single[] outArray = new Single[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Single[] firstOp, Single[] result, [CallerMemberName] string method = "")
+ {
+ if (BitConverter.SingleToInt32Bits(result[0]) != BitConverter.SingleToInt32Bits(firstOp[4]))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(firstOp[i + 4])))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.ExtractVector128)}<Single>(Vector256<Single><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Reflection;
+using System.Linq;
+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 ExtractVector128Single1()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Single1();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // 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 SimpleUnaryOpTest__ExtractVector128Single1
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Single);
+ private const int RetElementCount = 16 / sizeof(Single);
+
+ private static Single[] _data = new Single[Op1ElementCount];
+
+ private static Vector256<Single> _clsVar;
+
+ private Vector256<Single> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Single, Single> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128Single1()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _clsVar), ref Unsafe.As<Single, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128Single1()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _fld), ref Unsafe.As<Single, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Single, Single>(_data, new Single[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.ExtractVector128(
+ Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.ExtractVector128(
+ Avx.LoadVector256((Single*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.ExtractVector128(
+ Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Single) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Single) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Single*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Single) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.ExtractVector128(
+ _clsVar,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr);
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Single*)(_dataTable.inArrayPtr));
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr));
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Single1();
+ var result = Avx.ExtractVector128(test._fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.ExtractVector128(_fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Single> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Single[] inArray = new Single[Op1ElementCount];
+ Single[] outArray = new Single[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Single[] inArray = new Single[Op1ElementCount];
+ Single[] outArray = new Single[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Single[] firstOp, Single[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[4])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 4]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.ExtractVector128)}<Single>(Vector256<Single><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Reflection;
+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 ExtractVector128UInt161Store()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128UInt161Store();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // 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 SimpleUnaryOpTest__ExtractVector128UInt161Store
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt16);
+ private const int RetElementCount = 16 / sizeof(UInt16);
+
+ private static UInt16[] _data = new UInt16[Op1ElementCount];
+
+ private static Vector256<UInt16> _clsVar;
+
+ private Vector256<UInt16> _fld;
+
+ private SimpleUnaryOpTest__DataTable<UInt16, UInt16> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128UInt161Store()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _clsVar), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128UInt161Store()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _fld), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<UInt16, UInt16>(_data, new UInt16[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ Avx.ExtractVector128(
+ (UInt16*)_dataTable.outArrayPtr,
+ Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ Avx.ExtractVector128(
+ (UInt16*)_dataTable.outArrayPtr,
+ Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ Avx.ExtractVector128(
+ (UInt16*)_dataTable.outArrayPtr,
+ Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(UInt16*), typeof(Vector256<UInt16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(UInt16*)),
+ Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(UInt16*), typeof(Vector256<UInt16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(UInt16*)),
+ Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(UInt16*), typeof(Vector256<UInt16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(UInt16*)),
+ Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ Avx.ExtractVector128(
+ (UInt16*)_dataTable.outArrayPtr,
+ _clsVar,
+ 1
+ );
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr);
+ Avx.ExtractVector128((UInt16*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr));
+ Avx.ExtractVector128((UInt16*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr));
+ Avx.ExtractVector128((UInt16*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128UInt161Store();
+ Avx.ExtractVector128((UInt16*)_dataTable.outArrayPtr, test._fld, 1);
+ }
+
+ public void RunFldScenario()
+ {
+ Avx.ExtractVector128((UInt16*)_dataTable.outArrayPtr, _fld, 1);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt16> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray = new UInt16[Op1ElementCount];
+ UInt16[] outArray = new UInt16[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray = new UInt16[Op1ElementCount];
+ UInt16[] outArray = new UInt16[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(UInt16[] firstOp, UInt16[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[8])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 8]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.ExtractVector128)}<UInt16>(Vector256<UInt16><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Reflection;
+using System.Linq;
+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 ExtractVector128UInt161()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128UInt161();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // 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 SimpleUnaryOpTest__ExtractVector128UInt161
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt16);
+ private const int RetElementCount = 16 / sizeof(UInt16);
+
+ private static UInt16[] _data = new UInt16[Op1ElementCount];
+
+ private static Vector256<UInt16> _clsVar;
+
+ private Vector256<UInt16> _fld;
+
+ private SimpleUnaryOpTest__DataTable<UInt16, UInt16> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128UInt161()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _clsVar), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128UInt161()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _fld), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<UInt16, UInt16>(_data, new UInt16[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.ExtractVector128(
+ Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.ExtractVector128(
+ Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.ExtractVector128(
+ Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(UInt16) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(UInt16) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(UInt16) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.ExtractVector128(
+ _clsVar,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr);
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr));
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr));
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128UInt161();
+ var result = Avx.ExtractVector128(test._fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.ExtractVector128(_fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt16> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray = new UInt16[Op1ElementCount];
+ UInt16[] outArray = new UInt16[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray = new UInt16[Op1ElementCount];
+ UInt16[] outArray = new UInt16[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(UInt16[] firstOp, UInt16[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[8])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 8]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.ExtractVector128)}<UInt16>(Vector256<UInt16><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Reflection;
+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 ExtractVector128UInt321Store()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128UInt321Store();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // 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 SimpleUnaryOpTest__ExtractVector128UInt321Store
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt32);
+ private const int RetElementCount = 16 / sizeof(UInt32);
+
+ private static UInt32[] _data = new UInt32[Op1ElementCount];
+
+ private static Vector256<UInt32> _clsVar;
+
+ private Vector256<UInt32> _fld;
+
+ private SimpleUnaryOpTest__DataTable<UInt32, UInt32> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128UInt321Store()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _clsVar), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128UInt321Store()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _fld), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<UInt32, UInt32>(_data, new UInt32[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ Avx.ExtractVector128(
+ (UInt32*)_dataTable.outArrayPtr,
+ Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ Avx.ExtractVector128(
+ (UInt32*)_dataTable.outArrayPtr,
+ Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ Avx.ExtractVector128(
+ (UInt32*)_dataTable.outArrayPtr,
+ Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(UInt32*), typeof(Vector256<UInt32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(UInt32*)),
+ Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(UInt32*), typeof(Vector256<UInt32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(UInt32*)),
+ Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(UInt32*), typeof(Vector256<UInt32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(UInt32*)),
+ Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ Avx.ExtractVector128(
+ (UInt32*)_dataTable.outArrayPtr,
+ _clsVar,
+ 1
+ );
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr);
+ Avx.ExtractVector128((UInt32*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr));
+ Avx.ExtractVector128((UInt32*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr));
+ Avx.ExtractVector128((UInt32*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128UInt321Store();
+ Avx.ExtractVector128((UInt32*)_dataTable.outArrayPtr, test._fld, 1);
+ }
+
+ public void RunFldScenario()
+ {
+ Avx.ExtractVector128((UInt32*)_dataTable.outArrayPtr, _fld, 1);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt32> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray = new UInt32[Op1ElementCount];
+ UInt32[] outArray = new UInt32[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray = new UInt32[Op1ElementCount];
+ UInt32[] outArray = new UInt32[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(UInt32[] firstOp, UInt32[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[4])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 4]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.ExtractVector128)}<UInt32>(Vector256<UInt32><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Reflection;
+using System.Linq;
+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 ExtractVector128UInt321()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128UInt321();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // 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 SimpleUnaryOpTest__ExtractVector128UInt321
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt32);
+ private const int RetElementCount = 16 / sizeof(UInt32);
+
+ private static UInt32[] _data = new UInt32[Op1ElementCount];
+
+ private static Vector256<UInt32> _clsVar;
+
+ private Vector256<UInt32> _fld;
+
+ private SimpleUnaryOpTest__DataTable<UInt32, UInt32> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128UInt321()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _clsVar), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128UInt321()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _fld), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<UInt32, UInt32>(_data, new UInt32[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.ExtractVector128(
+ Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.ExtractVector128(
+ Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.ExtractVector128(
+ Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(UInt32) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(UInt32) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(UInt32) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.ExtractVector128(
+ _clsVar,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr);
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr));
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr));
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128UInt321();
+ var result = Avx.ExtractVector128(test._fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.ExtractVector128(_fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt32> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray = new UInt32[Op1ElementCount];
+ UInt32[] outArray = new UInt32[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray = new UInt32[Op1ElementCount];
+ UInt32[] outArray = new UInt32[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(UInt32[] firstOp, UInt32[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[4])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 4]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.ExtractVector128)}<UInt32>(Vector256<UInt32><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Reflection;
+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 ExtractVector128UInt641Store()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128UInt641Store();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // 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 SimpleUnaryOpTest__ExtractVector128UInt641Store
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt64);
+ private const int RetElementCount = 16 / sizeof(UInt64);
+
+ private static UInt64[] _data = new UInt64[Op1ElementCount];
+
+ private static Vector256<UInt64> _clsVar;
+
+ private Vector256<UInt64> _fld;
+
+ private SimpleUnaryOpTest__DataTable<UInt64, UInt64> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128UInt641Store()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _clsVar), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128UInt641Store()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _fld), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<UInt64, UInt64>(_data, new UInt64[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ Avx.ExtractVector128(
+ (UInt64*)_dataTable.outArrayPtr,
+ Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ Avx.ExtractVector128(
+ (UInt64*)_dataTable.outArrayPtr,
+ Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ Avx.ExtractVector128(
+ (UInt64*)_dataTable.outArrayPtr,
+ Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(UInt64*), typeof(Vector256<UInt64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(UInt64*)),
+ Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(UInt64*), typeof(Vector256<UInt64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(UInt64*)),
+ Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(UInt64*), typeof(Vector256<UInt64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(UInt64*)),
+ Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ Avx.ExtractVector128(
+ (UInt64*)_dataTable.outArrayPtr,
+ _clsVar,
+ 1
+ );
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr);
+ Avx.ExtractVector128((UInt64*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr));
+ Avx.ExtractVector128((UInt64*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr));
+ Avx.ExtractVector128((UInt64*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128UInt641Store();
+ Avx.ExtractVector128((UInt64*)_dataTable.outArrayPtr, test._fld, 1);
+ }
+
+ public void RunFldScenario()
+ {
+ Avx.ExtractVector128((UInt64*)_dataTable.outArrayPtr, _fld, 1);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt64> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray = new UInt64[Op1ElementCount];
+ UInt64[] outArray = new UInt64[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray = new UInt64[Op1ElementCount];
+ UInt64[] outArray = new UInt64[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(UInt64[] firstOp, UInt64[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[2])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 2]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.ExtractVector128)}<UInt64>(Vector256<UInt64><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Reflection;
+using System.Linq;
+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 ExtractVector128UInt641()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128UInt641();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // 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 SimpleUnaryOpTest__ExtractVector128UInt641
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt64);
+ private const int RetElementCount = 16 / sizeof(UInt64);
+
+ private static UInt64[] _data = new UInt64[Op1ElementCount];
+
+ private static Vector256<UInt64> _clsVar;
+
+ private Vector256<UInt64> _fld;
+
+ private SimpleUnaryOpTest__DataTable<UInt64, UInt64> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128UInt641()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _clsVar), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128UInt641()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _fld), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<UInt64, UInt64>(_data, new UInt64[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.ExtractVector128(
+ Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.ExtractVector128(
+ Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.ExtractVector128(
+ Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(UInt64) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(UInt64) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(UInt64) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.ExtractVector128(
+ _clsVar,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr);
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr));
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr));
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128UInt641();
+ var result = Avx.ExtractVector128(test._fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.ExtractVector128(_fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt64> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray = new UInt64[Op1ElementCount];
+ UInt64[] outArray = new UInt64[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray = new UInt64[Op1ElementCount];
+ UInt64[] outArray = new UInt64[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(UInt64[] firstOp, UInt64[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[2])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 2]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.ExtractVector128)}<UInt64>(Vector256<UInt64><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ 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.Collections.Generic;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ static Program()
+ {
+ TestList = new Dictionary<string, Action>() {
+ ["ExtractVector128.Byte.1"] = ExtractVector128Byte1,
+ ["ExtractVector128.SByte.1"] = ExtractVector128SByte1,
+ ["ExtractVector128.Int16.1"] = ExtractVector128Int161,
+ ["ExtractVector128.UInt16.1"] = ExtractVector128UInt161,
+ ["ExtractVector128.Int32.1"] = ExtractVector128Int321,
+ ["ExtractVector128.UInt32.1"] = ExtractVector128UInt321,
+ ["ExtractVector128.Int64.1"] = ExtractVector128Int641,
+ ["ExtractVector128.UInt64.1"] = ExtractVector128UInt641,
+ ["ExtractVector128.Single.1"] = ExtractVector128Single1,
+ ["ExtractVector128.Double.1"] = ExtractVector128Double1,
+ ["InsertVector128.Byte.1"] = InsertVector128Byte1,
+ ["InsertVector128.SByte.1"] = InsertVector128SByte1,
+ ["InsertVector128.Int16.1"] = InsertVector128Int161,
+ ["InsertVector128.UInt16.1"] = InsertVector128UInt161,
+ ["InsertVector128.Int32.1"] = InsertVector128Int321,
+ ["InsertVector128.UInt32.1"] = InsertVector128UInt321,
+ ["InsertVector128.Int64.1"] = InsertVector128Int641,
+ ["InsertVector128.UInt64.1"] = InsertVector128UInt641,
+ ["InsertVector128.Single.1"] = InsertVector128Single1,
+ ["InsertVector128.Double.1"] = InsertVector128Double1,
+ };
+ }
+ }
+}
--- /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="ExtractVector128.Byte.1.cs" />
+ <Compile Include="ExtractVector128.SByte.1.cs" />
+ <Compile Include="ExtractVector128.Int16.1.cs" />
+ <Compile Include="ExtractVector128.UInt16.1.cs" />
+ <Compile Include="ExtractVector128.Int32.1.cs" />
+ <Compile Include="ExtractVector128.UInt32.1.cs" />
+ <Compile Include="ExtractVector128.Int64.1.cs" />
+ <Compile Include="ExtractVector128.UInt64.1.cs" />
+ <Compile Include="ExtractVector128.Single.1.cs" />
+ <Compile Include="ExtractVector128.Double.1.cs" />
+ <Compile Include="InsertVector128.Byte.1.cs" />
+ <Compile Include="InsertVector128.SByte.1.cs" />
+ <Compile Include="InsertVector128.Int16.1.cs" />
+ <Compile Include="InsertVector128.UInt16.1.cs" />
+ <Compile Include="InsertVector128.Int32.1.cs" />
+ <Compile Include="InsertVector128.UInt32.1.cs" />
+ <Compile Include="InsertVector128.Int64.1.cs" />
+ <Compile Include="InsertVector128.UInt64.1.cs" />
+ <Compile Include="InsertVector128.Single.1.cs" />
+ <Compile Include="InsertVector128.Double.1.cs" />
+ <Compile Include="InsertExtractVector128.Avx.cs" />
+ <Compile Include="..\Shared\BooleanBinOpTest_DataTable.cs" />
+ <Compile Include="..\Shared\BooleanTwoCmpOpTest_DataTable.cs" />
+ <Compile Include="..\Shared\Program.cs" />
+ <Compile Include="..\Shared\SimpleBinOpTest_DataTable.cs" />
+ <Compile Include="..\Shared\SimpleTernOpTest_DataTable.cs" />
+ <Compile Include="..\Shared\SimpleUnOpTest_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="ExtractVector128.Byte.1.cs" />
+ <Compile Include="ExtractVector128.SByte.1.cs" />
+ <Compile Include="ExtractVector128.Int16.1.cs" />
+ <Compile Include="ExtractVector128.UInt16.1.cs" />
+ <Compile Include="ExtractVector128.Int32.1.cs" />
+ <Compile Include="ExtractVector128.UInt32.1.cs" />
+ <Compile Include="ExtractVector128.Int64.1.cs" />
+ <Compile Include="ExtractVector128.UInt64.1.cs" />
+ <Compile Include="ExtractVector128.Single.1.cs" />
+ <Compile Include="ExtractVector128.Double.1.cs" />
+ <Compile Include="InsertVector128.Byte.1.cs" />
+ <Compile Include="InsertVector128.SByte.1.cs" />
+ <Compile Include="InsertVector128.Int16.1.cs" />
+ <Compile Include="InsertVector128.UInt16.1.cs" />
+ <Compile Include="InsertVector128.Int32.1.cs" />
+ <Compile Include="InsertVector128.UInt32.1.cs" />
+ <Compile Include="InsertVector128.Int64.1.cs" />
+ <Compile Include="InsertVector128.UInt64.1.cs" />
+ <Compile Include="InsertVector128.Single.1.cs" />
+ <Compile Include="InsertVector128.Double.1.cs" />
+ <Compile Include="InsertExtractVector128.Avx.cs" />
+ <Compile Include="..\Shared\BooleanBinOpTest_DataTable.cs" />
+ <Compile Include="..\Shared\BooleanTwoCmpOpTest_DataTable.cs" />
+ <Compile Include="..\Shared\Program.cs" />
+ <Compile Include="..\Shared\SimpleBinOpTest_DataTable.cs" />
+ <Compile Include="..\Shared\SimpleTernOpTest_DataTable.cs" />
+ <Compile Include="..\Shared\SimpleUnOpTest_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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128Byte1Load()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Byte1Load();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // 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__InsertVector128Byte1Load
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Byte);
+ private const int Op2ElementCount = 16 / sizeof(Byte);
+ private const int RetElementCount = VectorSize / sizeof(Byte);
+
+ private static Byte[] _data1 = new Byte[Op1ElementCount];
+ private static Byte[] _data2 = new Byte[Op2ElementCount];
+
+ private static Vector256<Byte> _clsVar1;
+ private static Vector128<Byte> _clsVar2;
+
+ private Vector256<Byte> _fld1;
+ private Vector128<Byte> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Byte, Byte, Byte> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128Byte1Load()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _clsVar1), ref Unsafe.As<Byte, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar2), ref Unsafe.As<Byte, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128Byte1Load()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[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);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld2), ref Unsafe.As<Byte, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Byte, Byte>(_data1, _data2, new Byte[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.InsertVector128(
+ Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr),
+ (Byte*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr)),
+ (Byte*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr)),
+ (Byte*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<Byte>), typeof(Byte*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Byte*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<Byte>), typeof(Byte*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Byte*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<Byte>), typeof(Byte*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Byte*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.InsertVector128(
+ _clsVar1,
+ (Byte*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, (Byte*)_dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
+ var right = (Byte*)_dataTable.inArray2Ptr;
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr));
+ var right = (Byte*)(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr));
+ var right = (Byte*)(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Byte1Load();
+ var result = Avx.InsertVector128(test._fld1, (Byte*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, (Byte*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.InsertVector128(_fld1, (Byte*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, (Byte*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Byte> left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray1 = new Byte[Op1ElementCount];
+ Byte[] inArray2 = new Byte[Op2ElementCount];
+ Byte[] outArray = new Byte[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray1 = new Byte[Op1ElementCount];
+ Byte[] inArray2 = new Byte[Op2ElementCount];
+ Byte[] outArray = new Byte[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Byte[] left, Byte[] right, Byte[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 15 ? result[i] != right[i - 16] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.InsertVector128)}<Byte>(Vector256<Byte>, Vector128<Byte>.1): {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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Reflection;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128Byte1()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Byte1();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // 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__InsertVector128Byte1
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Byte);
+ private const int Op2ElementCount = 16 / sizeof(Byte);
+ private const int RetElementCount = VectorSize / sizeof(Byte);
+
+ private static Byte[] _data1 = new Byte[Op1ElementCount];
+ private static Byte[] _data2 = new Byte[Op2ElementCount];
+
+ private static Vector256<Byte> _clsVar1;
+ private static Vector128<Byte> _clsVar2;
+
+ private Vector256<Byte> _fld1;
+ private Vector128<Byte> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Byte, Byte, Byte> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128Byte1()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _clsVar1), ref Unsafe.As<Byte, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar2), ref Unsafe.As<Byte, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128Byte1()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[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);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld2), ref Unsafe.As<Byte, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Byte, Byte>(_data1, _data2, new Byte[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.InsertVector128(
+ Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr)),
+ LoadVector128((Byte*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr)),
+ LoadVector128((Byte*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.InsertVector128(
+ _clsVar1,
+ _clsVar2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr));
+ var right = LoadVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr));
+ var right = LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Byte1();
+ var result = Avx.InsertVector128(test._fld1, test._fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.InsertVector128(_fld1, _fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Byte> left, Vector128<Byte> right, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray1 = new Byte[Op1ElementCount];
+ Byte[] inArray2 = new Byte[Op2ElementCount];
+ Byte[] outArray = new Byte[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray1 = new Byte[Op1ElementCount];
+ Byte[] inArray2 = new Byte[Op2ElementCount];
+ Byte[] outArray = new Byte[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Byte[] left, Byte[] right, Byte[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 15 ? result[i] != right[i - 16] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.InsertVector128)}<Byte>(Vector256<Byte>, Vector128<Byte>.1): {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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128Double1Load()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Double1Load();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // 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__InsertVector128Double1Load
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Double);
+ private const int Op2ElementCount = 16 / sizeof(Double);
+ private const int RetElementCount = VectorSize / sizeof(Double);
+
+ private static Double[] _data1 = new Double[Op1ElementCount];
+ private static Double[] _data2 = new Double[Op2ElementCount];
+
+ private static Vector256<Double> _clsVar1;
+ private static Vector128<Double> _clsVar2;
+
+ private Vector256<Double> _fld1;
+ private Vector128<Double> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128Double1Load()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128Double1Load()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (double)(random.NextDouble()); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.InsertVector128(
+ Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr),
+ (Double*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr)),
+ (Double*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr)),
+ (Double*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<Double>), typeof(Double*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Double*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<Double>), typeof(Double*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Double*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<Double>), typeof(Double*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Double*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.InsertVector128(
+ _clsVar1,
+ (Double*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, (Double*)_dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
+ var right = (Double*)_dataTable.inArray2Ptr;
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
+ var right = (Double*)(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
+ var right = (Double*)(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Double1Load();
+ var result = Avx.InsertVector128(test._fld1, (Double*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, (Double*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.InsertVector128(_fld1, (Double*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, (Double*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Double> left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[Op1ElementCount];
+ Double[] inArray2 = new Double[Op2ElementCount];
+ Double[] outArray = new Double[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[Op1ElementCount];
+ Double[] inArray2 = new Double[Op2ElementCount];
+ Double[] outArray = new Double[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+ {
+ if (BitConverter.DoubleToInt64Bits(result[0]) != BitConverter.DoubleToInt64Bits(left[0]))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 1 ? BitConverter.DoubleToInt64Bits(result[i]) != BitConverter.DoubleToInt64Bits(right[i - 2]) : BitConverter.DoubleToInt64Bits(result[i]) != BitConverter.DoubleToInt64Bits(left[i])))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.InsertVector128)}<Double>(Vector256<Double>, Vector128<Double>.1): {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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Reflection;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128Double1()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Double1();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // 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__InsertVector128Double1
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Double);
+ private const int Op2ElementCount = 16 / sizeof(Double);
+ private const int RetElementCount = VectorSize / sizeof(Double);
+
+ private static Double[] _data1 = new Double[Op1ElementCount];
+ private static Double[] _data2 = new Double[Op2ElementCount];
+
+ private static Vector256<Double> _clsVar1;
+ private static Vector128<Double> _clsVar2;
+
+ private Vector256<Double> _fld1;
+ private Vector128<Double> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128Double1()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128Double1()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (double)(random.NextDouble()); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.InsertVector128(
+ Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr)),
+ LoadVector128((Double*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Double) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Double) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr)),
+ LoadVector128((Double*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Double) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.InsertVector128(
+ _clsVar1,
+ _clsVar2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
+ var right = LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
+ var right = LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Double1();
+ var result = Avx.InsertVector128(test._fld1, test._fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.InsertVector128(_fld1, _fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[Op1ElementCount];
+ Double[] inArray2 = new Double[Op2ElementCount];
+ Double[] outArray = new Double[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[Op1ElementCount];
+ Double[] inArray2 = new Double[Op2ElementCount];
+ Double[] outArray = new Double[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 1 ? result[i] != right[i - 2] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.InsertVector128)}<Double>(Vector256<Double>, Vector128<Double>.1): {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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128Int161Load()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Int161Load();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // 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__InsertVector128Int161Load
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int16);
+ private const int Op2ElementCount = 16 / sizeof(Int16);
+ private const int RetElementCount = VectorSize / sizeof(Int16);
+
+ private static Int16[] _data1 = new Int16[Op1ElementCount];
+ private static Int16[] _data2 = new Int16[Op2ElementCount];
+
+ private static Vector256<Int16> _clsVar1;
+ private static Vector128<Int16> _clsVar2;
+
+ private Vector256<Int16> _fld1;
+ private Vector128<Int16> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128Int161Load()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (short)(random.Next(0, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _clsVar1), ref Unsafe.As<Int16, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (short)(random.Next(0,short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar2), ref Unsafe.As<Int16, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128Int161Load()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (short)(random.Next(0, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _fld1), ref Unsafe.As<Int16, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (short)(random.Next(0,short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld2), ref Unsafe.As<Int16, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (short)(random.Next(0, short.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (short)(random.Next(0,short.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.InsertVector128(
+ Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr),
+ (Int16*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr)),
+ (Int16*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr)),
+ (Int16*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<Int16>), typeof(Int16*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Int16*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<Int16>), typeof(Int16*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Int16*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<Int16>), typeof(Int16*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Int16*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.InsertVector128(
+ _clsVar1,
+ (Int16*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, (Int16*)_dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
+ var right = (Int16*)_dataTable.inArray2Ptr;
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
+ var right = (Int16*)(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
+ var right = (Int16*)(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Int161Load();
+ var result = Avx.InsertVector128(test._fld1, (Int16*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, (Int16*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.InsertVector128(_fld1, (Int16*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, (Int16*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int16> left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray1 = new Int16[Op1ElementCount];
+ Int16[] inArray2 = new Int16[Op2ElementCount];
+ Int16[] outArray = new Int16[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray1 = new Int16[Op1ElementCount];
+ Int16[] inArray2 = new Int16[Op2ElementCount];
+ Int16[] outArray = new Int16[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 7 ? result[i] != right[i - 8] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.InsertVector128)}<Int16>(Vector256<Int16>, Vector128<Int16>.1): {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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Reflection;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128Int161()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Int161();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // 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__InsertVector128Int161
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int16);
+ private const int Op2ElementCount = 16 / sizeof(Int16);
+ private const int RetElementCount = VectorSize / sizeof(Int16);
+
+ private static Int16[] _data1 = new Int16[Op1ElementCount];
+ private static Int16[] _data2 = new Int16[Op2ElementCount];
+
+ private static Vector256<Int16> _clsVar1;
+ private static Vector128<Int16> _clsVar2;
+
+ private Vector256<Int16> _fld1;
+ private Vector128<Int16> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128Int161()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (short)(random.Next(0, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _clsVar1), ref Unsafe.As<Int16, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (short)(random.Next(0, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar2), ref Unsafe.As<Int16, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128Int161()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (short)(random.Next(0, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _fld1), ref Unsafe.As<Int16, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (short)(random.Next(0, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld2), ref Unsafe.As<Int16, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (short)(random.Next(0, short.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (short)(random.Next(0, short.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.InsertVector128(
+ Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr)),
+ LoadVector128((Int16*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Int16) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Int16) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr)),
+ LoadVector128((Int16*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Int16) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.InsertVector128(
+ _clsVar1,
+ _clsVar2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
+ var right = LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
+ var right = LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Int161();
+ var result = Avx.InsertVector128(test._fld1, test._fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.InsertVector128(_fld1, _fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int16> left, Vector128<Int16> right, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray1 = new Int16[Op1ElementCount];
+ Int16[] inArray2 = new Int16[Op2ElementCount];
+ Int16[] outArray = new Int16[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray1 = new Int16[Op1ElementCount];
+ Int16[] inArray2 = new Int16[Op2ElementCount];
+ Int16[] outArray = new Int16[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 7 ? result[i] != right[i - 8] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.InsertVector128)}<Int16>(Vector256<Int16>, Vector128<Int16>.1): {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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128Int321Load()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Int321Load();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // 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__InsertVector128Int321Load
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int32);
+ private const int Op2ElementCount = 16 / sizeof(Int32);
+ private const int RetElementCount = VectorSize / sizeof(Int32);
+
+ private static Int32[] _data1 = new Int32[Op1ElementCount];
+ private static Int32[] _data2 = new Int32[Op2ElementCount];
+
+ private static Vector256<Int32> _clsVar1;
+ private static Vector128<Int32> _clsVar2;
+
+ private Vector256<Int32> _fld1;
+ private Vector128<Int32> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int32, Int32, Int32> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128Int321Load()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (int)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _clsVar1), ref Unsafe.As<Int32, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (int)(random.Next(0,int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar2), ref Unsafe.As<Int32, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128Int321Load()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (int)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _fld1), ref Unsafe.As<Int32, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (int)(random.Next(0,int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld2), ref Unsafe.As<Int32, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (int)(random.Next(0, int.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (int)(random.Next(0,int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int32, Int32, Int32>(_data1, _data2, new Int32[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.InsertVector128(
+ Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr),
+ (Int32*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr)),
+ (Int32*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr)),
+ (Int32*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<Int32>), typeof(Int32*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Int32*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<Int32>), typeof(Int32*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Int32*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<Int32>), typeof(Int32*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Int32*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.InsertVector128(
+ _clsVar1,
+ (Int32*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, (Int32*)_dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
+ var right = (Int32*)_dataTable.inArray2Ptr;
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
+ var right = (Int32*)(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
+ var right = (Int32*)(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Int321Load();
+ var result = Avx.InsertVector128(test._fld1, (Int32*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, (Int32*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.InsertVector128(_fld1, (Int32*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, (Int32*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int32> left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray1 = new Int32[Op1ElementCount];
+ Int32[] inArray2 = new Int32[Op2ElementCount];
+ Int32[] outArray = new Int32[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray1 = new Int32[Op1ElementCount];
+ Int32[] inArray2 = new Int32[Op2ElementCount];
+ Int32[] outArray = new Int32[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int32[] left, Int32[] right, Int32[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 3 ? result[i] != right[i - 4] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.InsertVector128)}<Int32>(Vector256<Int32>, Vector128<Int32>.1): {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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Reflection;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128Int321()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Int321();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // 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__InsertVector128Int321
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int32);
+ private const int Op2ElementCount = 16 / sizeof(Int32);
+ private const int RetElementCount = VectorSize / sizeof(Int32);
+
+ private static Int32[] _data1 = new Int32[Op1ElementCount];
+ private static Int32[] _data2 = new Int32[Op2ElementCount];
+
+ private static Vector256<Int32> _clsVar1;
+ private static Vector128<Int32> _clsVar2;
+
+ private Vector256<Int32> _fld1;
+ private Vector128<Int32> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int32, Int32, Int32> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128Int321()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (int)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _clsVar1), ref Unsafe.As<Int32, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (int)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar2), ref Unsafe.As<Int32, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128Int321()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (int)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _fld1), ref Unsafe.As<Int32, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (int)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld2), ref Unsafe.As<Int32, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (int)(random.Next(0, int.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (int)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int32, Int32, Int32>(_data1, _data2, new Int32[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.InsertVector128(
+ Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr)),
+ LoadVector128((Int32*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Int32) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Int32) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr)),
+ LoadVector128((Int32*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Int32) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.InsertVector128(
+ _clsVar1,
+ _clsVar2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
+ var right = LoadVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
+ var right = LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Int321();
+ var result = Avx.InsertVector128(test._fld1, test._fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.InsertVector128(_fld1, _fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int32> left, Vector128<Int32> right, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray1 = new Int32[Op1ElementCount];
+ Int32[] inArray2 = new Int32[Op2ElementCount];
+ Int32[] outArray = new Int32[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray1 = new Int32[Op1ElementCount];
+ Int32[] inArray2 = new Int32[Op2ElementCount];
+ Int32[] outArray = new Int32[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int32[] left, Int32[] right, Int32[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 3 ? result[i] != right[i - 4] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.InsertVector128)}<Int32>(Vector256<Int32>, Vector128<Int32>.1): {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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128Int641Load()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Int641Load();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // 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__InsertVector128Int641Load
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int64);
+ private const int Op2ElementCount = 16 / sizeof(Int64);
+ private const int RetElementCount = VectorSize / sizeof(Int64);
+
+ private static Int64[] _data1 = new Int64[Op1ElementCount];
+ private static Int64[] _data2 = new Int64[Op2ElementCount];
+
+ private static Vector256<Int64> _clsVar1;
+ private static Vector128<Int64> _clsVar2;
+
+ private Vector256<Int64> _fld1;
+ private Vector128<Int64> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int64, Int64, Int64> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128Int641Load()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (long)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _clsVar1), ref Unsafe.As<Int64, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (long)(random.Next(0,int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar2), ref Unsafe.As<Int64, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128Int641Load()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (long)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _fld1), ref Unsafe.As<Int64, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (long)(random.Next(0,int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld2), ref Unsafe.As<Int64, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (long)(random.Next(0, int.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (long)(random.Next(0,int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int64, Int64, Int64>(_data1, _data2, new Int64[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.InsertVector128(
+ Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr),
+ (Int64*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr)),
+ (Int64*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr)),
+ (Int64*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<Int64>), typeof(Int64*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Int64*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<Int64>), typeof(Int64*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Int64*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<Int64>), typeof(Int64*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Int64*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.InsertVector128(
+ _clsVar1,
+ (Int64*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, (Int64*)_dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr);
+ var right = (Int64*)_dataTable.inArray2Ptr;
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr));
+ var right = (Int64*)(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr));
+ var right = (Int64*)(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Int641Load();
+ var result = Avx.InsertVector128(test._fld1, (Int64*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, (Int64*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.InsertVector128(_fld1, (Int64*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, (Int64*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int64> left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray1 = new Int64[Op1ElementCount];
+ Int64[] inArray2 = new Int64[Op2ElementCount];
+ Int64[] outArray = new Int64[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray1 = new Int64[Op1ElementCount];
+ Int64[] inArray2 = new Int64[Op2ElementCount];
+ Int64[] outArray = new Int64[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int64[] left, Int64[] right, Int64[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 1 ? result[i] != right[i - 2] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.InsertVector128)}<Int64>(Vector256<Int64>, Vector128<Int64>.1): {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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Reflection;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128Int641()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Int641();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // 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__InsertVector128Int641
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int64);
+ private const int Op2ElementCount = 16 / sizeof(Int64);
+ private const int RetElementCount = VectorSize / sizeof(Int64);
+
+ private static Int64[] _data1 = new Int64[Op1ElementCount];
+ private static Int64[] _data2 = new Int64[Op2ElementCount];
+
+ private static Vector256<Int64> _clsVar1;
+ private static Vector128<Int64> _clsVar2;
+
+ private Vector256<Int64> _fld1;
+ private Vector128<Int64> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int64, Int64, Int64> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128Int641()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (long)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _clsVar1), ref Unsafe.As<Int64, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (long)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar2), ref Unsafe.As<Int64, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128Int641()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (long)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _fld1), ref Unsafe.As<Int64, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (long)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld2), ref Unsafe.As<Int64, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (long)(random.Next(0, int.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (long)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int64, Int64, Int64>(_data1, _data2, new Int64[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.InsertVector128(
+ Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr)),
+ LoadVector128((Int64*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Int64) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Int64) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr)),
+ LoadVector128((Int64*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Int64) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.InsertVector128(
+ _clsVar1,
+ _clsVar2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr));
+ var right = LoadVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr));
+ var right = LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Int641();
+ var result = Avx.InsertVector128(test._fld1, test._fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.InsertVector128(_fld1, _fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int64> left, Vector128<Int64> right, void* result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray1 = new Int64[Op1ElementCount];
+ Int64[] inArray2 = new Int64[Op2ElementCount];
+ Int64[] outArray = new Int64[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray1 = new Int64[Op1ElementCount];
+ Int64[] inArray2 = new Int64[Op2ElementCount];
+ Int64[] outArray = new Int64[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int64[] left, Int64[] right, Int64[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 1 ? result[i] != right[i - 2] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.InsertVector128)}<Int64>(Vector256<Int64>, Vector128<Int64>.1): {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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128SByte1Load()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128SByte1Load();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // 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__InsertVector128SByte1Load
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(SByte);
+ private const int Op2ElementCount = 16 / sizeof(SByte);
+ private const int RetElementCount = VectorSize / sizeof(SByte);
+
+ private static SByte[] _data1 = new SByte[Op1ElementCount];
+ private static SByte[] _data2 = new SByte[Op2ElementCount];
+
+ private static Vector256<SByte> _clsVar1;
+ private static Vector128<SByte> _clsVar2;
+
+ private Vector256<SByte> _fld1;
+ private Vector128<SByte> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<SByte, SByte, SByte> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128SByte1Load()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _clsVar1), ref Unsafe.As<SByte, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (sbyte)(random.Next(0,sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar2), ref Unsafe.As<SByte, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128SByte1Load()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _fld1), ref Unsafe.As<SByte, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (sbyte)(random.Next(0,sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld2), ref Unsafe.As<SByte, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (sbyte)(random.Next(0,sbyte.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<SByte, SByte, SByte>(_data1, _data2, new SByte[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.InsertVector128(
+ Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr),
+ (SByte*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr)),
+ (SByte*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr)),
+ (SByte*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<SByte>), typeof(SByte*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(SByte*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<SByte>), typeof(SByte*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(SByte*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<SByte>), typeof(SByte*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(SByte*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.InsertVector128(
+ _clsVar1,
+ (SByte*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, (SByte*)_dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr);
+ var right = (SByte*)_dataTable.inArray2Ptr;
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr));
+ var right = (SByte*)(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr));
+ var right = (SByte*)(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128SByte1Load();
+ var result = Avx.InsertVector128(test._fld1, (SByte*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, (SByte*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.InsertVector128(_fld1, (SByte*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, (SByte*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<SByte> left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray1 = new SByte[Op1ElementCount];
+ SByte[] inArray2 = new SByte[Op2ElementCount];
+ SByte[] outArray = new SByte[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray1 = new SByte[Op1ElementCount];
+ SByte[] inArray2 = new SByte[Op2ElementCount];
+ SByte[] outArray = new SByte[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 15 ? result[i] != right[i - 16] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.InsertVector128)}<SByte>(Vector256<SByte>, Vector128<SByte>.1): {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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Reflection;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128SByte1()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128SByte1();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // 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__InsertVector128SByte1
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(SByte);
+ private const int Op2ElementCount = 16 / sizeof(SByte);
+ private const int RetElementCount = VectorSize / sizeof(SByte);
+
+ private static SByte[] _data1 = new SByte[Op1ElementCount];
+ private static SByte[] _data2 = new SByte[Op2ElementCount];
+
+ private static Vector256<SByte> _clsVar1;
+ private static Vector128<SByte> _clsVar2;
+
+ private Vector256<SByte> _fld1;
+ private Vector128<SByte> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<SByte, SByte, SByte> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128SByte1()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _clsVar1), ref Unsafe.As<SByte, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar2), ref Unsafe.As<SByte, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128SByte1()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _fld1), ref Unsafe.As<SByte, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld2), ref Unsafe.As<SByte, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<SByte, SByte, SByte>(_data1, _data2, new SByte[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.InsertVector128(
+ Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr)),
+ LoadVector128((SByte*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(SByte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(SByte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr)),
+ LoadVector128((SByte*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(SByte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.InsertVector128(
+ _clsVar1,
+ _clsVar2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr));
+ var right = LoadVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr));
+ var right = LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128SByte1();
+ var result = Avx.InsertVector128(test._fld1, test._fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.InsertVector128(_fld1, _fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<SByte> left, Vector128<SByte> right, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray1 = new SByte[Op1ElementCount];
+ SByte[] inArray2 = new SByte[Op2ElementCount];
+ SByte[] outArray = new SByte[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray1 = new SByte[Op1ElementCount];
+ SByte[] inArray2 = new SByte[Op2ElementCount];
+ SByte[] outArray = new SByte[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 15 ? result[i] != right[i - 16] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.InsertVector128)}<SByte>(Vector256<SByte>, Vector128<SByte>.1): {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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128Single1Load()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Single1Load();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // 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__InsertVector128Single1Load
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Single);
+ private const int Op2ElementCount = 16 / sizeof(Single);
+ private const int RetElementCount = VectorSize / sizeof(Single);
+
+ private static Single[] _data1 = new Single[Op1ElementCount];
+ private static Single[] _data2 = new Single[Op2ElementCount];
+
+ private static Vector256<Single> _clsVar1;
+ private static Vector128<Single> _clsVar2;
+
+ private Vector256<Single> _fld1;
+ private Vector128<Single> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128Single1Load()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _clsVar1), ref Unsafe.As<Single, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar2), ref Unsafe.As<Single, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128Single1Load()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _fld2), ref Unsafe.As<Single, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (float)(random.NextDouble()); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.InsertVector128(
+ Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr),
+ (Single*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr)),
+ (Single*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr)),
+ (Single*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<Single>), typeof(Single*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Single*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<Single>), typeof(Single*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Single*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<Single>), typeof(Single*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Single*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.InsertVector128(
+ _clsVar1,
+ (Single*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, (Single*)_dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
+ var right = (Single*)_dataTable.inArray2Ptr;
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
+ var right = (Single*)(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
+ var right = (Single*)(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Single1Load();
+ var result = Avx.InsertVector128(test._fld1, (Single*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, (Single*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.InsertVector128(_fld1, (Single*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, (Single*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Single> left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Single[] inArray1 = new Single[Op1ElementCount];
+ Single[] inArray2 = new Single[Op2ElementCount];
+ Single[] outArray = new Single[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Single[] inArray1 = new Single[Op1ElementCount];
+ Single[] inArray2 = new Single[Op2ElementCount];
+ Single[] outArray = new Single[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Single[] left, Single[] right, Single[] result, [CallerMemberName] string method = "")
+ {
+ if (BitConverter.SingleToInt32Bits(result[0]) != BitConverter.SingleToInt32Bits(left[0]))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 3 ? BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(right[i - 4]) : BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(left[i])))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.InsertVector128)}<Single>(Vector256<Single>, Vector128<Single>.1): {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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Reflection;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128Single1()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Single1();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // 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__InsertVector128Single1
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Single);
+ private const int Op2ElementCount = 16 / sizeof(Single);
+ private const int RetElementCount = VectorSize / sizeof(Single);
+
+ private static Single[] _data1 = new Single[Op1ElementCount];
+ private static Single[] _data2 = new Single[Op2ElementCount];
+
+ private static Vector256<Single> _clsVar1;
+ private static Vector128<Single> _clsVar2;
+
+ private Vector256<Single> _fld1;
+ private Vector128<Single> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128Single1()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _clsVar1), ref Unsafe.As<Single, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar2), ref Unsafe.As<Single, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128Single1()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _fld2), ref Unsafe.As<Single, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (float)(random.NextDouble()); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.InsertVector128(
+ Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr)),
+ LoadVector128((Single*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Single) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Single) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr)),
+ LoadVector128((Single*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Single) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.InsertVector128(
+ _clsVar1,
+ _clsVar2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
+ var right = LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
+ var right = LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Single1();
+ var result = Avx.InsertVector128(test._fld1, test._fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.InsertVector128(_fld1, _fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ {
+ Single[] inArray1 = new Single[Op1ElementCount];
+ Single[] inArray2 = new Single[Op2ElementCount];
+ Single[] outArray = new Single[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Single[] inArray1 = new Single[Op1ElementCount];
+ Single[] inArray2 = new Single[Op2ElementCount];
+ Single[] outArray = new Single[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Single[] left, Single[] right, Single[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 3 ? result[i] != right[i - 4] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.InsertVector128)}<Single>(Vector256<Single>, Vector128<Single>.1): {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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128UInt161Load()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128UInt161Load();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // 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__InsertVector128UInt161Load
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt16);
+ private const int Op2ElementCount = 16 / sizeof(UInt16);
+ private const int RetElementCount = VectorSize / sizeof(UInt16);
+
+ private static UInt16[] _data1 = new UInt16[Op1ElementCount];
+ private static UInt16[] _data2 = new UInt16[Op2ElementCount];
+
+ private static Vector256<UInt16> _clsVar1;
+ private static Vector128<UInt16> _clsVar2;
+
+ private Vector256<UInt16> _fld1;
+ private Vector128<UInt16> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128UInt161Load()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _clsVar1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ushort)(random.Next(0,ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar2), ref Unsafe.As<UInt16, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128UInt161Load()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[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);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ushort)(random.Next(0,ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _fld2), ref Unsafe.As<UInt16, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ushort)(random.Next(0,ushort.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16>(_data1, _data2, new UInt16[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.InsertVector128(
+ Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr),
+ (UInt16*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr)),
+ (UInt16*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr)),
+ (UInt16*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<UInt16>), typeof(UInt16*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(UInt16*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<UInt16>), typeof(UInt16*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(UInt16*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<UInt16>), typeof(UInt16*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(UInt16*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.InsertVector128(
+ _clsVar1,
+ (UInt16*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, (UInt16*)_dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr);
+ var right = (UInt16*)_dataTable.inArray2Ptr;
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var right = (UInt16*)(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var right = (UInt16*)(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128UInt161Load();
+ var result = Avx.InsertVector128(test._fld1, (UInt16*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, (UInt16*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.InsertVector128(_fld1, (UInt16*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, (UInt16*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt16> left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray1 = new UInt16[Op1ElementCount];
+ UInt16[] inArray2 = new UInt16[Op2ElementCount];
+ UInt16[] outArray = new UInt16[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray1 = new UInt16[Op1ElementCount];
+ UInt16[] inArray2 = new UInt16[Op2ElementCount];
+ UInt16[] outArray = new UInt16[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(UInt16[] left, UInt16[] right, UInt16[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 7 ? result[i] != right[i - 8] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.InsertVector128)}<UInt16>(Vector256<UInt16>, Vector128<UInt16>.1): {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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Reflection;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128UInt161()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128UInt161();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // 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__InsertVector128UInt161
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt16);
+ private const int Op2ElementCount = 16 / sizeof(UInt16);
+ private const int RetElementCount = VectorSize / sizeof(UInt16);
+
+ private static UInt16[] _data1 = new UInt16[Op1ElementCount];
+ private static UInt16[] _data2 = new UInt16[Op2ElementCount];
+
+ private static Vector256<UInt16> _clsVar1;
+ private static Vector128<UInt16> _clsVar2;
+
+ private Vector256<UInt16> _fld1;
+ private Vector128<UInt16> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128UInt161()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _clsVar1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar2), ref Unsafe.As<UInt16, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128UInt161()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[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);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _fld2), ref Unsafe.As<UInt16, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16>(_data1, _data2, new UInt16[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.InsertVector128(
+ Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr)),
+ LoadVector128((UInt16*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(UInt16) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(UInt16) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr)),
+ LoadVector128((UInt16*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(UInt16) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.InsertVector128(
+ _clsVar1,
+ _clsVar2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var right = LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var right = LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128UInt161();
+ var result = Avx.InsertVector128(test._fld1, test._fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.InsertVector128(_fld1, _fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt16> left, Vector128<UInt16> right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray1 = new UInt16[Op1ElementCount];
+ UInt16[] inArray2 = new UInt16[Op2ElementCount];
+ UInt16[] outArray = new UInt16[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray1 = new UInt16[Op1ElementCount];
+ UInt16[] inArray2 = new UInt16[Op2ElementCount];
+ UInt16[] outArray = new UInt16[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(UInt16[] left, UInt16[] right, UInt16[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 7 ? result[i] != right[i - 8] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.InsertVector128)}<UInt16>(Vector256<UInt16>, Vector128<UInt16>.1): {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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128UInt321Load()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128UInt321Load();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // 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__InsertVector128UInt321Load
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt32);
+ private const int Op2ElementCount = 16 / sizeof(UInt32);
+ private const int RetElementCount = VectorSize / sizeof(UInt32);
+
+ private static UInt32[] _data1 = new UInt32[Op1ElementCount];
+ private static UInt32[] _data2 = new UInt32[Op2ElementCount];
+
+ private static Vector256<UInt32> _clsVar1;
+ private static Vector128<UInt32> _clsVar2;
+
+ private Vector256<UInt32> _fld1;
+ private Vector128<UInt32> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128UInt321Load()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _clsVar1), ref Unsafe.As<UInt32, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (uint)(random.Next(0,int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _clsVar2), ref Unsafe.As<UInt32, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128UInt321Load()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[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);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (uint)(random.Next(0,int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _fld2), ref Unsafe.As<UInt32, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (uint)(random.Next(0, int.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (uint)(random.Next(0,int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32>(_data1, _data2, new UInt32[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.InsertVector128(
+ Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr),
+ (UInt32*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr)),
+ (UInt32*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr)),
+ (UInt32*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<UInt32>), typeof(UInt32*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(UInt32*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<UInt32>), typeof(UInt32*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(UInt32*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<UInt32>), typeof(UInt32*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(UInt32*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.InsertVector128(
+ _clsVar1,
+ (UInt32*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, (UInt32*)_dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr);
+ var right = (UInt32*)_dataTable.inArray2Ptr;
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var right = (UInt32*)(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var right = (UInt32*)(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128UInt321Load();
+ var result = Avx.InsertVector128(test._fld1, (UInt32*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, (UInt32*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.InsertVector128(_fld1, (UInt32*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, (UInt32*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt32> left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray1 = new UInt32[Op1ElementCount];
+ UInt32[] inArray2 = new UInt32[Op2ElementCount];
+ UInt32[] outArray = new UInt32[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray1 = new UInt32[Op1ElementCount];
+ UInt32[] inArray2 = new UInt32[Op2ElementCount];
+ UInt32[] outArray = new UInt32[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(UInt32[] left, UInt32[] right, UInt32[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 3 ? result[i] != right[i - 4] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.InsertVector128)}<UInt32>(Vector256<UInt32>, Vector128<UInt32>.1): {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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Reflection;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128UInt321()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128UInt321();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // 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__InsertVector128UInt321
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt32);
+ private const int Op2ElementCount = 16 / sizeof(UInt32);
+ private const int RetElementCount = VectorSize / sizeof(UInt32);
+
+ private static UInt32[] _data1 = new UInt32[Op1ElementCount];
+ private static UInt32[] _data2 = new UInt32[Op2ElementCount];
+
+ private static Vector256<UInt32> _clsVar1;
+ private static Vector128<UInt32> _clsVar2;
+
+ private Vector256<UInt32> _fld1;
+ private Vector128<UInt32> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128UInt321()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _clsVar1), ref Unsafe.As<UInt32, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _clsVar2), ref Unsafe.As<UInt32, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128UInt321()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[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);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _fld2), ref Unsafe.As<UInt32, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (uint)(random.Next(0, int.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (uint)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32>(_data1, _data2, new UInt32[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.InsertVector128(
+ Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr)),
+ LoadVector128((UInt32*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(UInt32) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(UInt32) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr)),
+ LoadVector128((UInt32*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(UInt32) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.InsertVector128(
+ _clsVar1,
+ _clsVar2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var right = LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var right = LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128UInt321();
+ var result = Avx.InsertVector128(test._fld1, test._fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.InsertVector128(_fld1, _fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt32> left, Vector128<UInt32> right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray1 = new UInt32[Op1ElementCount];
+ UInt32[] inArray2 = new UInt32[Op2ElementCount];
+ UInt32[] outArray = new UInt32[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray1 = new UInt32[Op1ElementCount];
+ UInt32[] inArray2 = new UInt32[Op2ElementCount];
+ UInt32[] outArray = new UInt32[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(UInt32[] left, UInt32[] right, UInt32[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 3 ? result[i] != right[i - 4] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.InsertVector128)}<UInt32>(Vector256<UInt32>, Vector128<UInt32>.1): {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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128UInt641Load()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128UInt641Load();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // 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__InsertVector128UInt641Load
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt64);
+ private const int Op2ElementCount = 16 / sizeof(UInt64);
+ private const int RetElementCount = VectorSize / sizeof(UInt64);
+
+ private static UInt64[] _data1 = new UInt64[Op1ElementCount];
+ private static UInt64[] _data2 = new UInt64[Op2ElementCount];
+
+ private static Vector256<UInt64> _clsVar1;
+ private static Vector128<UInt64> _clsVar2;
+
+ private Vector256<UInt64> _fld1;
+ private Vector128<UInt64> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128UInt641Load()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _clsVar1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ulong)(random.Next(0,int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128UInt641Load()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[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);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ulong)(random.Next(0,int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ulong)(random.Next(0,int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64>(_data1, _data2, new UInt64[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.InsertVector128(
+ Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr),
+ (UInt64*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr)),
+ (UInt64*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr)),
+ (UInt64*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<UInt64>), typeof(UInt64*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(UInt64*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<UInt64>), typeof(UInt64*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(UInt64*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<UInt64>), typeof(UInt64*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(UInt64*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.InsertVector128(
+ _clsVar1,
+ (UInt64*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, (UInt64*)_dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr);
+ var right = (UInt64*)_dataTable.inArray2Ptr;
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr));
+ var right = (UInt64*)(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr));
+ var right = (UInt64*)(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128UInt641Load();
+ var result = Avx.InsertVector128(test._fld1, (UInt64*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, (UInt64*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.InsertVector128(_fld1, (UInt64*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, (UInt64*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt64> left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray1 = new UInt64[Op1ElementCount];
+ UInt64[] inArray2 = new UInt64[Op2ElementCount];
+ UInt64[] outArray = new UInt64[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray1 = new UInt64[Op1ElementCount];
+ UInt64[] inArray2 = new UInt64[Op2ElementCount];
+ UInt64[] outArray = new UInt64[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(UInt64[] left, UInt64[] right, UInt64[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 1 ? result[i] != right[i - 2] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.InsertVector128)}<UInt64>(Vector256<UInt64>, Vector128<UInt64>.1): {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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Reflection;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128UInt641()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128UInt641();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // 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__InsertVector128UInt641
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt64);
+ private const int Op2ElementCount = 16 / sizeof(UInt64);
+ private const int RetElementCount = VectorSize / sizeof(UInt64);
+
+ private static UInt64[] _data1 = new UInt64[Op1ElementCount];
+ private static UInt64[] _data2 = new UInt64[Op2ElementCount];
+
+ private static Vector256<UInt64> _clsVar1;
+ private static Vector128<UInt64> _clsVar2;
+
+ private Vector256<UInt64> _fld1;
+ private Vector128<UInt64> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128UInt641()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _clsVar1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128UInt641()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[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);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64>(_data1, _data2, new UInt64[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.InsertVector128(
+ Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr)),
+ LoadVector128((UInt64*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(UInt64) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(UInt64) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr)),
+ LoadVector128((UInt64*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(UInt64) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.InsertVector128(
+ _clsVar1,
+ _clsVar2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr));
+ var right = LoadVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr));
+ var right = LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128UInt641();
+ var result = Avx.InsertVector128(test._fld1, test._fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.InsertVector128(_fld1, _fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt64> left, Vector128<UInt64> right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray1 = new UInt64[Op1ElementCount];
+ UInt64[] inArray2 = new UInt64[Op2ElementCount];
+ UInt64[] outArray = new UInt64[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray1 = new UInt64[Op1ElementCount];
+ UInt64[] inArray2 = new UInt64[Op2ElementCount];
+ UInt64[] outArray = new UInt64[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(UInt64[] left, UInt64[] right, UInt64[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 1 ? result[i] != right[i - 2] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.InsertVector128)}<UInt64>(Vector256<UInt64>, Vector128<UInt64>.1): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
["ExtendToVector256.UInt16"] = ExtendToVector256UInt16,
["ExtendToVector256.UInt32"] = ExtendToVector256UInt32,
["ExtendToVector256.UInt64"] = ExtendToVector256UInt64,
+ ["ExtractVector128.Byte.1.Store"] = ExtractVector128Byte1Store,
+ ["ExtractVector128.SByte.1.Store"] = ExtractVector128SByte1Store,
+ ["ExtractVector128.Int16.1.Store"] = ExtractVector128Int161Store,
+ ["ExtractVector128.UInt16.1.Store"] = ExtractVector128UInt161Store,
+ ["ExtractVector128.Int32.1.Store"] = ExtractVector128Int321Store,
+ ["ExtractVector128.UInt32.1.Store"] = ExtractVector128UInt321Store,
+ ["ExtractVector128.Int64.1.Store"] = ExtractVector128Int641Store,
+ ["ExtractVector128.UInt64.1.Store"] = ExtractVector128UInt641Store,
+ ["ExtractVector128.Single.1.Store"] = ExtractVector128Single1Store,
+ ["ExtractVector128.Double.1.Store"] = ExtractVector128Double1Store,
+ ["InsertVector128.Byte.1.Load"] = InsertVector128Byte1Load,
+ ["InsertVector128.SByte.1.Load"] = InsertVector128SByte1Load,
+ ["InsertVector128.Int16.1.Load"] = InsertVector128Int161Load,
+ ["InsertVector128.UInt16.1.Load"] = InsertVector128UInt161Load,
+ ["InsertVector128.Int32.1.Load"] = InsertVector128Int321Load,
+ ["InsertVector128.UInt32.1.Load"] = InsertVector128UInt321Load,
+ ["InsertVector128.Int64.1.Load"] = InsertVector128Int641Load,
+ ["InsertVector128.UInt64.1.Load"] = InsertVector128UInt641Load,
+ ["InsertVector128.Single.1.Load"] = InsertVector128Single1Load,
+ ["InsertVector128.Double.1.Load"] = InsertVector128Double1Load,
["Floor.Double"] = FloorDouble,
["Floor.Single"] = FloorSingle,
["GetLowerHalf.Byte"] = GetLowerHalfByte,
("GenericUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Sse2",["Method"] = "ExtendToVector256", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["VectorSize"] = "32", ["NextValueOp1"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "result[i] != ((i < (RetElementCount / 2)) ? firstOp[i] : 0)"}),
("GenericUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Sse2",["Method"] = "ExtendToVector256", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["VectorSize"] = "32", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "result[i] != ((i < (RetElementCount / 2)) ? firstOp[i] : 0)"}),
("GenericUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Sse2",["Method"] = "ExtendToVector256", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["VectorSize"] = "32", ["NextValueOp1"] = "(ulong)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "result[i] != ((i < (RetElementCount / 2)) ? firstOp[i] : 0)"}),
+ ("ExtractStoreTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Byte", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))", ["ValidateFirstResult"] = "result[0] != firstOp[16]", ["ValidateRemainingResults"] = "(result[i] != firstOp[i + 16])"}),
+ ("ExtractStoreTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "SByte", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(sbyte)(random.Next(0, sbyte.MaxValue))", ["ValidateFirstResult"] = "result[0] != firstOp[16]", ["ValidateRemainingResults"] = "(result[i] != firstOp[i + 16])"}),
+ ("ExtractStoreTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int16", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(short)(random.Next(0, short.MaxValue))", ["ValidateFirstResult"] = "result[0] != firstOp[8]", ["ValidateRemainingResults"] = "(result[i] != firstOp[i + 8])"}),
+ ("ExtractStoreTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt16", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["ValidateFirstResult"] = "result[0] != firstOp[8]", ["ValidateRemainingResults"] = "(result[i] != firstOp[i + 8])"}),
+ ("ExtractStoreTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(int)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "result[0] != firstOp[4]", ["ValidateRemainingResults"] = "(result[i] != firstOp[i + 4])"}),
+ ("ExtractStoreTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt32", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "result[0] != firstOp[4]", ["ValidateRemainingResults"] = "(result[i] != firstOp[i + 4])"}),
+ ("ExtractStoreTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(long)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "result[0] != firstOp[2]", ["ValidateRemainingResults"] = "(result[i] != firstOp[i + 2])"}),
+ ("ExtractStoreTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt64", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(ulong)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "result[0] != firstOp[2]", ["ValidateRemainingResults"] = "(result[i] != firstOp[i + 2])"}),
+ ("ExtractStoreTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(float)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(result[0]) != BitConverter.SingleToInt32Bits(firstOp[4])", ["ValidateRemainingResults"] = "(BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(firstOp[i + 4]))"}),
+ ("ExtractStoreTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != BitConverter.DoubleToInt64Bits(firstOp[2])", ["ValidateRemainingResults"] = "(BitConverter.DoubleToInt64Bits(result[i]) != BitConverter.DoubleToInt64Bits(firstOp[i + 2]))"}),
+ ("InsertLoadTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "InsertVector128", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))", ["NextValueOp2"] = "(byte)(random.Next(0, byte.MaxValue))", ["ValidateFirstResult"] = "result[0] != left[0]", ["ValidateRemainingResults"] = "(i > 15 ? result[i] != right[i - 16] : result[i] != left[i])"}),
+ ("InsertLoadTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "InsertVector128", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(sbyte)(random.Next(0, sbyte.MaxValue))", ["NextValueOp2"] = "(sbyte)(random.Next(0,sbyte.MaxValue))", ["ValidateFirstResult"] = "result[0] != left[0]", ["ValidateRemainingResults"] = "(i > 15 ? result[i] != right[i - 16] : result[i] != left[i])"}),
+ ("InsertLoadTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "InsertVector128", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(short)(random.Next(0, short.MaxValue))", ["NextValueOp2"] = "(short)(random.Next(0,short.MaxValue))", ["ValidateFirstResult"] = "result[0] != left[0]", ["ValidateRemainingResults"] = "(i > 7 ? result[i] != right[i - 8] : result[i] != left[i])"}),
+ ("InsertLoadTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "InsertVector128", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["NextValueOp2"] = "(ushort)(random.Next(0,ushort.MaxValue))", ["ValidateFirstResult"] = "result[0] != left[0]", ["ValidateRemainingResults"] = "(i > 7 ? result[i] != right[i - 8] : result[i] != left[i])"}),
+ ("InsertLoadTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "InsertVector128", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(int)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(int)(random.Next(0,int.MaxValue))", ["ValidateFirstResult"] = "result[0] != left[0]", ["ValidateRemainingResults"] = "(i > 3 ? result[i] != right[i - 4] : result[i] != left[i])"}),
+ ("InsertLoadTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "InsertVector128", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(uint)(random.Next(0,int.MaxValue))", ["ValidateFirstResult"] = "result[0] != left[0]", ["ValidateRemainingResults"] = "(i > 3 ? result[i] != right[i - 4] : result[i] != left[i])"}),
+ ("InsertLoadTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "InsertVector128", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(long)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(long)(random.Next(0,int.MaxValue))", ["ValidateFirstResult"] = "result[0] != left[0]", ["ValidateRemainingResults"] = "(i > 1 ? result[i] != right[i - 2] : result[i] != left[i])"}),
+ ("InsertLoadTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "InsertVector128", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(ulong)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(ulong)(random.Next(0,int.MaxValue))", ["ValidateFirstResult"] = "result[0] != left[0]", ["ValidateRemainingResults"] = "(i > 1 ? result[i] != right[i - 2] : result[i] != left[i])"}),
+ ("InsertLoadTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "InsertVector128", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(float)(random.NextDouble())", ["NextValueOp2"] = "(float)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(result[0]) != BitConverter.SingleToInt32Bits(left[0])", ["ValidateRemainingResults"] = "(i > 3 ? BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(right[i - 4]) : BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(left[i]))"}),
+ ("InsertLoadTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "InsertVector128", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != BitConverter.DoubleToInt64Bits(left[0])", ["ValidateRemainingResults"] = "(i > 1 ? BitConverter.DoubleToInt64Bits(result[i]) != BitConverter.DoubleToInt64Bits(right[i - 2]) : BitConverter.DoubleToInt64Bits(result[i]) != BitConverter.DoubleToInt64Bits(left[i]))"}),
("SimpleUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Floor", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["VectorSize"] = "32", ["NextValueOp1"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != BitConverter.DoubleToInt64Bits(Math.Floor(firstOp[0]))", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != BitConverter.DoubleToInt64Bits(Math.Floor(firstOp[i]))"}),
("SimpleUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Floor", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["VectorSize"] = "32", ["NextValueOp1"] = "(float)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(result[0]) != BitConverter.SingleToInt32Bits(MathF.Floor(firstOp[0]))", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(MathF.Floor(firstOp[i]))"}),
("GenericUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "GetLowerHalf", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Byte", ["VectorSize"] = "32", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "result[i] != ((i < (Op1ElementCount / 2)) ? firstOp[i] : 0)"}),