--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+//
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics.X86;
+using System.Runtime.Intrinsics;
+
+namespace IntelHardwareIntrinsicTest
+{
+ class Program
+ {
+ const int Pass = 100;
+ const int Fail = 0;
+
+ static unsafe int Main(string[] args)
+ {
+ int testResult = Pass;
+
+ if (Avx.IsSupported)
+ {
+ using (TestTable<float> floatTable = new TestTable<float>(new float[8] {22, -1, -50, 0, 22, -1, -50, 0 }, new float[8] { 22, -1, -50, 0, 22, -1, -50, 0 }, new float[8]))
+ using (TestTable<double> doubleTable = new TestTable<double>(new double[4] { 1, -5, 100, 0 }, new double[4] { 22, -1, -50, 0 }, new double[4]))
+ {
+
+ var vf1 = Unsafe.Read<Vector256<float>>(floatTable.inArray1Ptr);
+ var vf2 = Unsafe.Read<Vector256<float>>(floatTable.inArray2Ptr);
+ var vf3 = Avx.HorizontalAdd(vf1, vf2);
+ Unsafe.Write(floatTable.outArrayPtr, vf3);
+
+ if (!floatTable.CheckResult((left, right, result) =>
+ (left[0] + left[1] == result[0]) && (right[0] + right[1] == result[2]) &&
+ (left[2] + left[3] == result[1]) && (right[2] + right[3] == result[3]) &&
+ (left[4] + left[5] == result[4]) && (right[4] + right[5] == result[6]) &&
+ (left[6] + left[7] == result[5]) && (right[6] + right[7] == result[7])))
+ {
+ Console.WriteLine("Avx HorizontalAdd failed on float:");
+ foreach (var item in floatTable.outArray)
+ {
+ Console.Write(item + ", ");
+ }
+ Console.WriteLine();
+ testResult = Fail;
+ }
+
+ var vd1 = Unsafe.Read<Vector256<double>>(doubleTable.inArray1Ptr);
+ var vd2 = Unsafe.Read<Vector256<double>>(doubleTable.inArray2Ptr);
+ var vd3 = Avx.HorizontalAdd(vd1, vd2);
+ Unsafe.Write(doubleTable.outArrayPtr, vd3);
+
+ if (!doubleTable.CheckResult((left, right, result) =>
+ (left[0] + left[1] == result[0]) && (right[0] + right[1] == result[1]) &&
+ (left[2] + left[3] == result[2]) && (right[2] + right[3] == result[3])))
+ {
+ Console.WriteLine("Avx HorizontalAdd failed on double:");
+ foreach (var item in doubleTable.outArray)
+ {
+ Console.Write(item + ", ");
+ }
+ Console.WriteLine();
+ testResult = Fail;
+ }
+ }
+ }
+
+
+ return testResult;
+ }
+
+ public unsafe struct TestTable<T> : IDisposable where T : struct
+ {
+ public T[] inArray1;
+ public T[] inArray2;
+ public T[] outArray;
+
+ public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer();
+ public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer();
+ public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer();
+
+ GCHandle inHandle1;
+ GCHandle inHandle2;
+ GCHandle outHandle;
+ public TestTable(T[] a, T[] b, T[] c)
+ {
+ this.inArray1 = a;
+ this.inArray2 = b;
+ this.outArray = c;
+
+ inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned);
+ inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned);
+ outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned);
+ }
+ public bool CheckResult(Func<T[], T[], T[], bool> check)
+ {
+ return check(inArray1, inArray2, outArray);
+ }
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+ }
+
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "></PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType>None</DebugType>
+ <Optimize></Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="HorizontalAdd.cs" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
\ No newline at end of file
--- /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="HorizontalAdd.cs" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
+</Project>
\ No newline at end of file
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+//
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics.X86;
+using System.Runtime.Intrinsics;
+
+namespace IntelHardwareIntrinsicTest
+{
+ class Program
+ {
+ const int Pass = 100;
+ const int Fail = 0;
+
+ static unsafe int Main(string[] args)
+ {
+ int testResult = Pass;
+
+ if (Avx.IsSupported)
+ {
+ using (TestTable<float> floatTable = new TestTable<float>(new float[8] {22, -1, -50, 0, 22, -1, -50, 0 }, new float[8] { 22, -1, -50, 0, 22, -1, -50, 0 }, new float[8]))
+ using (TestTable<double> doubleTable = new TestTable<double>(new double[4] { 1, -5, 100, 0 }, new double[4] { 22, -1, -50, 0 }, new double[4]))
+ {
+
+ var vf1 = Unsafe.Read<Vector256<float>>(floatTable.inArray1Ptr);
+ var vf2 = Unsafe.Read<Vector256<float>>(floatTable.inArray2Ptr);
+ var vf3 = Avx.HorizontalSubtract(vf1, vf2);
+ Unsafe.Write(floatTable.outArrayPtr, vf3);
+
+ if (!floatTable.CheckResult((left, right, result) =>
+ (left[0] - left[1] == result[0]) && (right[0] - right[1] == result[2]) &&
+ (left[2] - left[3] == result[1]) && (right[2] - right[3] == result[3]) &&
+ (left[4] - left[5] == result[4]) && (right[4] - right[5] == result[6]) &&
+ (left[6] - left[7] == result[5]) && (right[6] - right[7] == result[7])))
+ {
+ Console.WriteLine("Avx HorizontalAdd failed on float:");
+ foreach (var item in floatTable.outArray)
+ {
+ Console.Write(item + ", ");
+ }
+ Console.WriteLine();
+ testResult = Fail;
+ }
+
+ var vd1 = Unsafe.Read<Vector256<double>>(doubleTable.inArray1Ptr);
+ var vd2 = Unsafe.Read<Vector256<double>>(doubleTable.inArray2Ptr);
+ var vd3 = Avx.HorizontalSubtract(vd1, vd2);
+ Unsafe.Write(doubleTable.outArrayPtr, vd3);
+
+ if (!doubleTable.CheckResult((left, right, result) =>
+ (left[0] - left[1] == result[0]) && (right[0] - right[1] == result[1]) &&
+ (left[2] - left[3] == result[2]) && (right[2] - right[3] == result[3])))
+ {
+ Console.WriteLine("Avx HorizontalAdd failed on double:");
+ foreach (var item in doubleTable.outArray)
+ {
+ Console.Write(item + ", ");
+ }
+ Console.WriteLine();
+ testResult = Fail;
+ }
+ }
+ }
+
+
+ return testResult;
+ }
+
+ public unsafe struct TestTable<T> : IDisposable where T : struct
+ {
+ public T[] inArray1;
+ public T[] inArray2;
+ public T[] outArray;
+
+ public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer();
+ public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer();
+ public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer();
+
+ GCHandle inHandle1;
+ GCHandle inHandle2;
+ GCHandle outHandle;
+ public TestTable(T[] a, T[] b, T[] c)
+ {
+ this.inArray1 = a;
+ this.inArray2 = b;
+ this.outArray = c;
+
+ inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned);
+ inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned);
+ outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned);
+ }
+ public bool CheckResult(Func<T[], T[], T[], bool> check)
+ {
+ return check(inArray1, inArray2, outArray);
+ }
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+ }
+
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "></PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType>None</DebugType>
+ <Optimize></Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="HorizontalSubtract.cs" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
\ No newline at end of file
--- /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="HorizontalSubtract.cs" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
+</Project>
\ No newline at end of file
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+//
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics.X86;
+using System.Runtime.Intrinsics;
+
+namespace IntelHardwareIntrinsicTest
+{
+ class Program
+ {
+ const int Pass = 100;
+ const int Fail = 0;
+
+ static unsafe int Main(string[] args)
+ {
+ int testResult = Pass;
+
+ if (Avx.IsSupported)
+ {
+ using (TestTable<float> floatTable = new TestTable<float>(new float[8] { 1, -5, 100, 0, 1, -5, 100, 0}, new float[8]))
+ using (TestTable<double> doubleTable = new TestTable<double>(new double[4] { 1, -5, 100, 0 }, new double[4]))
+ {
+
+ var vf1 = Unsafe.Read<Vector256<float>>(floatTable.inArrayPtr);
+ var vf2 = Avx.Sqrt(vf1);
+ Unsafe.Write(floatTable.outArrayPtr, vf2);
+
+ var vd1 = Unsafe.Read<Vector256<double>>(doubleTable.inArrayPtr);
+ var vd2 = Avx.Sqrt(vd1);
+ Unsafe.Write(doubleTable.outArrayPtr, vd2);
+
+ if (!floatTable.CheckResult((x, y) => {
+ var expected = MathF.Sqrt(x);
+ return (expected == y)
+ || (float.IsNaN(expected) && float.IsNaN(y));
+ }))
+ {
+ Console.WriteLine("Avx Sqrt failed on float:");
+ foreach (var item in floatTable.outArray)
+ {
+ Console.Write(item + ", ");
+ }
+ Console.WriteLine();
+ testResult = Fail;
+ }
+
+ if (!doubleTable.CheckResult((x, y) => {
+ var expected = Math.Sqrt(x);
+ return (expected == y)
+ || (double.IsNaN(expected) && double.IsNaN(y));
+ }))
+ {
+ Console.WriteLine("Avx Sqrt failed on double:");
+ foreach (var item in doubleTable.outArray)
+ {
+ Console.Write(item + ", ");
+ }
+ Console.WriteLine();
+ testResult = Fail;
+ }
+ }
+ }
+
+
+ return testResult;
+ }
+
+ public unsafe struct TestTable<T> : IDisposable where T : struct
+ {
+ public T[] inArray;
+ public T[] outArray;
+
+ public void* inArrayPtr => inHandle.AddrOfPinnedObject().ToPointer();
+ public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer();
+
+ GCHandle inHandle;
+ GCHandle outHandle;
+ public TestTable(T[] a, T[] b)
+ {
+ this.inArray = a;
+ this.outArray = b;
+
+ inHandle = GCHandle.Alloc(inArray, GCHandleType.Pinned);
+ outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned);
+ }
+ public bool CheckResult(Func<T, T, bool> check)
+ {
+ for (int i = 0; i < inArray.Length; i++)
+ {
+ if (!check(inArray[i], outArray[i]))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public void Dispose()
+ {
+ inHandle.Free();
+ outHandle.Free();
+ }
+ }
+
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "></PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType>None</DebugType>
+ <Optimize></Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Sqrt.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="Sqrt.cs" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
+</Project>
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+//
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics.X86;
+using System.Runtime.Intrinsics;
+
+namespace IntelHardwareIntrinsicTest
+{
+ class Program
+ {
+ const int Pass = 100;
+ const int Fail = 0;
+
+ static unsafe int Main(string[] args)
+ {
+ int testResult = Pass;
+
+ if (Avx.IsSupported)
+ {
+ using (TestTable<float> floatTable = new TestTable<float>(new float[8] {22, -1, -50, 0, 22, -1, -50, 0 }, new float[8] { 22, -1, -50, 0, 22, -1, -50, 0 }, new float[8]))
+ using (TestTable<double> doubleTable = new TestTable<double>(new double[4] { 1, -5, 100, 0 }, new double[4] { 22, -1, -50, 0 }, new double[4]))
+ {
+
+ var vf1 = Unsafe.Read<Vector256<float>>(floatTable.inArray1Ptr);
+ var vf2 = Unsafe.Read<Vector256<float>>(floatTable.inArray2Ptr);
+ var vf3 = Avx.UnpackHigh(vf1, vf2);
+ Unsafe.Write(floatTable.outArrayPtr, vf3);
+
+ if (!floatTable.CheckResult((left, right, result) =>
+ (left[2] == result[0]) && (right[2] == result[1]) &&
+ (left[3] == result[2]) && (right[3] == result[3]) &&
+ (left[6] == result[4]) && (right[6] == result[5]) &&
+ (left[7] == result[6]) && (right[7] == result[7])))
+ {
+ Console.WriteLine("Avx UnpackHigh failed on float:");
+ foreach (var item in floatTable.outArray)
+ {
+ Console.Write(item + ", ");
+ }
+ Console.WriteLine();
+ testResult = Fail;
+ }
+
+ var vd1 = Unsafe.Read<Vector256<double>>(doubleTable.inArray1Ptr);
+ var vd2 = Unsafe.Read<Vector256<double>>(doubleTable.inArray2Ptr);
+ var vd3 = Avx.UnpackHigh(vd1, vd2);
+ Unsafe.Write(doubleTable.outArrayPtr, vd3);
+
+ if (!doubleTable.CheckResult((left, right, result) =>
+ (left[1] == result[0]) && (right[1] == result[1]) &&
+ (left[3] == result[2]) && (right[3] == result[3])))
+ {
+ Console.WriteLine("Avx UnpackHigh failed on double:");
+ foreach (var item in doubleTable.outArray)
+ {
+ Console.Write(item + ", ");
+ }
+ Console.WriteLine();
+ testResult = Fail;
+ }
+ }
+ }
+
+
+ return testResult;
+ }
+
+ public unsafe struct TestTable<T> : IDisposable where T : struct
+ {
+ public T[] inArray1;
+ public T[] inArray2;
+ public T[] outArray;
+
+ public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer();
+ public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer();
+ public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer();
+
+ GCHandle inHandle1;
+ GCHandle inHandle2;
+ GCHandle outHandle;
+ public TestTable(T[] a, T[] b, T[] c)
+ {
+ this.inArray1 = a;
+ this.inArray2 = b;
+ this.outArray = c;
+
+ inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned);
+ inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned);
+ outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned);
+ }
+ public bool CheckResult(Func<T[], T[], T[], bool> check)
+ {
+ return check(inArray1, inArray2, outArray);
+ }
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+ }
+
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "></PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType>None</DebugType>
+ <Optimize></Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="UnpackHigh.cs" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
\ No newline at end of file
--- /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="UnpackHigh.cs" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
+</Project>
\ No newline at end of file
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+//
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics.X86;
+using System.Runtime.Intrinsics;
+
+namespace IntelHardwareIntrinsicTest
+{
+ class Program
+ {
+ const int Pass = 100;
+ const int Fail = 0;
+
+ static unsafe int Main(string[] args)
+ {
+ int testResult = Pass;
+
+ if (Avx.IsSupported)
+ {
+ using (TestTable<float> floatTable = new TestTable<float>(new float[8] {22, -1, -50, 0, 22, -1, -50, 0 }, new float[8] { 22, -1, -50, 0, 22, -1, -50, 0 }, new float[8]))
+ using (TestTable<double> doubleTable = new TestTable<double>(new double[4] { 1, -5, 100, 0 }, new double[4] { 22, -1, -50, 0 }, new double[4]))
+ {
+
+ var vf1 = Unsafe.Read<Vector256<float>>(floatTable.inArray1Ptr);
+ var vf2 = Unsafe.Read<Vector256<float>>(floatTable.inArray2Ptr);
+ var vf3 = Avx.UnpackLow(vf1, vf2);
+ Unsafe.Write(floatTable.outArrayPtr, vf3);
+
+ if (!floatTable.CheckResult((left, right, result) =>
+ (left[0] == result[0]) && (right[0] == result[1]) &&
+ (left[1] == result[2]) && (right[1] == result[3]) &&
+ (left[4] == result[4]) && (right[4] == result[5]) &&
+ (left[5] == result[6]) && (right[5] == result[7])))
+ {
+ Console.WriteLine("Avx UnpackLow failed on float:");
+ foreach (var item in floatTable.outArray)
+ {
+ Console.Write(item + ", ");
+ }
+ Console.WriteLine();
+ testResult = Fail;
+ }
+
+ var vd1 = Unsafe.Read<Vector256<double>>(doubleTable.inArray1Ptr);
+ var vd2 = Unsafe.Read<Vector256<double>>(doubleTable.inArray2Ptr);
+ var vd3 = Avx.UnpackLow(vd1, vd2);
+ Unsafe.Write(doubleTable.outArrayPtr, vd3);
+
+ if (!doubleTable.CheckResult((left, right, result) =>
+ (left[0] == result[0]) && (right[0] == result[1]) &&
+ (left[2] == result[2]) && (right[2] == result[3])))
+ {
+ Console.WriteLine("Avx UnpackLow failed on double:");
+ foreach (var item in doubleTable.outArray)
+ {
+ Console.Write(item + ", ");
+ }
+ Console.WriteLine();
+ testResult = Fail;
+ }
+ }
+ }
+
+
+ return testResult;
+ }
+
+ public unsafe struct TestTable<T> : IDisposable where T : struct
+ {
+ public T[] inArray1;
+ public T[] inArray2;
+ public T[] outArray;
+
+ public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer();
+ public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer();
+ public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer();
+
+ GCHandle inHandle1;
+ GCHandle inHandle2;
+ GCHandle outHandle;
+ public TestTable(T[] a, T[] b, T[] c)
+ {
+ this.inArray1 = a;
+ this.inArray2 = b;
+ this.outArray = c;
+
+ inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned);
+ inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned);
+ outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned);
+ }
+ public bool CheckResult(Func<T[], T[], T[], bool> check)
+ {
+ return check(inArray1, inArray2, outArray);
+ }
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+ }
+
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "></PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType>None</DebugType>
+ <Optimize></Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="UnpackLow.cs" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
\ No newline at end of file
--- /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="UnpackLow.cs" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
+</Project>
\ No newline at end of file
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+//
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics.X86;
+using System.Runtime.Intrinsics;
+
+namespace IntelHardwareIntrinsicTest
+{
+ class Program
+ {
+ const int Pass = 100;
+ const int Fail = 0;
+
+ static unsafe int Main(string[] args)
+ {
+ int testResult = Pass;
+
+ if (Avx2.IsSupported)
+ {
+ using (TestTable<byte, byte, byte> byteTable = new TestTable<byte, byte, byte>(new byte[32] { 1, 5, 100, 0, 1, 5, 100, 0, 1, 5, 100, 0, 1, 5, 100, 0, 1, 5, 100, 0, 1, 5, 100, 0, 1, 5, 100, 0, 1, 5, 100, 0 }, new byte[32] { 22, 1, 50, 0, 22, 1, 50, 0, 22, 1, 50, 0, 22, 1, 50, 0, 22, 1, 50, 0, 22, 1, 50, 0, 22, 1, 50, 0, 22, 1, 50, 0 }, new byte[32]))
+ using (TestTable<sbyte, sbyte, sbyte> sbyteTable = new TestTable<sbyte, sbyte, sbyte>(new sbyte[32] { 1, -5, 100, 0, 1, -5, 100, 0, 1, -5, 100, 0, 1, -5, 100, 0, 1, -5, 100, 0, 1, -5, 100, 0, 1, -5, 100, 0, 1, -5, 100, 0 }, new sbyte[32] { 22, -1, -50, 0, 22, -1, -50, 0, 22, -1, -50, 0, 22, -1, -50, 0, 22, -1, -50, 0, 22, -1, -50, 0, 22, -1, -50, 0, 22, -1, -50, 0 }, new sbyte[32]))
+ using (TestTable<short, short, short> shortTable = new TestTable<short, short, short>(new short[16] { 1, -5, 100, 0, 1, -5, 100, 0, 1, -5, 100, 0, 1, -5, 100, 0 }, new short[16] { 22, -1, -50, 0, 22, -1, -50, 0, 22, -1, -50, 0, 22, -1, -50, 0}, new short[16]))
+ using (TestTable<ushort, ushort, ushort> ushortTable = new TestTable<ushort, ushort, ushort>(new ushort[16] { 1, 5, 100, 0, 1, 5, 100, 0, 1, 5, 100, 0, 1, 5, 100, 0 }, new ushort[16] { 22, 1, 50, 0, 22, 1, 50, 0, 22, 1, 50, 0, 22, 1, 50, 0 }, new ushort[16]))
+ {
+
+ var vb1 = Unsafe.Read<Vector256<byte>>(byteTable.inArray1Ptr);
+ var vb2 = Unsafe.Read<Vector256<byte>>(byteTable.inArray2Ptr);
+ var vb3 = Avx2.AddSaturate(vb1, vb2);
+ Unsafe.Write(byteTable.outArrayPtr, vb3);
+
+ var vsb1 = Unsafe.Read<Vector256<sbyte>>(sbyteTable.inArray1Ptr);
+ var vsb2 = Unsafe.Read<Vector256<sbyte>>(sbyteTable.inArray2Ptr);
+ var vsb3 = Avx2.AddSaturate(vsb1, vsb2);
+ Unsafe.Write(sbyteTable.outArrayPtr, vsb3);
+
+ var vs1 = Unsafe.Read<Vector256<short>>(shortTable.inArray1Ptr);
+ var vs2 = Unsafe.Read<Vector256<short>>(shortTable.inArray2Ptr);
+ var vs3 = Avx2.AddSaturate(vs1, vs2);
+ Unsafe.Write(shortTable.outArrayPtr, vs3);
+
+ var vus1 = Unsafe.Read<Vector256<ushort>>(ushortTable.inArray1Ptr);
+ var vus2 = Unsafe.Read<Vector256<ushort>>(ushortTable.inArray2Ptr);
+ var vus3 = Avx2.AddSaturate(vus1, vus2);
+ Unsafe.Write(ushortTable.outArrayPtr, vus3);
+
+ for (int i = 0; i < byteTable.outArray.Length; i++)
+ {
+ int value = byteTable.inArray1[i] + byteTable.inArray2[i];
+ value = Math.Max(value, 0);
+ value = Math.Min(value, byte.MaxValue);
+ if ((byte)value != byteTable.outArray[i])
+ {
+ Console.WriteLine("AVX2 AddSaturate failed on byte:");
+ Console.WriteLine();
+
+ testResult = Fail;
+ break;
+ }
+ }
+
+ for (int i = 0; i < sbyteTable.outArray.Length; i++)
+ {
+ int value = sbyteTable.inArray1[i] + sbyteTable.inArray2[i];
+ value = Math.Max(value, sbyte.MinValue);
+ value = Math.Min(value, sbyte.MaxValue);
+ if ((sbyte) value != sbyteTable.outArray[i])
+ {
+ Console.WriteLine("AVX2 AddSaturate failed on sbyte:");
+ Console.WriteLine();
+
+ testResult = Fail;
+ break;
+ }
+ }
+
+
+ for (int i = 0; i < shortTable.outArray.Length; i++)
+ {
+ int value = shortTable.inArray1[i] + shortTable.inArray2[i];
+ value = Math.Max(value, short.MinValue);
+ value = Math.Min(value, short.MaxValue);
+ if ((short) value != shortTable.outArray[i])
+ {
+ Console.WriteLine("AVX2 AddSaturate failed on short:");
+ Console.WriteLine();
+
+ testResult = Fail;
+ break;
+ }
+ }
+
+ for (int i = 0; i < ushortTable.outArray.Length; i++)
+ {
+ int value = ushortTable.inArray1[i] + ushortTable.inArray2[i];
+ value = Math.Max(value, 0);
+ value = Math.Min(value, ushort.MaxValue);
+ if ((ushort)value != ushortTable.outArray[i])
+ {
+ Console.WriteLine("AVX2 AddSaturate failed on ushort:");
+ Console.WriteLine();
+
+ testResult = Fail;
+ break;
+ }
+ }
+ }
+ }
+
+ return testResult;
+ }
+
+ public unsafe struct TestTable<T1, T2, T3> : IDisposable where T1 : struct where T2 : struct where T3 : struct
+ {
+ public T1[] inArray1;
+ public T2[] inArray2;
+ public T3[] outArray;
+
+ public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer();
+ public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer();
+ public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer();
+
+ GCHandle inHandle1;
+ GCHandle inHandle2;
+ GCHandle outHandle;
+ public TestTable(T1[] a, T2[] b, T3[] c)
+ {
+ this.inArray1 = a;
+ this.inArray2 = b;
+ this.outArray = c;
+
+ inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned);
+ inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned);
+ outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned);
+ }
+ public bool CheckResult(Func<T1, T2, T3, bool> check)
+ {
+ for (int i = 0; i < inArray1.Length; i++)
+ {
+ if (!check(inArray1[i], inArray2[i], outArray[i]))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+ }
+
+ }
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "></PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType>None</DebugType>
+ <Optimize></Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="AddSaturate.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="AddSaturate.cs" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
+</Project>
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+//
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics.X86;
+using System.Runtime.Intrinsics;
+
+namespace IntelHardwareIntrinsicTest
+{
+ class Program
+ {
+ const int Pass = 100;
+ const int Fail = 0;
+
+ static unsafe int Main(string[] args)
+ {
+ int testResult = Pass;
+
+ if (Avx2.IsSupported)
+ {
+ using (TestTable<short, short, short> shortTable = new TestTable<short, short, short>(new short[16] { 1, -5, 100, 0, 1, -5, 100, 0, 1, -5, 100, 0, 1, -5, 100, 0 }, new short[16] { 22, -1, -50, 0, 22, -1, -50, 0, 22, -1, -50, 0, 22, -1, -50, 0}, new short[16]))
+ using (TestTable<int, int, int> intTable = new TestTable<int, int, int>(new int[8] { 1, 5, 100, 0, 1, 5, 100, 0 }, new int[8] { 22, 1, 50, 0, 22, 1, 50, 0 }, new int[8]))
+ {
+ var vs1 = Unsafe.Read<Vector256<short>>(shortTable.inArray1Ptr);
+ var vs2 = Unsafe.Read<Vector256<short>>(shortTable.inArray2Ptr);
+ var vs3 = Avx2.HorizontalAdd(vs1, vs2);
+ Unsafe.Write(shortTable.outArrayPtr, vs3);
+
+ var vi1 = Unsafe.Read<Vector256<int>>(intTable.inArray1Ptr);
+ var vi2 = Unsafe.Read<Vector256<int>>(intTable.inArray2Ptr);
+ var vi3 = Avx2.HorizontalAdd(vi1, vi2);
+ Unsafe.Write(intTable.outArrayPtr, vi3);
+
+ if ((shortTable.inArray1[1] + shortTable.inArray1[0] != shortTable.outArray[0]) ||
+ (shortTable.inArray1[3] + shortTable.inArray1[2] != shortTable.outArray[1]) ||
+ (shortTable.inArray1[5] + shortTable.inArray1[4] != shortTable.outArray[2]) ||
+ (shortTable.inArray1[7] + shortTable.inArray1[6] != shortTable.outArray[3]) ||
+ (shortTable.inArray2[1] + shortTable.inArray2[0] != shortTable.outArray[4]) ||
+ (shortTable.inArray2[3] + shortTable.inArray2[2] != shortTable.outArray[5]) ||
+ (shortTable.inArray2[5] + shortTable.inArray2[4] != shortTable.outArray[6]) ||
+ (shortTable.inArray2[7] + shortTable.inArray2[6] != shortTable.outArray[7]) ||
+ (shortTable.inArray1[9] + shortTable.inArray1[8] != shortTable.outArray[8]) ||
+ (shortTable.inArray1[11] + shortTable.inArray1[10] !=shortTable.outArray[9]) ||
+ (shortTable.inArray1[13] + shortTable.inArray1[12] !=shortTable.outArray[10]) ||
+ (shortTable.inArray1[15] + shortTable.inArray1[14] !=shortTable.outArray[11]) ||
+ (shortTable.inArray2[9] + shortTable.inArray2[8] !=shortTable.outArray[12]) ||
+ (shortTable.inArray2[11] + shortTable.inArray2[10] !=shortTable.outArray[13]) ||
+ (shortTable.inArray2[13] + shortTable.inArray2[12] !=shortTable.outArray[14]) ||
+ (shortTable.inArray2[15] + shortTable.inArray2[14] !=shortTable.outArray[15]))
+ {
+ Console.WriteLine("AVX2 HorizontalAdd failed on short:");
+
+ testResult = Fail;
+
+ }
+
+ if ((intTable.inArray1[1] + intTable.inArray1[0] != intTable.outArray[0]) ||
+ (intTable.inArray1[3] + intTable.inArray1[2] != intTable.outArray[1]) ||
+ (intTable.inArray2[1] + intTable.inArray2[0] != intTable.outArray[2]) ||
+ (intTable.inArray2[3] + intTable.inArray2[2] != intTable.outArray[3]) ||
+ (intTable.inArray1[5] + intTable.inArray1[4] != intTable.outArray[4]) ||
+ (intTable.inArray1[7] + intTable.inArray1[6] != intTable.outArray[5]) ||
+ (intTable.inArray2[5] + intTable.inArray2[4] != intTable.outArray[6]) ||
+ (intTable.inArray2[7] + intTable.inArray2[6] != intTable.outArray[7]))
+
+ {
+ Console.WriteLine("AVX2 HorizontalAdd failed on int:");
+
+ testResult = Fail;
+
+ }
+
+
+ }
+ }
+
+ return testResult;
+ }
+
+ public unsafe struct TestTable<T1, T2, T3> : IDisposable where T1 : struct where T2 : struct where T3 : struct
+ {
+ public T1[] inArray1;
+ public T2[] inArray2;
+ public T3[] outArray;
+
+ public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer();
+ public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer();
+ public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer();
+
+ GCHandle inHandle1;
+ GCHandle inHandle2;
+ GCHandle outHandle;
+ public TestTable(T1[] a, T2[] b, T3[] c)
+ {
+ this.inArray1 = a;
+ this.inArray2 = b;
+ this.outArray = c;
+
+ inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned);
+ inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned);
+ outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned);
+ }
+ public bool CheckResult(Func<T1, T2, T3, bool> check)
+ {
+ for (int i = 0; i < inArray1.Length; i++)
+ {
+ if (!check(inArray1[i], inArray2[i], outArray[i]))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+ }
+
+ }
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "></PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType>None</DebugType>
+ <Optimize></Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="HorizontalAdd.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="HorizontalAdd.cs" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
+</Project>
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+//
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics.X86;
+using System.Runtime.Intrinsics;
+
+namespace IntelHardwareIntrinsicTest
+{
+ class Program
+ {
+ const int Pass = 100;
+ const int Fail = 0;
+
+ static unsafe int Main(string[] args)
+ {
+ int testResult = Pass;
+
+ if (Avx2.IsSupported)
+ {
+ using (TestTable<short, short, short> shortTable = new TestTable<short, short, short>(new short[16] { 1, -5, 100, 0, 1, -5, 100, 0, 1, -5, 100, 0, 1, -5, 100, 0 }, new short[16] { 22, -1, -50, 0, 22, -1, -50, 0, 22, -1, -50, 0, 22, -1, -50, 0}, new short[16]))
+ using (TestTable<int, int, int> intTable = new TestTable<int, int, int>(new int[8] { 1, 5, 100, 0, 1, 5, 100, 0 }, new int[8] { 22, 1, 50, 0, 22, 1, 50, 0 }, new int[8]))
+ {
+ var vs1 = Unsafe.Read<Vector256<short>>(shortTable.inArray1Ptr);
+ var vs2 = Unsafe.Read<Vector256<short>>(shortTable.inArray2Ptr);
+ var vs3 = Avx2.HorizontalSubtract(vs1, vs2);
+ Unsafe.Write(shortTable.outArrayPtr, vs3);
+
+ var vi1 = Unsafe.Read<Vector256<int>>(intTable.inArray1Ptr);
+ var vi2 = Unsafe.Read<Vector256<int>>(intTable.inArray2Ptr);
+ var vi3 = Avx2.HorizontalSubtract(vi1, vi2);
+ Unsafe.Write(intTable.outArrayPtr, vi3);
+
+ if ((shortTable.inArray1[0] - shortTable.inArray1[1] != shortTable.outArray[0]) ||
+ (shortTable.inArray1[2] - shortTable.inArray1[3] != shortTable.outArray[1]) ||
+ (shortTable.inArray1[4] - shortTable.inArray1[5] != shortTable.outArray[2]) ||
+ (shortTable.inArray1[6] - shortTable.inArray1[7] != shortTable.outArray[3]) ||
+ (shortTable.inArray2[0] - shortTable.inArray2[1] != shortTable.outArray[4]) ||
+ (shortTable.inArray2[2] - shortTable.inArray2[3] != shortTable.outArray[5]) ||
+ (shortTable.inArray2[4] - shortTable.inArray2[5] != shortTable.outArray[6]) ||
+ (shortTable.inArray2[6] - shortTable.inArray2[7] != shortTable.outArray[7]) ||
+ (shortTable.inArray1[8] - shortTable.inArray1[9] != shortTable.outArray[8]) ||
+ (shortTable.inArray1[10] - shortTable.inArray1[11] !=shortTable.outArray[9]) ||
+ (shortTable.inArray1[12] - shortTable.inArray1[13] !=shortTable.outArray[10]) ||
+ (shortTable.inArray1[14] - shortTable.inArray1[15] !=shortTable.outArray[11]) ||
+ (shortTable.inArray2[8] - shortTable.inArray2[9] !=shortTable.outArray[12]) ||
+ (shortTable.inArray2[10] - shortTable.inArray2[11] !=shortTable.outArray[13]) ||
+ (shortTable.inArray2[12] - shortTable.inArray2[13] !=shortTable.outArray[14]) ||
+ (shortTable.inArray2[14] - shortTable.inArray2[15] !=shortTable.outArray[15]))
+ {
+ Console.WriteLine("AVX2 HorizontalSubtract failed on short:");
+
+ testResult = Fail;
+
+ }
+
+ if ((intTable.inArray1[0] - intTable.inArray1[1] != intTable.outArray[0]) ||
+ (intTable.inArray1[2] - intTable.inArray1[3] != intTable.outArray[1]) ||
+ (intTable.inArray2[0] - intTable.inArray2[1] != intTable.outArray[2]) ||
+ (intTable.inArray2[2] - intTable.inArray2[3] != intTable.outArray[3]) ||
+ (intTable.inArray1[4] - intTable.inArray1[5] != intTable.outArray[4]) ||
+ (intTable.inArray1[6] - intTable.inArray1[7] != intTable.outArray[5]) ||
+ (intTable.inArray2[4] - intTable.inArray2[5] != intTable.outArray[6]) ||
+ (intTable.inArray2[6] - intTable.inArray2[7] != intTable.outArray[7]))
+
+ {
+ Console.WriteLine("AVX2 HorizontalSubtract failed on int:");
+
+ testResult = Fail;
+
+ }
+
+
+ }
+ }
+
+ return testResult;
+ }
+
+ public unsafe struct TestTable<T1, T2, T3> : IDisposable where T1 : struct where T2 : struct where T3 : struct
+ {
+ public T1[] inArray1;
+ public T2[] inArray2;
+ public T3[] outArray;
+
+ public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer();
+ public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer();
+ public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer();
+
+ GCHandle inHandle1;
+ GCHandle inHandle2;
+ GCHandle outHandle;
+ public TestTable(T1[] a, T2[] b, T3[] c)
+ {
+ this.inArray1 = a;
+ this.inArray2 = b;
+ this.outArray = c;
+
+ inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned);
+ inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned);
+ outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned);
+ }
+ public bool CheckResult(Func<T1, T2, T3, bool> check)
+ {
+ for (int i = 0; i < inArray1.Length; i++)
+ {
+ if (!check(inArray1[i], inArray2[i], outArray[i]))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+ }
+
+ }
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "></PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType>None</DebugType>
+ <Optimize></Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="HorizontalSubtract.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="HorizontalSubtract.cs" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
+</Project>
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+//
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics.X86;
+using System.Runtime.Intrinsics;
+
+namespace IntelHardwareIntrinsicTest
+{
+ class Program
+ {
+ const int Pass = 100;
+ const int Fail = 0;
+
+ static unsafe int Main(string[] args)
+ {
+ int testResult = Pass;
+
+ if (Avx2.IsSupported)
+ {
+ using (TestTable<byte, byte, byte> byteTable = new TestTable<byte, byte, byte>(new byte[32] { 1, 5, 100, 0, 1, 5, 100, 0, 1, 5, 100, 0, 1, 5, 100, 0, 1, 5, 100, 0, 1, 5, 100, 0, 1, 5, 100, 0, 1, 5, 100, 0 }, new byte[32] { 22, 1, 50, 0, 22, 1, 50, 0, 22, 1, 50, 0, 22, 1, 50, 0, 22, 1, 50, 0, 22, 1, 50, 0, 22, 1, 50, 0, 22, 1, 50, 0 }, new byte[32]))
+ using (TestTable<sbyte, sbyte, sbyte> sbyteTable = new TestTable<sbyte, sbyte, sbyte>(new sbyte[32] { 1, -5, 100, 0, 1, -5, 100, 0, 1, -5, 100, 0, 1, -5, 100, 0, 1, -5, 100, 0, 1, -5, 100, 0, 1, -5, 100, 0, 1, -5, 100, 0 }, new sbyte[32] { 22, -1, -50, 0, 22, -1, -50, 0, 22, -1, -50, 0, 22, -1, -50, 0, 22, -1, -50, 0, 22, -1, -50, 0, 22, -1, -50, 0, 22, -1, -50, 0 }, new sbyte[32]))
+ using (TestTable<short, short, short> shortTable = new TestTable<short, short, short>(new short[16] { 1, -5, 100, 0, 1, -5, 100, 0, 1, -5, 100, 0, 1, -5, 100, 0 }, new short[16] { 22, -1, -50, 0, 22, -1, -50, 0, 22, -1, -50, 0, 22, -1, -50, 0}, new short[16]))
+ using (TestTable<ushort, ushort, ushort> ushortTable = new TestTable<ushort, ushort, ushort>(new ushort[16] { 1, 5, 100, 0, 1, 5, 100, 0, 1, 5, 100, 0, 1, 5, 100, 0 }, new ushort[16] { 22, 1, 50, 0, 22, 1, 50, 0, 22, 1, 50, 0, 22, 1, 50, 0 }, new ushort[16]))
+ {
+
+ var vb1 = Unsafe.Read<Vector256<byte>>(byteTable.inArray1Ptr);
+ var vb2 = Unsafe.Read<Vector256<byte>>(byteTable.inArray2Ptr);
+ var vb3 = Avx2.SubtractSaturate(vb1, vb2);
+ Unsafe.Write(byteTable.outArrayPtr, vb3);
+
+ var vsb1 = Unsafe.Read<Vector256<sbyte>>(sbyteTable.inArray1Ptr);
+ var vsb2 = Unsafe.Read<Vector256<sbyte>>(sbyteTable.inArray2Ptr);
+ var vsb3 = Avx2.SubtractSaturate(vsb1, vsb2);
+ Unsafe.Write(sbyteTable.outArrayPtr, vsb3);
+
+ var vs1 = Unsafe.Read<Vector256<short>>(shortTable.inArray1Ptr);
+ var vs2 = Unsafe.Read<Vector256<short>>(shortTable.inArray2Ptr);
+ var vs3 = Avx2.SubtractSaturate(vs1, vs2);
+ Unsafe.Write(shortTable.outArrayPtr, vs3);
+
+ var vus1 = Unsafe.Read<Vector256<ushort>>(ushortTable.inArray1Ptr);
+ var vus2 = Unsafe.Read<Vector256<ushort>>(ushortTable.inArray2Ptr);
+ var vus3 = Avx2.SubtractSaturate(vus1, vus2);
+ Unsafe.Write(ushortTable.outArrayPtr, vus3);
+
+ for (int i = 0; i < byteTable.outArray.Length; i++)
+ {
+ int value = byteTable.inArray1[i] - byteTable.inArray2[i];
+ value = Math.Max(value, 0);
+ value = Math.Min(value, byte.MaxValue);
+ if ((byte)value != byteTable.outArray[i])
+ {
+ Console.WriteLine("AVX2 SubtractSaturate failed on byte:");
+ Console.WriteLine();
+
+ testResult = Fail;
+ break;
+ }
+ }
+
+ for (int i = 0; i < sbyteTable.outArray.Length; i++)
+ {
+ int value = sbyteTable.inArray1[i] - sbyteTable.inArray2[i];
+ value = Math.Max(value, sbyte.MinValue);
+ value = Math.Min(value, sbyte.MaxValue);
+ if ((sbyte)value != sbyteTable.outArray[i])
+ {
+ Console.WriteLine("AVX2 SubtractSaturate failed on sbyte:");
+ Console.WriteLine();
+
+ testResult = Fail;
+ break;
+ }
+ }
+
+
+ for (int i = 0; i < shortTable.outArray.Length; i++)
+ {
+ int value = shortTable.inArray1[i] - shortTable.inArray2[i];
+ value = Math.Max(value, short.MinValue);
+ value = Math.Min(value, short.MaxValue);
+ if ((short)value != shortTable.outArray[i])
+ {
+ Console.WriteLine("AVX2 SubtractSaturate failed on short:");
+ Console.WriteLine();
+
+ testResult = Fail;
+ break;
+ }
+ }
+
+ for (int i = 0; i < ushortTable.outArray.Length; i++)
+ {
+ int value = ushortTable.inArray1[i] - ushortTable.inArray2[i];
+ value = Math.Max(value, 0);
+ value = Math.Min(value, ushort.MaxValue);
+ if ((ushort)value != ushortTable.outArray[i])
+ {
+ Console.WriteLine("AVX2 SubtractSaturate failed on ushort:");
+ Console.WriteLine();
+
+ testResult = Fail;
+ break;
+ }
+ }
+ }
+ }
+
+ return testResult;
+ }
+
+ public unsafe struct TestTable<T1, T2, T3> : IDisposable where T1 : struct where T2 : struct where T3 : struct
+ {
+ public T1[] inArray1;
+ public T2[] inArray2;
+ public T3[] outArray;
+
+ public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer();
+ public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer();
+ public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer();
+
+ GCHandle inHandle1;
+ GCHandle inHandle2;
+ GCHandle outHandle;
+ public TestTable(T1[] a, T2[] b, T3[] c)
+ {
+ this.inArray1 = a;
+ this.inArray2 = b;
+ this.outArray = c;
+
+ inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned);
+ inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned);
+ outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned);
+ }
+ public bool CheckResult(Func<T1, T2, T3, bool> check)
+ {
+ for (int i = 0; i < inArray1.Length; i++)
+ {
+ if (!check(inArray1[i], inArray2[i], outArray[i]))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+ }
+
+ }
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "></PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType>None</DebugType>
+ <Optimize></Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="SubtractSaturate.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="SubtractSaturate.cs" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
+</Project>
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+//
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics.X86;
+using System.Runtime.Intrinsics;
+
+namespace IntelHardwareIntrinsicTest
+{
+ class Program
+ {
+ const int Pass = 100;
+ const int Fail = 0;
+
+ static unsafe int Main(string[] args)
+ {
+ int testResult = Pass;
+
+ if (Avx2.IsSupported)
+ {
+ using (TestTable<byte, byte, byte> byteTable = new TestTable<byte, byte, byte>(new byte[32] { 1, 5, 100, 0, 1, 5, 100, 0, 1, 5, 100, 0, 1, 5, 100, 0, 1, 5, 100, 0, 1, 5, 100, 0, 1, 5, 100, 0, 1, 5, 100, 0 }, new byte[32] { 22, 1, 50, 0, 22, 1, 50, 0, 22, 1, 50, 0, 22, 1, 50, 0, 22, 1, 50, 0, 22, 1, 50, 0, 22, 1, 50, 0, 22, 1, 50, 0 }, new byte[32]))
+ using (TestTable<sbyte, sbyte, sbyte> sbyteTable = new TestTable<sbyte, sbyte, sbyte>(new sbyte[32] { 1, -5, 100, 0, 1, -5, 100, 0, 1, -5, 100, 0, 1, -5, 100, 0, 1, -5, 100, 0, 1, -5, 100, 0, 1, -5, 100, 0, 1, -5, 100, 0 }, new sbyte[32] { 22, -1, -50, 0, 22, -1, -50, 0, 22, -1, -50, 0, 22, -1, -50, 0, 22, -1, -50, 0, 22, -1, -50, 0, 22, -1, -50, 0, 22, -1, -50, 0 }, new sbyte[32]))
+ using (TestTable<short, short, short> shortTable = new TestTable<short, short, short>(new short[16] { 1, -5, 100, 0, 1, -5, 100, 0, 1, -5, 100, 0, 1, -5, 100, 0 }, new short[16] { 22, -1, -50, 0, 22, -1, -50, 0, 22, -1, -50, 0, 22, -1, -50, 0}, new short[16]))
+ using (TestTable<ushort, ushort, ushort> ushortTable = new TestTable<ushort, ushort, ushort>(new ushort[16] { 1, 5, 100, 0, 1, 5, 100, 0, 1, 5, 100, 0, 1, 5, 100, 0 }, new ushort[16] { 22, 1, 50, 0, 22, 1, 50, 0, 22, 1, 50, 0, 22, 1, 50, 0 }, new ushort[16]))
+ using (TestTable<int, int, int> intTable = new TestTable<int, int, int>(new int[8] { 1, 5, 100, 0, 1, 5, 100, 0}, new int[8] { 22, 1, 50, 0, 22, 1, 50, 0 }, new int[8]))
+ using (TestTable<uint, uint, uint> uintTable = new TestTable<uint, uint, uint>(new uint[8] { 1, 5, 100, 0, 1, 5, 100, 0 }, new uint[8] { 22, 1, 50, 0, 22, 1, 50, 0 }, new uint[8]))
+ using (TestTable<long, long, long> longTable = new TestTable<long, long, long>(new long[4] { 1, -5, 100, 0 }, new long[4] { 22, -1, -50, 0}, new long[4]))
+ using (TestTable<ulong, ulong, ulong> ulongTable = new TestTable<ulong, ulong, ulong>(new ulong[4] { 1, 5, 100, 0 }, new ulong[4] { 22, 1, 50, 0 }, new ulong[4]))
+
+ {
+
+ var vb1 = Unsafe.Read<Vector256<byte>>(byteTable.inArray1Ptr);
+ var vb2 = Unsafe.Read<Vector256<byte>>(byteTable.inArray2Ptr);
+ var vb3 = Avx2.UnpackHigh(vb1, vb2);
+ Unsafe.Write(byteTable.outArrayPtr, vb3);
+
+ var vsb1 = Unsafe.Read<Vector256<sbyte>>(sbyteTable.inArray1Ptr);
+ var vsb2 = Unsafe.Read<Vector256<sbyte>>(sbyteTable.inArray2Ptr);
+ var vsb3 = Avx2.UnpackHigh(vsb1, vsb2);
+ Unsafe.Write(sbyteTable.outArrayPtr, vsb3);
+
+ var vs1 = Unsafe.Read<Vector256<short>>(shortTable.inArray1Ptr);
+ var vs2 = Unsafe.Read<Vector256<short>>(shortTable.inArray2Ptr);
+ var vs3 = Avx2.UnpackHigh(vs1, vs2);
+ Unsafe.Write(shortTable.outArrayPtr, vs3);
+
+ var vus1 = Unsafe.Read<Vector256<ushort>>(ushortTable.inArray1Ptr);
+ var vus2 = Unsafe.Read<Vector256<ushort>>(ushortTable.inArray2Ptr);
+ var vus3 = Avx2.UnpackHigh(vus1, vus2);
+ Unsafe.Write(ushortTable.outArrayPtr, vus3);
+
+ var vi1 = Unsafe.Read<Vector256<int>>(intTable.inArray1Ptr);
+ var vi2 = Unsafe.Read<Vector256<int>>(intTable.inArray2Ptr);
+ var vi3 = Avx2.UnpackHigh(vi1, vi2);
+ Unsafe.Write(intTable.outArrayPtr, vi3);
+
+ var vui1 = Unsafe.Read<Vector256<uint>>(uintTable.inArray1Ptr);
+ var vui2 = Unsafe.Read<Vector256<uint>>(uintTable.inArray2Ptr);
+ var vui3 = Avx2.UnpackHigh(vui1, vui2);
+ Unsafe.Write(uintTable.outArrayPtr, vui3);
+
+ var vl1 = Unsafe.Read<Vector256<long>>(longTable.inArray1Ptr);
+ var vl2 = Unsafe.Read<Vector256<long>>(longTable.inArray2Ptr);
+ var vl3 = Avx2.UnpackHigh(vl1, vl2);
+ Unsafe.Write(longTable.outArrayPtr, vl3);
+
+ var vul1 = Unsafe.Read<Vector256<ulong>>(ulongTable.inArray1Ptr);
+ var vul2 = Unsafe.Read<Vector256<ulong>>(ulongTable.inArray2Ptr);
+ var vul3 = Avx2.UnpackHigh(vul1, vul2);
+ Unsafe.Write(ulongTable.outArrayPtr, vul3);
+
+ if((byteTable.inArray1[8] != byteTable.outArray[0]) || (byteTable.inArray2[8] != byteTable.outArray[1]) ||
+ (byteTable.inArray1[9] != byteTable.outArray[2]) || (byteTable.inArray2[9] != byteTable.outArray[3]) ||
+ (byteTable.inArray1[10] != byteTable.outArray[4]) || (byteTable.inArray2[10] != byteTable.outArray[5]) ||
+ (byteTable.inArray1[11] != byteTable.outArray[6]) || (byteTable.inArray2[11] != byteTable.outArray[7]) ||
+ (byteTable.inArray1[12] != byteTable.outArray[8]) || (byteTable.inArray2[12] != byteTable.outArray[9]) ||
+ (byteTable.inArray1[13] != byteTable.outArray[10]) || (byteTable.inArray2[13] != byteTable.outArray[11]) ||
+ (byteTable.inArray1[14] != byteTable.outArray[12]) || (byteTable.inArray2[14] != byteTable.outArray[13]) ||
+ (byteTable.inArray1[15] != byteTable.outArray[14]) || (byteTable.inArray2[15] != byteTable.outArray[15]) ||
+ (byteTable.inArray1[24] != byteTable.outArray[16]) || (byteTable.inArray2[24] != byteTable.outArray[17]) ||
+ (byteTable.inArray1[25] != byteTable.outArray[18]) || (byteTable.inArray2[25] != byteTable.outArray[19]) ||
+ (byteTable.inArray1[26] != byteTable.outArray[20]) || (byteTable.inArray2[26] != byteTable.outArray[21]) ||
+ (byteTable.inArray1[27] != byteTable.outArray[22]) || (byteTable.inArray2[27] != byteTable.outArray[23]) ||
+ (byteTable.inArray1[28] != byteTable.outArray[24]) || (byteTable.inArray2[28] != byteTable.outArray[25]) ||
+ (byteTable.inArray1[29] != byteTable.outArray[26]) || (byteTable.inArray2[29] != byteTable.outArray[27]) ||
+ (byteTable.inArray1[30] != byteTable.outArray[28]) || (byteTable.inArray2[30] != byteTable.outArray[29]) ||
+ (byteTable.inArray1[31] != byteTable.outArray[30]) || (byteTable.inArray2[31] != byteTable.outArray[31]))
+ {
+ Console.WriteLine("AVX2 UnpackHigh failed on byte:");
+ Console.WriteLine($" left: ({string.Join(", ", byteTable.inArray1)})");
+ Console.WriteLine($" right: ({string.Join(", ", byteTable.inArray2)})");
+ Console.WriteLine($" result: ({string.Join(", ", byteTable.outArray)})");
+ Console.WriteLine();
+
+ testResult = Fail;
+ }
+
+ if((sbyteTable.inArray1[8] != sbyteTable.outArray[0]) || (sbyteTable.inArray2[8] != sbyteTable.outArray[1]) ||
+ (sbyteTable.inArray1[9] != sbyteTable.outArray[2]) || (sbyteTable.inArray2[9] != sbyteTable.outArray[3]) ||
+ (sbyteTable.inArray1[10] != sbyteTable.outArray[4]) || (sbyteTable.inArray2[10] != sbyteTable.outArray[5]) ||
+ (sbyteTable.inArray1[11] != sbyteTable.outArray[6]) || (sbyteTable.inArray2[11] != sbyteTable.outArray[7]) ||
+ (sbyteTable.inArray1[12] != sbyteTable.outArray[8]) || (sbyteTable.inArray2[12] != sbyteTable.outArray[9]) ||
+ (sbyteTable.inArray1[13] != sbyteTable.outArray[10]) || (sbyteTable.inArray2[13] != sbyteTable.outArray[11]) ||
+ (sbyteTable.inArray1[14] != sbyteTable.outArray[12]) || (sbyteTable.inArray2[14] != sbyteTable.outArray[13]) ||
+ (sbyteTable.inArray1[15] != sbyteTable.outArray[14]) || (sbyteTable.inArray2[15] != sbyteTable.outArray[15]) ||
+ (sbyteTable.inArray1[24] != sbyteTable.outArray[16]) || (sbyteTable.inArray2[24] != sbyteTable.outArray[17]) ||
+ (sbyteTable.inArray1[25] != sbyteTable.outArray[18]) || (sbyteTable.inArray2[25] != sbyteTable.outArray[19]) ||
+ (sbyteTable.inArray1[26] != sbyteTable.outArray[20]) || (sbyteTable.inArray2[26] != sbyteTable.outArray[21]) ||
+ (sbyteTable.inArray1[27] != sbyteTable.outArray[22]) || (sbyteTable.inArray2[27] != sbyteTable.outArray[23]) ||
+ (sbyteTable.inArray1[28] != sbyteTable.outArray[24]) || (sbyteTable.inArray2[28] != sbyteTable.outArray[25]) ||
+ (sbyteTable.inArray1[29] != sbyteTable.outArray[26]) || (sbyteTable.inArray2[29] != sbyteTable.outArray[27]) ||
+ (sbyteTable.inArray1[30] != sbyteTable.outArray[28]) || (sbyteTable.inArray2[30] != sbyteTable.outArray[29]) ||
+ (sbyteTable.inArray1[31] != sbyteTable.outArray[30]) || (sbyteTable.inArray2[31] != sbyteTable.outArray[31]))
+ {
+ Console.WriteLine("AVX2 UnpackHigh failed on sbyte:");
+ Console.WriteLine($" left: ({string.Join(", ", byteTable.inArray1)})");
+ Console.WriteLine($" right: ({string.Join(", ", byteTable.inArray2)})");
+ Console.WriteLine($" result: ({string.Join(", ", byteTable.outArray)})");
+ Console.WriteLine();
+
+ testResult = Fail;
+ }
+
+ if((shortTable.inArray1[4] != shortTable.outArray[0]) || (shortTable.inArray2[4] != shortTable.outArray[1]) ||
+ (shortTable.inArray1[5] != shortTable.outArray[2]) || (shortTable.inArray2[5] != shortTable.outArray[3]) ||
+ (shortTable.inArray1[6] != shortTable.outArray[4]) || (shortTable.inArray2[6] != shortTable.outArray[5]) ||
+ (shortTable.inArray1[7] != shortTable.outArray[6]) || (shortTable.inArray2[7] != shortTable.outArray[7]) ||
+ (shortTable.inArray1[12] != shortTable.outArray[8]) || (shortTable.inArray2[12] != shortTable.outArray[9]) ||
+ (shortTable.inArray1[13] != shortTable.outArray[10]) || (shortTable.inArray2[13] != shortTable.outArray[11]) ||
+ (shortTable.inArray1[14] != shortTable.outArray[12]) || (shortTable.inArray2[14] != shortTable.outArray[13]) ||
+ (shortTable.inArray1[15] != shortTable.outArray[14]) || (shortTable.inArray2[15] != shortTable.outArray[15]))
+
+ {
+ Console.WriteLine("AVX2 UnpackHigh failed on short:");
+ Console.WriteLine($" left: ({string.Join(", ", byteTable.inArray1)})");
+ Console.WriteLine($" right: ({string.Join(", ", byteTable.inArray2)})");
+ Console.WriteLine($" result: ({string.Join(", ", byteTable.outArray)})");
+ Console.WriteLine();
+
+ testResult = Fail;
+ }
+
+ if((ushortTable.inArray1[4] != ushortTable.outArray[0]) || (ushortTable.inArray2[4] != ushortTable.outArray[1]) ||
+ (ushortTable.inArray1[5] != ushortTable.outArray[2]) || (ushortTable.inArray2[5] != ushortTable.outArray[3]) ||
+ (ushortTable.inArray1[6] != ushortTable.outArray[4]) || (ushortTable.inArray2[6] != ushortTable.outArray[5]) ||
+ (ushortTable.inArray1[7] != ushortTable.outArray[6]) || (ushortTable.inArray2[7] != ushortTable.outArray[7]) ||
+ (ushortTable.inArray1[12] != ushortTable.outArray[8]) || (ushortTable.inArray2[12] != ushortTable.outArray[9]) ||
+ (ushortTable.inArray1[13] != ushortTable.outArray[10]) || (ushortTable.inArray2[13] != ushortTable.outArray[11]) ||
+ (ushortTable.inArray1[14] != ushortTable.outArray[12]) || (ushortTable.inArray2[14] != ushortTable.outArray[13]) ||
+ (ushortTable.inArray1[15] != ushortTable.outArray[14]) || (ushortTable.inArray2[15] != ushortTable.outArray[15]))
+ {
+ Console.WriteLine("AVX2 UnpackHigh failed on ushort:");
+ Console.WriteLine($" left: ({string.Join(", ", byteTable.inArray1)})");
+ Console.WriteLine($" right: ({string.Join(", ", byteTable.inArray2)})");
+ Console.WriteLine($" result: ({string.Join(", ", byteTable.outArray)})");
+ Console.WriteLine();
+
+ testResult = Fail;
+ }
+
+ if ((intTable.inArray1[2] != intTable.outArray[0]) || (intTable.inArray2[2] != intTable.outArray[1]) ||
+ (intTable.inArray1[3] != intTable.outArray[2]) || (intTable.inArray2[3] != intTable.outArray[3]) ||
+ (intTable.inArray1[6] != intTable.outArray[4]) || (intTable.inArray2[6] != intTable.outArray[5]) ||
+ (intTable.inArray1[7] != intTable.outArray[6]) || (intTable.inArray2[7] != intTable.outArray[7]))
+ {
+ Console.WriteLine("AVX2 UnpackHigh failed on int:");
+ Console.WriteLine($" left: ({string.Join(", ", byteTable.inArray1)})");
+ Console.WriteLine($" right: ({string.Join(", ", byteTable.inArray2)})");
+ Console.WriteLine($" result: ({string.Join(", ", byteTable.outArray)})");
+ Console.WriteLine();
+
+ testResult = Fail;
+ }
+
+ if ((uintTable.inArray1[2] != uintTable.outArray[0]) || (uintTable.inArray2[2] != uintTable.outArray[1]) ||
+ (uintTable.inArray1[3] != uintTable.outArray[2]) || (uintTable.inArray2[3] != uintTable.outArray[3]) ||
+ (uintTable.inArray1[6] != uintTable.outArray[4]) || (uintTable.inArray2[6] != uintTable.outArray[5]) ||
+ (uintTable.inArray1[7] != uintTable.outArray[6]) || (uintTable.inArray2[7] != uintTable.outArray[7]))
+ {
+ Console.WriteLine("AVX2 UnpackHigh failed on uint:");
+ Console.WriteLine($" left: ({string.Join(", ", byteTable.inArray1)})");
+ Console.WriteLine($" right: ({string.Join(", ", byteTable.inArray2)})");
+ Console.WriteLine($" result: ({string.Join(", ", byteTable.outArray)})");
+ Console.WriteLine();
+
+ testResult = Fail;
+ }
+
+ if ((longTable.inArray1[1] != longTable.outArray[0]) || (longTable.inArray2[1] != longTable.outArray[1]) ||
+ (longTable.inArray1[3] != longTable.outArray[2]) || (longTable.inArray2[3] != longTable.outArray[3]) )
+ {
+ Console.WriteLine("AVX2 UnpackHigh failed on long:");
+ Console.WriteLine($" left: ({string.Join(", ", byteTable.inArray1)})");
+ Console.WriteLine($" right: ({string.Join(", ", byteTable.inArray2)})");
+ Console.WriteLine($" result: ({string.Join(", ", byteTable.outArray)})");
+ Console.WriteLine();
+
+ testResult = Fail;
+ }
+
+ if ((ulongTable.inArray1[1] != ulongTable.outArray[0]) || (ulongTable.inArray2[1] != ulongTable.outArray[1]) ||
+ (ulongTable.inArray1[3] != ulongTable.outArray[2]) || (ulongTable.inArray2[3] != ulongTable.outArray[3]) )
+ {
+ Console.WriteLine("AVX2 UnpackHigh failed on ulong:");
+ Console.WriteLine($" left: ({string.Join(", ", byteTable.inArray1)})");
+ Console.WriteLine($" right: ({string.Join(", ", byteTable.inArray2)})");
+ Console.WriteLine($" result: ({string.Join(", ", byteTable.outArray)})");
+ Console.WriteLine();
+
+ testResult = Fail;
+ }
+ }
+ }
+
+ return testResult;
+ }
+
+ public unsafe struct TestTable<T1, T2, T3> : IDisposable where T1 : struct where T2 : struct where T3 : struct
+ {
+ public T1[] inArray1;
+ public T2[] inArray2;
+ public T3[] outArray;
+
+ public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer();
+ public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer();
+ public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer();
+
+ GCHandle inHandle1;
+ GCHandle inHandle2;
+ GCHandle outHandle;
+ public TestTable(T1[] a, T2[] b, T3[] c)
+ {
+ this.inArray1 = a;
+ this.inArray2 = b;
+ this.outArray = c;
+
+ inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned);
+ inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned);
+ outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned);
+ }
+ public bool CheckResult(Func<T1, T2, T3, bool> check)
+ {
+ for (int i = 0; i < inArray1.Length; i++)
+ {
+ if (!check(inArray1[i], inArray2[i], outArray[i]))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+ }
+
+ }
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "></PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType>None</DebugType>
+ <Optimize></Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="UnpackHigh.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="UnpackHigh.cs" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
+</Project>
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+//
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics.X86;
+using System.Runtime.Intrinsics;
+
+namespace IntelHardwareIntrinsicTest
+{
+ class Program
+ {
+ const int Pass = 100;
+ const int Fail = 0;
+
+ static unsafe int Main(string[] args)
+ {
+ int testResult = Pass;
+
+ if (Avx2.IsSupported)
+ {
+ using (TestTable<byte, byte, byte> byteTable = new TestTable<byte, byte, byte>(new byte[32] { 1, 5, 100, 0, 1, 5, 100, 0, 1, 5, 100, 0, 1, 5, 100, 0, 1, 5, 100, 0, 1, 5, 100, 0, 1, 5, 100, 0, 1, 5, 100, 0 }, new byte[32] { 22, 1, 50, 0, 22, 1, 50, 0, 22, 1, 50, 0, 22, 1, 50, 0, 22, 1, 50, 0, 22, 1, 50, 0, 22, 1, 50, 0, 22, 1, 50, 0 }, new byte[32]))
+ using (TestTable<sbyte, sbyte, sbyte> sbyteTable = new TestTable<sbyte, sbyte, sbyte>(new sbyte[32] { 1, -5, 100, 0, 1, -5, 100, 0, 1, -5, 100, 0, 1, -5, 100, 0, 1, -5, 100, 0, 1, -5, 100, 0, 1, -5, 100, 0, 1, -5, 100, 0 }, new sbyte[32] { 22, -1, -50, 0, 22, -1, -50, 0, 22, -1, -50, 0, 22, -1, -50, 0, 22, -1, -50, 0, 22, -1, -50, 0, 22, -1, -50, 0, 22, -1, -50, 0 }, new sbyte[32]))
+ using (TestTable<short, short, short> shortTable = new TestTable<short, short, short>(new short[16] { 1, -5, 100, 0, 1, -5, 100, 0, 1, -5, 100, 0, 1, -5, 100, 0 }, new short[16] { 22, -1, -50, 0, 22, -1, -50, 0, 22, -1, -50, 0, 22, -1, -50, 0}, new short[16]))
+ using (TestTable<ushort, ushort, ushort> ushortTable = new TestTable<ushort, ushort, ushort>(new ushort[16] { 1, 5, 100, 0, 1, 5, 100, 0, 1, 5, 100, 0, 1, 5, 100, 0 }, new ushort[16] { 22, 1, 50, 0, 22, 1, 50, 0, 22, 1, 50, 0, 22, 1, 50, 0 }, new ushort[16]))
+ using (TestTable<int, int, int> intTable = new TestTable<int, int, int>(new int[8] { 1, 5, 100, 0, 1, 5, 100, 0}, new int[8] { 22, 1, 50, 0, 22, 1, 50, 0 }, new int[8]))
+ using (TestTable<uint, uint, uint> uintTable = new TestTable<uint, uint, uint>(new uint[8] { 1, 5, 100, 0, 1, 5, 100, 0 }, new uint[8] { 22, 1, 50, 0, 22, 1, 50, 0 }, new uint[8]))
+ using (TestTable<long, long, long> longTable = new TestTable<long, long, long>(new long[4] { 1, -5, 100, 0 }, new long[4] { 22, -1, -50, 0}, new long[4]))
+ using (TestTable<ulong, ulong, ulong> ulongTable = new TestTable<ulong, ulong, ulong>(new ulong[4] { 1, 5, 100, 0 }, new ulong[4] { 22, 1, 50, 0 }, new ulong[4]))
+
+ {
+
+ var vb1 = Unsafe.Read<Vector256<byte>>(byteTable.inArray1Ptr);
+ var vb2 = Unsafe.Read<Vector256<byte>>(byteTable.inArray2Ptr);
+ var vb3 = Avx2.UnpackLow(vb1, vb2);
+ Unsafe.Write(byteTable.outArrayPtr, vb3);
+
+ var vsb1 = Unsafe.Read<Vector256<sbyte>>(sbyteTable.inArray1Ptr);
+ var vsb2 = Unsafe.Read<Vector256<sbyte>>(sbyteTable.inArray2Ptr);
+ var vsb3 = Avx2.UnpackLow(vsb1, vsb2);
+ Unsafe.Write(sbyteTable.outArrayPtr, vsb3);
+
+ var vs1 = Unsafe.Read<Vector256<short>>(shortTable.inArray1Ptr);
+ var vs2 = Unsafe.Read<Vector256<short>>(shortTable.inArray2Ptr);
+ var vs3 = Avx2.UnpackLow(vs1, vs2);
+ Unsafe.Write(shortTable.outArrayPtr, vs3);
+
+ var vus1 = Unsafe.Read<Vector256<ushort>>(ushortTable.inArray1Ptr);
+ var vus2 = Unsafe.Read<Vector256<ushort>>(ushortTable.inArray2Ptr);
+ var vus3 = Avx2.UnpackLow(vus1, vus2);
+ Unsafe.Write(ushortTable.outArrayPtr, vus3);
+
+ var vi1 = Unsafe.Read<Vector256<int>>(intTable.inArray1Ptr);
+ var vi2 = Unsafe.Read<Vector256<int>>(intTable.inArray2Ptr);
+ var vi3 = Avx2.UnpackLow(vi1, vi2);
+ Unsafe.Write(intTable.outArrayPtr, vi3);
+
+ var vui1 = Unsafe.Read<Vector256<uint>>(uintTable.inArray1Ptr);
+ var vui2 = Unsafe.Read<Vector256<uint>>(uintTable.inArray2Ptr);
+ var vui3 = Avx2.UnpackLow(vui1, vui2);
+ Unsafe.Write(uintTable.outArrayPtr, vui3);
+
+ var vl1 = Unsafe.Read<Vector256<long>>(longTable.inArray1Ptr);
+ var vl2 = Unsafe.Read<Vector256<long>>(longTable.inArray2Ptr);
+ var vl3 = Avx2.UnpackLow(vl1, vl2);
+ Unsafe.Write(longTable.outArrayPtr, vl3);
+
+ var vul1 = Unsafe.Read<Vector256<ulong>>(ulongTable.inArray1Ptr);
+ var vul2 = Unsafe.Read<Vector256<ulong>>(ulongTable.inArray2Ptr);
+ var vul3 = Avx2.UnpackLow(vul1, vul2);
+ Unsafe.Write(ulongTable.outArrayPtr, vul3);
+
+ if((byteTable.inArray1[0] != byteTable.outArray[0]) || (byteTable.inArray2[0] != byteTable.outArray[1]) ||
+ (byteTable.inArray1[1] != byteTable.outArray[2]) || (byteTable.inArray2[1] != byteTable.outArray[3]) ||
+ (byteTable.inArray1[2] != byteTable.outArray[4]) || (byteTable.inArray2[2] != byteTable.outArray[5]) ||
+ (byteTable.inArray1[3] != byteTable.outArray[6]) || (byteTable.inArray2[3] != byteTable.outArray[7]) ||
+ (byteTable.inArray1[4] != byteTable.outArray[8]) || (byteTable.inArray2[4] != byteTable.outArray[9]) ||
+ (byteTable.inArray1[5] != byteTable.outArray[10]) || (byteTable.inArray2[5] != byteTable.outArray[11]) ||
+ (byteTable.inArray1[6] != byteTable.outArray[12]) || (byteTable.inArray2[6] != byteTable.outArray[13]) ||
+ (byteTable.inArray1[7] != byteTable.outArray[14]) || (byteTable.inArray2[7] != byteTable.outArray[15]) ||
+ (byteTable.inArray1[16] != byteTable.outArray[16]) || (byteTable.inArray2[16] != byteTable.outArray[17]) ||
+ (byteTable.inArray1[17] != byteTable.outArray[18]) || (byteTable.inArray2[17] != byteTable.outArray[19]) ||
+ (byteTable.inArray1[18] != byteTable.outArray[20]) || (byteTable.inArray2[18] != byteTable.outArray[21]) ||
+ (byteTable.inArray1[19] != byteTable.outArray[22]) || (byteTable.inArray2[19] != byteTable.outArray[23]) ||
+ (byteTable.inArray1[20] != byteTable.outArray[24]) || (byteTable.inArray2[20] != byteTable.outArray[25]) ||
+ (byteTable.inArray1[21] != byteTable.outArray[26]) || (byteTable.inArray2[21] != byteTable.outArray[27]) ||
+ (byteTable.inArray1[22] != byteTable.outArray[28]) || (byteTable.inArray2[22] != byteTable.outArray[29]) ||
+ (byteTable.inArray1[23] != byteTable.outArray[30]) || (byteTable.inArray2[23] != byteTable.outArray[31]))
+ {
+ Console.WriteLine("AVX2 UnpackLow failed on byte:");
+ Console.WriteLine($" left: ({string.Join(", ", byteTable.inArray1)})");
+ Console.WriteLine($" right: ({string.Join(", ", byteTable.inArray2)})");
+ Console.WriteLine($" result: ({string.Join(", ", byteTable.outArray)})");
+ Console.WriteLine();
+
+ testResult = Fail;
+ }
+
+ if((sbyteTable.inArray1[0] != sbyteTable.outArray[0]) || (sbyteTable.inArray2[0] != sbyteTable.outArray[1]) ||
+ (sbyteTable.inArray1[1] != sbyteTable.outArray[2]) || (sbyteTable.inArray2[1] != sbyteTable.outArray[3]) ||
+ (sbyteTable.inArray1[2] != sbyteTable.outArray[4]) || (sbyteTable.inArray2[2] != sbyteTable.outArray[5]) ||
+ (sbyteTable.inArray1[3] != sbyteTable.outArray[6]) || (sbyteTable.inArray2[3] != sbyteTable.outArray[7]) ||
+ (sbyteTable.inArray1[4] != sbyteTable.outArray[8]) || (sbyteTable.inArray2[4] != sbyteTable.outArray[9]) ||
+ (sbyteTable.inArray1[5] != sbyteTable.outArray[10]) || (sbyteTable.inArray2[5] != sbyteTable.outArray[11]) ||
+ (sbyteTable.inArray1[6] != sbyteTable.outArray[12]) || (sbyteTable.inArray2[6] != sbyteTable.outArray[13]) ||
+ (sbyteTable.inArray1[7] != sbyteTable.outArray[14]) || (sbyteTable.inArray2[7] != sbyteTable.outArray[15]) ||
+ (sbyteTable.inArray1[16] != sbyteTable.outArray[16]) || (sbyteTable.inArray2[16] != sbyteTable.outArray[17]) ||
+ (sbyteTable.inArray1[17] != sbyteTable.outArray[18]) || (sbyteTable.inArray2[17] != sbyteTable.outArray[19]) ||
+ (sbyteTable.inArray1[18] != sbyteTable.outArray[20]) || (sbyteTable.inArray2[18] != sbyteTable.outArray[21]) ||
+ (sbyteTable.inArray1[19] != sbyteTable.outArray[22]) || (sbyteTable.inArray2[19] != sbyteTable.outArray[23]) ||
+ (sbyteTable.inArray1[20] != sbyteTable.outArray[24]) || (sbyteTable.inArray2[20] != sbyteTable.outArray[25]) ||
+ (sbyteTable.inArray1[21] != sbyteTable.outArray[26]) || (sbyteTable.inArray2[21] != sbyteTable.outArray[27]) ||
+ (sbyteTable.inArray1[22] != sbyteTable.outArray[28]) || (sbyteTable.inArray2[22] != sbyteTable.outArray[29]) ||
+ (sbyteTable.inArray1[23] != sbyteTable.outArray[30]) || (sbyteTable.inArray2[23] != sbyteTable.outArray[31]))
+ {
+ Console.WriteLine("AVX2 UnpackLow failed on sbyte:");
+ Console.WriteLine($" left: ({string.Join(", ", byteTable.inArray1)})");
+ Console.WriteLine($" right: ({string.Join(", ", byteTable.inArray2)})");
+ Console.WriteLine($" result: ({string.Join(", ", byteTable.outArray)})");
+ Console.WriteLine();
+
+ testResult = Fail;
+ }
+
+ if((shortTable.inArray1[0] != shortTable.outArray[0]) || (shortTable.inArray2[0] != shortTable.outArray[1]) ||
+ (shortTable.inArray1[1] != shortTable.outArray[2]) || (shortTable.inArray2[1] != shortTable.outArray[3]) ||
+ (shortTable.inArray1[2] != shortTable.outArray[4]) || (shortTable.inArray2[2] != shortTable.outArray[5]) ||
+ (shortTable.inArray1[3] != shortTable.outArray[6]) || (shortTable.inArray2[3] != shortTable.outArray[7]) ||
+ (shortTable.inArray1[8] != shortTable.outArray[8]) || (shortTable.inArray2[8] != shortTable.outArray[9]) ||
+ (shortTable.inArray1[9] != shortTable.outArray[10]) || (shortTable.inArray2[9] != shortTable.outArray[11]) ||
+ (shortTable.inArray1[10] != shortTable.outArray[12]) || (shortTable.inArray2[10] != shortTable.outArray[13]) ||
+ (shortTable.inArray1[11] != shortTable.outArray[14]) || (shortTable.inArray2[11] != shortTable.outArray[15]))
+
+ {
+ Console.WriteLine("AVX2 UnpackLow failed on short:");
+ Console.WriteLine($" left: ({string.Join(", ", byteTable.inArray1)})");
+ Console.WriteLine($" right: ({string.Join(", ", byteTable.inArray2)})");
+ Console.WriteLine($" result: ({string.Join(", ", byteTable.outArray)})");
+ Console.WriteLine();
+
+ testResult = Fail;
+ }
+
+ if((ushortTable.inArray1[0] != ushortTable.outArray[0]) || (ushortTable.inArray2[0] != ushortTable.outArray[1]) ||
+ (ushortTable.inArray1[1] != ushortTable.outArray[2]) || (ushortTable.inArray2[1] != ushortTable.outArray[3]) ||
+ (ushortTable.inArray1[2] != ushortTable.outArray[4]) || (ushortTable.inArray2[2] != ushortTable.outArray[5]) ||
+ (ushortTable.inArray1[3] != ushortTable.outArray[6]) || (ushortTable.inArray2[3] != ushortTable.outArray[7]) ||
+ (ushortTable.inArray1[8] != ushortTable.outArray[8]) || (ushortTable.inArray2[8] != ushortTable.outArray[9]) ||
+ (ushortTable.inArray1[9] != ushortTable.outArray[10]) || (ushortTable.inArray2[9] != ushortTable.outArray[11]) ||
+ (ushortTable.inArray1[10] != ushortTable.outArray[12]) || (ushortTable.inArray2[10] != ushortTable.outArray[13]) ||
+ (ushortTable.inArray1[11] != ushortTable.outArray[14]) || (ushortTable.inArray2[11] != ushortTable.outArray[15]))
+ {
+ Console.WriteLine("AVX2 UnpackLow failed on ushort:");
+ Console.WriteLine($" left: ({string.Join(", ", byteTable.inArray1)})");
+ Console.WriteLine($" right: ({string.Join(", ", byteTable.inArray2)})");
+ Console.WriteLine($" result: ({string.Join(", ", byteTable.outArray)})");
+ Console.WriteLine();
+
+ testResult = Fail;
+ }
+
+ if ((intTable.inArray1[0] != intTable.outArray[0]) || (intTable.inArray2[0] != intTable.outArray[1]) ||
+ (intTable.inArray1[1] != intTable.outArray[2]) || (intTable.inArray2[1] != intTable.outArray[3]) ||
+ (intTable.inArray1[4] != intTable.outArray[4]) || (intTable.inArray2[4] != intTable.outArray[5]) ||
+ (intTable.inArray1[5] != intTable.outArray[6]) || (intTable.inArray2[5] != intTable.outArray[7]))
+ {
+ Console.WriteLine("AVX2 UnpackLow failed on int:");
+ Console.WriteLine($" left: ({string.Join(", ", byteTable.inArray1)})");
+ Console.WriteLine($" right: ({string.Join(", ", byteTable.inArray2)})");
+ Console.WriteLine($" result: ({string.Join(", ", byteTable.outArray)})");
+ Console.WriteLine();
+
+ testResult = Fail;
+ }
+
+ if ((uintTable.inArray1[0] != uintTable.outArray[0]) || (uintTable.inArray2[0] != uintTable.outArray[1]) ||
+ (uintTable.inArray1[1] != uintTable.outArray[2]) || (uintTable.inArray2[1] != uintTable.outArray[3]) ||
+ (uintTable.inArray1[4] != uintTable.outArray[4]) || (uintTable.inArray2[4] != uintTable.outArray[5]) ||
+ (uintTable.inArray1[5] != uintTable.outArray[6]) || (uintTable.inArray2[5] != uintTable.outArray[7]))
+ {
+ Console.WriteLine("AVX2 UnpackLow failed on uint:");
+ Console.WriteLine($" left: ({string.Join(", ", byteTable.inArray1)})");
+ Console.WriteLine($" right: ({string.Join(", ", byteTable.inArray2)})");
+ Console.WriteLine($" result: ({string.Join(", ", byteTable.outArray)})");
+ Console.WriteLine();
+
+ testResult = Fail;
+ }
+
+ if ((longTable.inArray1[0] != longTable.outArray[0]) || (longTable.inArray2[0] != longTable.outArray[1]) ||
+ (longTable.inArray1[2] != longTable.outArray[2]) || (longTable.inArray2[2] != longTable.outArray[3]) )
+ {
+ Console.WriteLine("AVX2 UnpackLow failed on long:");
+ Console.WriteLine($" left: ({string.Join(", ", byteTable.inArray1)})");
+ Console.WriteLine($" right: ({string.Join(", ", byteTable.inArray2)})");
+ Console.WriteLine($" result: ({string.Join(", ", byteTable.outArray)})");
+ Console.WriteLine();
+
+ testResult = Fail;
+ }
+
+ if ((ulongTable.inArray1[0] != ulongTable.outArray[0]) || (ulongTable.inArray2[0] != ulongTable.outArray[1]) ||
+ (ulongTable.inArray1[2] != ulongTable.outArray[2]) || (ulongTable.inArray2[2] != ulongTable.outArray[3]) )
+ {
+ Console.WriteLine("AVX2 UnpackLow failed on ulong:");
+ Console.WriteLine($" left: ({string.Join(", ", byteTable.inArray1)})");
+ Console.WriteLine($" right: ({string.Join(", ", byteTable.inArray2)})");
+ Console.WriteLine($" result: ({string.Join(", ", byteTable.outArray)})");
+ Console.WriteLine();
+
+ testResult = Fail;
+ }
+ }
+ }
+
+ return testResult;
+ }
+
+ public unsafe struct TestTable<T1, T2, T3> : IDisposable where T1 : struct where T2 : struct where T3 : struct
+ {
+ public T1[] inArray1;
+ public T2[] inArray2;
+ public T3[] outArray;
+
+ public void* inArray1Ptr => inHandle1.AddrOfPinnedObject().ToPointer();
+ public void* inArray2Ptr => inHandle2.AddrOfPinnedObject().ToPointer();
+ public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer();
+
+ GCHandle inHandle1;
+ GCHandle inHandle2;
+ GCHandle outHandle;
+ public TestTable(T1[] a, T2[] b, T3[] c)
+ {
+ this.inArray1 = a;
+ this.inArray2 = b;
+ this.outArray = c;
+
+ inHandle1 = GCHandle.Alloc(inArray1, GCHandleType.Pinned);
+ inHandle2 = GCHandle.Alloc(inArray2, GCHandleType.Pinned);
+ outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned);
+ }
+ public bool CheckResult(Func<T1, T2, T3, bool> check)
+ {
+ for (int i = 0; i < inArray1.Length; i++)
+ {
+ if (!check(inArray1[i], inArray2[i], outArray[i]))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+ }
+
+ }
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "></PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType>None</DebugType>
+ <Optimize></Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="UnpackLow.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="UnpackLow.cs" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
+</Project>