diff options
author | Egor Bogatov <egorbo@gmail.com> | 2021-02-10 21:03:35 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-10 21:03:35 +0300 |
commit | af25fe652ec08fda63c23ae8f61470a48e65660e (patch) | |
tree | c9aee4bfbe05fd0efeebba01bd085f11c62464dc /src/tests/baseservices | |
parent | 69425a7e6198ff78131ad64f1aa3fc28202bfde8 (diff) |
[RyuJIT] Implement Interlocked.And and Interlocked.Or for arm64-v8.1 (#46253)
Diffstat (limited to 'src/tests/baseservices')
4 files changed, 308 insertions, 0 deletions
diff --git a/src/tests/baseservices/threading/interlocked/and_or/and_or_int32.cs b/src/tests/baseservices/threading/interlocked/and_or/and_or_int32.cs new file mode 100644 index 00000000000..a5f22074220 --- /dev/null +++ b/src/tests/baseservices/threading/interlocked/and_or/and_or_int32.cs @@ -0,0 +1,144 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.CompilerServices; +using System.Threading; + +public class Program +{ + private static int s_RetCode = 100; + + public static int Main() + { + int[] testData = new int[] { int.MinValue, int.MinValue + 1, -1, 0, 1, 2, 1000, int.MaxValue - 1, int.MaxValue }; + for (int i = 0; i < testData.Length; i++) + { + for (int j = 0; j < testData.Length; j++) + { + // XAnd + int test1Value = testData[i]; + int test1Arg = testData[j]; + int ret1Value = RefImpl.XAnd32(ref test1Value, test1Arg); + + int test2Value = testData[i]; + int test2Arg = testData[j]; + int ret2Value = InterlockedImpl.XAnd32(ref test2Value, test2Arg); + AssertEquals(test1Value, test2Value); + AssertEquals(ret1Value, ret2Value); + + // XAnd_noret + int test3Value = testData[i]; + int test3Arg = testData[j]; + RefImpl.XAnd32_noret(ref test3Value, test3Arg); + + int test4Value = testData[i]; + int test4Arg = testData[j]; + InterlockedImpl.XAnd32_noret(ref test4Value, test4Arg); + AssertEquals(test3Value, test4Value); + + // XOr + int test5Value = testData[i]; + int test5Arg = testData[j]; + int ret5Value = RefImpl.XOr32(ref test5Value, test5Arg); + + int test6Value = testData[i]; + int test6Arg = testData[j]; + int ret6Value = InterlockedImpl.XOr32(ref test6Value, test6Arg); + AssertEquals(test5Value, test6Value); + AssertEquals(ret5Value, ret6Value); + + // XOr_noret + int test7Value = testData[i]; + int test7Arg = testData[j]; + RefImpl.XOr32_noret(ref test7Value, test7Arg); + + int test8Value = testData[i]; + int test8Arg = testData[j]; + InterlockedImpl.XOr32_noret(ref test8Value, test8Arg); + AssertEquals(test7Value, test8Value); + } + + ThrowsNRE(() => + { + ref int nullref = ref Unsafe.NullRef<int>(); + InterlockedImpl.XAnd32(ref nullref, testData[i]); + }); + + ThrowsNRE(() => + { + ref int nullref = ref Unsafe.NullRef<int>(); + InterlockedImpl.XAnd32_noret(ref nullref, testData[i]); + }); + + ThrowsNRE(() => + { + ref int nullref = ref Unsafe.NullRef<int>(); + InterlockedImpl.XOr32(ref nullref, testData[i]); + }); + + ThrowsNRE(() => + { + ref int nullref = ref Unsafe.NullRef<int>(); + InterlockedImpl.XOr32_noret(ref nullref, testData[i]); + }); + } + + + return s_RetCode; + } + + static void ThrowsNRE(Action action) + { + try + { + action(); + } + catch (NullReferenceException) + { + return; + } + + Console.WriteLine("ERROR: NullReferenceException was expected"); + s_RetCode++; + } + + static void AssertEquals(int expected, int actual, [CallerLineNumber] int line = 0) + { + if (expected != actual) + { + Console.WriteLine($"ERROR: {expected} != {actual} (Line:{line})"); + s_RetCode++; + } + } +} + +class RefImpl +{ + [MethodImpl(MethodImplOptions.NoInlining)] + public static int XAnd32(ref int a, int b) { int src = a; a &= b; return src; } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void XAnd32_noret(ref int a, int b) => a &= b; + + [MethodImpl(MethodImplOptions.NoInlining)] + public static int XOr32(ref int a, int b) { int src = a; a |= b; return src; } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void XOr32_noret(ref int a, int b) => a |= b; +} + +class InterlockedImpl +{ + [MethodImpl(MethodImplOptions.NoInlining)] + public static int XAnd32(ref int a, int b) => Interlocked.And(ref a, b); + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void XAnd32_noret(ref int a, int b) => Interlocked.And(ref a, b); + + [MethodImpl(MethodImplOptions.NoInlining)] + public static int XOr32(ref int a, int b) => Interlocked.Or(ref a, b); + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void XOr32_noret(ref int a, int b) => Interlocked.Or(ref a, b); +}
\ No newline at end of file diff --git a/src/tests/baseservices/threading/interlocked/and_or/and_or_int32.csproj b/src/tests/baseservices/threading/interlocked/and_or/and_or_int32.csproj new file mode 100644 index 00000000000..19781e26c20 --- /dev/null +++ b/src/tests/baseservices/threading/interlocked/and_or/and_or_int32.csproj @@ -0,0 +1,10 @@ +<Project Sdk="Microsoft.NET.Sdk"> + <PropertyGroup> + <OutputType>Exe</OutputType> + <DebugType /> + <Optimize>True</Optimize> + </PropertyGroup> + <ItemGroup> + <Compile Include="$(MSBuildProjectName).cs" /> + </ItemGroup> +</Project> diff --git a/src/tests/baseservices/threading/interlocked/and_or/and_or_int64.cs b/src/tests/baseservices/threading/interlocked/and_or/and_or_int64.cs new file mode 100644 index 00000000000..01f7e014cff --- /dev/null +++ b/src/tests/baseservices/threading/interlocked/and_or/and_or_int64.cs @@ -0,0 +1,144 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.CompilerServices; +using System.Threading; + +public class Program +{ + private static int s_RetCode = 100; + + public static int Main() + { + long[] testData = new long[] { long.MinValue, long.MinValue + 1, -1, 0, 1, 2, 1000, long.MaxValue - 1, long.MaxValue }; + for (long i = 0; i < testData.Length; i++) + { + for (long j = 0; j < testData.Length; j++) + { + // XAnd + long test1Value = testData[i]; + long test1Arg = testData[j]; + long ret1Value = RefImpl.XAnd64(ref test1Value, test1Arg); + + long test2Value = testData[i]; + long test2Arg = testData[j]; + long ret2Value = InterlockedImpl.XAnd64(ref test2Value, test2Arg); + AssertEquals(test1Value, test2Value); + AssertEquals(ret1Value, ret2Value); + + // XAnd_noret + long test3Value = testData[i]; + long test3Arg = testData[j]; + RefImpl.XAnd64_noret(ref test3Value, test3Arg); + + long test4Value = testData[i]; + long test4Arg = testData[j]; + InterlockedImpl.XAnd64_noret(ref test4Value, test4Arg); + AssertEquals(test3Value, test4Value); + + // XOr + long test5Value = testData[i]; + long test5Arg = testData[j]; + long ret5Value = RefImpl.XOr64(ref test5Value, test5Arg); + + long test6Value = testData[i]; + long test6Arg = testData[j]; + long ret6Value = InterlockedImpl.XOr64(ref test6Value, test6Arg); + AssertEquals(test5Value, test6Value); + AssertEquals(ret5Value, ret6Value); + + // XOr_noret + long test7Value = testData[i]; + long test7Arg = testData[j]; + RefImpl.XOr64_noret(ref test7Value, test7Arg); + + long test8Value = testData[i]; + long test8Arg = testData[j]; + InterlockedImpl.XOr64_noret(ref test8Value, test8Arg); + AssertEquals(test7Value, test8Value); + } + + ThrowsNRE(() => + { + ref long nullref = ref Unsafe.NullRef<long>(); + InterlockedImpl.XAnd64(ref nullref, testData[i]); + }); + + ThrowsNRE(() => + { + ref long nullref = ref Unsafe.NullRef<long>(); + InterlockedImpl.XAnd64_noret(ref nullref, testData[i]); + }); + + ThrowsNRE(() => + { + ref long nullref = ref Unsafe.NullRef<long>(); + InterlockedImpl.XOr64(ref nullref, testData[i]); + }); + + ThrowsNRE(() => + { + ref long nullref = ref Unsafe.NullRef<long>(); + InterlockedImpl.XOr64_noret(ref nullref, testData[i]); + }); + } + + + return s_RetCode; + } + + static void ThrowsNRE(Action action) + { + try + { + action(); + } + catch (NullReferenceException) + { + return; + } + + Console.WriteLine("ERROR: NullReferenceException was expected"); + s_RetCode++; + } + + static void AssertEquals(long expected, long actual, [CallerLineNumber] long line = 0) + { + if (expected != actual) + { + Console.WriteLine($"ERROR: {expected} != {actual} (Line:{line})"); + s_RetCode++; + } + } +} + +class RefImpl +{ + [MethodImpl(MethodImplOptions.NoInlining)] + public static long XAnd64(ref long a, long b) { long src = a; a &= b; return src; } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void XAnd64_noret(ref long a, long b) => a &= b; + + [MethodImpl(MethodImplOptions.NoInlining)] + public static long XOr64(ref long a, long b) { long src = a; a |= b; return src; } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void XOr64_noret(ref long a, long b) => a |= b; +} + +class InterlockedImpl +{ + [MethodImpl(MethodImplOptions.NoInlining)] + public static long XAnd64(ref long a, long b) => Interlocked.And(ref a, b); + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void XAnd64_noret(ref long a, long b) => Interlocked.And(ref a, b); + + [MethodImpl(MethodImplOptions.NoInlining)] + public static long XOr64(ref long a, long b) => Interlocked.Or(ref a, b); + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void XOr64_noret(ref long a, long b) => Interlocked.Or(ref a, b); +}
\ No newline at end of file diff --git a/src/tests/baseservices/threading/interlocked/and_or/and_or_int64.csproj b/src/tests/baseservices/threading/interlocked/and_or/and_or_int64.csproj new file mode 100644 index 00000000000..19781e26c20 --- /dev/null +++ b/src/tests/baseservices/threading/interlocked/and_or/and_or_int64.csproj @@ -0,0 +1,10 @@ +<Project Sdk="Microsoft.NET.Sdk"> + <PropertyGroup> + <OutputType>Exe</OutputType> + <DebugType /> + <Optimize>True</Optimize> + </PropertyGroup> + <ItemGroup> + <Compile Include="$(MSBuildProjectName).cs" /> + </ItemGroup> +</Project> |