diff options
author | Levi Broderick <GrabYourPitchforks@users.noreply.github.com> | 2018-11-05 16:06:32 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-11-05 16:06:32 -0800 |
commit | f72025c8b6d8a4fc3b4e22e2a3b6e1afeaef15ff (patch) | |
tree | 963da39e25dfd9ac91fcca84e8b78adba86b5820 /tests/src/JIT | |
parent | 28417584d8e98ae7eac22e92b952778f8ea94047 (diff) | |
download | coreclr-f72025c8b6d8a4fc3b4e22e2a3b6e1afeaef15ff.tar.gz coreclr-f72025c8b6d8a4fc3b4e22e2a3b6e1afeaef15ff.tar.bz2 coreclr-f72025c8b6d8a4fc3b4e22e2a3b6e1afeaef15ff.zip |
Add support for BSWAP intrinsic (#18398)
With this change, the JIT will recognize a call to BinaryPrimitives.ReverseEndianness and will emit a bswap instruction.
This logic is currently only hooked up for x86 and x64; ARM still uses fallback logic.
If the JIT can't emit a bswap instruction (for example, trying to emit a 64-bit bswap in a 32-bit process), it will fall back to a software implementation, so the APIs will work across all architectures.
Diffstat (limited to 'tests/src/JIT')
3 files changed, 206 insertions, 0 deletions
diff --git a/tests/src/JIT/Intrinsics/BinaryPrimitivesReverseEndianness.cs b/tests/src/JIT/Intrinsics/BinaryPrimitivesReverseEndianness.cs new file mode 100644 index 0000000000..b650fc8982 --- /dev/null +++ b/tests/src/JIT/Intrinsics/BinaryPrimitivesReverseEndianness.cs @@ -0,0 +1,136 @@ +// 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.Buffers.Binary; +using Internal; + +namespace BinaryPrimitivesReverseEndianness +{ + class Program + { + public const int Pass = 100; + public const int Fail = 0; + + private const ushort ConstantUInt16Input = 0x9876; + private const ushort ConstantUInt16Expected = 0x7698; + + private const uint ConstantUInt32Input = 0x98765432; + private const uint ConstantUInt32Expected = 0x32547698; + + private const ulong ConstantUInt64Input = 0xfedcba9876543210; + private const ulong ConstantUInt64Expected = 0x1032547698badcfe; + + + static int Main(string[] args) + { + /* + * CONST VALUE TESTS + */ + + ushort swappedUInt16 = BinaryPrimitives.ReverseEndianness(ConstantUInt16Input); + if (swappedUInt16 != ConstantUInt16Expected) + { + Console.WriteLine($"BinaryPrimitives.ReverseEndianness(const UInt16) failed."); + Console.WriteLine($"Input: 0x{ConstantUInt16Input:X4}"); + Console.WriteLine($"Output: 0x{swappedUInt16:X4}"); + Console.WriteLine($"Expected: 0x{ConstantUInt16Expected:X4}"); + } + + uint swappedUInt32 = BinaryPrimitives.ReverseEndianness(ConstantUInt32Input); + if (swappedUInt32 != ConstantUInt32Expected) + { + Console.WriteLine($"BinaryPrimitives.ReverseEndianness(const UInt32) failed."); + Console.WriteLine($"Input: 0x{ConstantUInt32Input:X8}"); + Console.WriteLine($"Output: 0x{swappedUInt32:X8}"); + Console.WriteLine($"Expected: 0x{ConstantUInt32Expected:X8}"); + } + + ulong swappedUInt64 = BinaryPrimitives.ReverseEndianness(ConstantUInt64Input); + if (swappedUInt64 != ConstantUInt64Expected) + { + Console.WriteLine($"BinaryPrimitives.ReverseEndianness(const UInt32) failed."); + Console.WriteLine($"Input: 0x{ConstantUInt64Input:X16}"); + Console.WriteLine($"Output: 0x{swappedUInt64:X16}"); + Console.WriteLine($"Expected: 0x{ConstantUInt64Expected:X16}"); + } + + /* + * NON-CONST VALUE TESTS + */ + + ushort nonConstUInt16Input = (ushort)DateTime.UtcNow.Ticks; + ushort nonConstUInt16Output = BinaryPrimitives.ReverseEndianness(nonConstUInt16Input); + ushort nonConstUInt16Expected = ByteSwapUInt16_Control(nonConstUInt16Input); + if (nonConstUInt16Output != nonConstUInt16Expected) + { + Console.WriteLine($"BinaryPrimitives.ReverseEndianness(non-const UInt16) failed."); + Console.WriteLine($"Input: 0x{nonConstUInt16Input:X4}"); + Console.WriteLine($"Output: 0x{nonConstUInt16Output:X4}"); + Console.WriteLine($"Expected: 0x{nonConstUInt16Expected:X4}"); + } + + uint nonConstUInt32Input = (uint)DateTime.UtcNow.Ticks; + uint nonConstUInt32Output = BinaryPrimitives.ReverseEndianness(nonConstUInt32Input); + uint nonConstUInt32Expected = ByteSwapUInt32_Control(nonConstUInt32Input); + if (nonConstUInt32Output != nonConstUInt32Expected) + { + Console.WriteLine($"BinaryPrimitives.ReverseEndianness(non-const UInt32) failed."); + Console.WriteLine($"Input: 0x{nonConstUInt32Input:X8}"); + Console.WriteLine($"Output: 0x{nonConstUInt32Output:X8}"); + Console.WriteLine($"Expected: 0x{nonConstUInt32Expected:X8}"); + } + + ulong nonConstUInt64Input = (ulong)DateTime.UtcNow.Ticks; + ulong nonConstUInt64Output = BinaryPrimitives.ReverseEndianness(nonConstUInt64Input); + ulong nonConstUInt64Expected = ByteSwapUInt64_Control(nonConstUInt64Input); + if (nonConstUInt64Output != nonConstUInt64Expected) + { + Console.WriteLine($"BinaryPrimitives.ReverseEndianness(non-const UInt64) failed."); + Console.WriteLine($"Input: 0x{nonConstUInt64Input:X16}"); + Console.WriteLine($"Output: 0x{nonConstUInt64Output:X16}"); + Console.WriteLine($"Expected: 0x{nonConstUInt64Expected:X16}"); + } + + return Pass; + } + + private static ushort ByteSwapUInt16_Control(ushort value) + { + return (ushort)ByteSwapUnsigned_General(value, sizeof(ushort)); + } + + private static uint ByteSwapUInt32_Control(uint value) + { + return (uint)ByteSwapUnsigned_General(value, sizeof(uint)); + } + + private static ulong ByteSwapUInt64_Control(ulong value) + { + return (ulong)ByteSwapUnsigned_General(value, sizeof(ulong)); + } + + private static ulong ByteSwapUnsigned_General(ulong value, int width) + { + // A naive byte swap routine that works on integers of any arbitrary width. + // Width is specified in bytes. + + ulong retVal = 0; + do + { + retVal = retVal << 8 | (byte)value; + value >>= 8; + } while (--width > 0); + + if (value != 0) + { + // All bits of value should've been shifted out at this point. + throw new Exception("Unexpected data width specified - error in test program?"); + } + + return retVal; + } + } +} diff --git a/tests/src/JIT/Intrinsics/BinaryPrimitivesReverseEndianness_r.csproj b/tests/src/JIT/Intrinsics/BinaryPrimitivesReverseEndianness_r.csproj new file mode 100644 index 0000000000..32ddef9c5a --- /dev/null +++ b/tests/src/JIT/Intrinsics/BinaryPrimitivesReverseEndianness_r.csproj @@ -0,0 +1,35 @@ +<?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> + <ReferenceSystemPrivateCoreLib>true</ReferenceSystemPrivateCoreLib> + </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> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + <DebugType>None</DebugType> + <Optimize></Optimize> + </PropertyGroup> + <ItemGroup> + <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> + </ItemGroup> + <ItemGroup> + <Compile Include="BinaryPrimitivesReverseEndianness.cs" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> + <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup> +</Project> diff --git a/tests/src/JIT/Intrinsics/BinaryPrimitivesReverseEndianness_ro.csproj b/tests/src/JIT/Intrinsics/BinaryPrimitivesReverseEndianness_ro.csproj new file mode 100644 index 0000000000..ca7ce2184e --- /dev/null +++ b/tests/src/JIT/Intrinsics/BinaryPrimitivesReverseEndianness_ro.csproj @@ -0,0 +1,35 @@ +<?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> + <ReferenceSystemPrivateCoreLib>true</ReferenceSystemPrivateCoreLib> + </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> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + <DebugType>None</DebugType> + <Optimize>True</Optimize> + </PropertyGroup> + <ItemGroup> + <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> + </ItemGroup> + <ItemGroup> + <Compile Include="BinaryPrimitivesReverseEndianness.cs" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> + <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup> +</Project> |