[jit] Add unaligned tests.
authorRodrigo Kumpera <kumpera@gmail.com>
Fri, 19 May 2017 03:13:38 +0000 (20:13 -0700)
committerRodrigo Kumpera <kumpera@gmail.com>
Fri, 19 May 2017 03:16:30 +0000 (20:16 -0700)
mono/mini/Makefile.am.in
mono/mini/MemoryIntrinsics.il [new file with mode: 0644]
mono/mini/unaligned.cs [new file with mode: 0644]

index e0db07a52b4a8042be12b8a32a6e8b42ae7826e1..1872e1af95d769140b432ea07794eba2ae38585e 100755 (executable)
@@ -502,6 +502,8 @@ test_sources =                      \
        aot-tests.cs \
        gc-test.cs \
        gshared.cs \
+       unaligned.cs    \
+       MemoryIntrinsics.il     \
        mixed.cs
 
 if NACL_CODEGEN
@@ -521,6 +523,7 @@ regtests_UNIVERSAL = \
        devirtualization.exe \
        generics.exe \
        basic-simd.exe \
+       unaligned.exe   \
        basic-vectors.exe
 
 if NACL_CODEGEN
@@ -654,6 +657,9 @@ nacl.exe: nacl.cs TestDriver.dll
 generics.exe: generics.cs TestDriver.dll generics-variant-types.dll
        $(MCS) -out:$@ $(CSFLAGS) $< -r:TestDriver.dll -r:generics-variant-types.dll -r:$(CLASS)/System.Core.dll
 
+unaligned.exe: unaligned.cs TestDriver.dll MemoryIntrinsics.dll
+       $(MCS) -out:$@ $(CSFLAGS) $< -r:TestDriver.dll -r:MemoryIntrinsics.dll
+
 %.exe: %.cs TestDriver.dll
        $(MCS) -out:$@ $(CSFLAGS) $< -r:TestDriver.dll
 
@@ -666,6 +672,9 @@ TestDriver.dll: $(srcdir)/TestDriver.cs $(srcdir)/TestHelpers.cs
 generics-variant-types.dll: generics-variant-types.il
        $(ILASM) -dll -output=$@ $<
 
+MemoryIntrinsics.dll: MemoryIntrinsics.il
+       $(ILASM) -dll -output=$@ $<
+
 if NACL_CODEGEN
 GENMDESC_OPTS=--nacl
 else !NACL_CODEGEN
diff --git a/mono/mini/MemoryIntrinsics.il b/mono/mini/MemoryIntrinsics.il
new file mode 100644 (file)
index 0000000..2b471ac
--- /dev/null
@@ -0,0 +1,180 @@
+.assembly extern mscorlib
+{
+       .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )
+       .ver 4:0:0:0
+}
+
+.assembly 'MemoryIntrinsics'
+{
+       .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78  63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )
+       .hash algorithm 0x00008004
+       .ver 0:0:0:0
+}
+.module 'instrics-lib.dll'
+.imagebase 0x00400000
+.file alignment 0x00000200
+.stackreserve 0x00100000
+.subsystem 0x0003
+.corflags 0x00000001
+
+.namespace Mono {
+       .class public abstract auto ansi sealed beforefieldinit Intrinsics extends [mscorlib]System.Object
+       {
+               .method public hidebysig static void  Cpobj<T>(void* 'to', void* from) cil managed
+               {
+                       ldarg.0
+                       ldarg.1
+                       cpobj !!T
+                       ret
+               }
+
+               .method public hidebysig static !!T Ldobj<T>(void* 'from') cil managed
+               {
+                       ldarg.0
+                       ldobj !!T
+                       ret
+               }
+
+               .method public hidebysig static void Stobj<T>(void* 'to', !!T 'value') cil managed
+               {
+                       ldarg.0
+                       ldarg.1
+                       stobj !!T
+                       ret
+               }
+
+               .method public hidebysig static void LdobjStObjPair<T>(void* 'to', void* 'from') cil managed
+               {
+                       ldarg.0
+                       ldarg.1
+                       ldobj !!T
+                       stobj !!T
+                       ret
+               }
+
+               .method public hidebysig static void Cpblk(void* 'to', void* 'from', int32 size) cil managed
+               {
+                       ldarg.0
+                       ldarg.1
+                       ldarg.3
+                       cpblk
+                       ret
+               }
+
+               .method public hidebysig static void Initblk<T>(void* 'to', int32 'value', int32 'size') cil managed
+               {
+                       ldarg.0
+                       ldarg.1
+                       ldarg.3
+                       initblk
+                       ret
+               }
+
+               //Unaligned intrinsics
+               .method public hidebysig static void UnalignedCpobj<T>(void* 'to', void* from) cil managed
+               {
+                       ldarg.0
+                       ldarg.1
+                       unaligned. 1
+                       cpobj !!T
+                       ret
+               }
+
+               .method public hidebysig static !!T UnalignedLdobj<T>(void* 'from') cil managed
+               {
+                       ldarg.0
+                       unaligned. 1
+                       ldobj !!T
+                       ret
+               }
+
+               .method public hidebysig static void UnalignedStobj<T>(void* 'to', !!T 'value') cil managed
+               {
+                       ldarg.0
+                       ldarg.1
+                       unaligned. 1
+                       stobj !!T
+                       ret
+               }
+
+               .method public hidebysig static void UnalignedLdobjStObjPair<T>(void* 'to', void* 'from') cil managed
+               {
+                       ldarg.0
+                       ldarg.1
+                       unaligned. 1
+                       ldobj !!T
+                       stobj !!T
+                       ret
+               }
+
+               .method public hidebysig static void UnalignedCpblk(void* 'to', void* 'from', int32 size) cil managed
+               {
+                       ldarg.0
+                       ldarg.1
+                       ldarg.2
+                       unaligned. 1
+                       cpblk
+                       ret
+               }
+
+               .method public hidebysig static void UnalignedInit(void* 'to', int32 'value', int32 'size') cil managed
+               {
+                       ldarg.0
+                       ldarg.1
+                       ldarg.2
+                       unaligned. 1
+                       initblk
+                       ret
+               }
+
+               //Unaligned ldind
+               .method public hidebysig static int16 UnalignedLdInd2(void* 'from') cil managed
+               {
+                       ldarg.0
+                       unaligned. 1
+                       ldind.i2
+                       ret
+               }
+
+               .method public hidebysig static int32 UnalignedLdInd4(void* 'from') cil managed
+               {
+                       ldarg.0
+                       unaligned. 1
+                       ldind.i4
+                       ret
+               }
+
+               .method public hidebysig static int64 UnalignedLdInd8(void* 'from') cil managed
+               {
+                       ldarg.0
+                       unaligned. 1
+                       ldind.i8
+                       ret
+               }
+
+               .method public hidebysig static float32 UnalignedLdIndR4(void* 'from') cil managed
+               {
+                       ldarg.0
+                       unaligned. 1
+                       ldind.r4
+                       ret
+               }
+
+               .method public hidebysig static float64 UnalignedLdIndR8(void* 'from') cil managed
+               {
+                       ldarg.0
+                       unaligned. 1
+                       ldind.r8
+                       ret
+               }
+
+               .method public hidebysig static native int UnalignedLdIndI(void* 'from') cil managed
+               {
+                       ldarg.0
+                       unaligned. 1
+                       ldind.i
+                       ret
+               }
+
+       }
+}
diff --git a/mono/mini/unaligned.cs b/mono/mini/unaligned.cs
new file mode 100644 (file)
index 0000000..397fbbb
--- /dev/null
@@ -0,0 +1,307 @@
+using System;
+using System.Runtime.CompilerServices;
+using Mono;
+
+/*
+ * Regression tests for the mono JIT.
+ *
+ * Each test needs to be of the form:
+ *
+ * static int test_<result>_<name> ();
+ *
+ * where <result> is an integer (the value that needs to be returned by
+ * the method to make it pass.
+ * <name> is a user-displayed name used to identify the test.
+ *
+ * The tests can be driven in two ways:
+ * *) running the program directly: Main() uses reflection to find and invoke
+ *     the test methods (this is useful mostly to check that the tests are correct)
+ * *) with the --regression switch of the jit (this is the preferred way since
+ *     all the tests will be run with optimizations on and off)
+ *
+ * The reflection logic could be moved to a .dll since we need at least another
+ * regression test file written in IL code to have better control on how
+ * the IL code looks.
+ */
+
+#if __MOBILE__
+namespace UnalignedTests
+{
+#endif
+
+
+class Tests {
+
+#if !__MOBILE__
+       public static int Main (string[] args) {
+               return TestDriver.RunTests (typeof (Tests), args);
+       }
+#endif
+
+
+       public static unsafe int test_0_ldobj_r4 ()
+       {
+               byte *ptr = stackalloc byte [32];
+               float f = (float)123.44f;
+               *(float*)ptr = (float)f;
+
+               int expected = *(int*)ptr;
+
+               Intrinsics.UnalignedStobj<int> (ptr + 1, expected);
+               if (Intrinsics.UnalignedLdobj<float> (ptr + 1) != f)
+                       return 1;
+
+               return 0;
+       }
+
+       public static unsafe int test_0_ldobj_r8 ()
+       {
+               byte *ptr = stackalloc byte [32];
+               double f = 34423.44f;
+               *(double*)ptr = (double)f;
+
+               long expected = *(long*)ptr;
+
+               Intrinsics.UnalignedStobj<long> (ptr + 3, expected);
+               if (Intrinsics.UnalignedLdobj<double> (ptr + 3) != f)
+                       return 1;
+
+               return 0;
+       }
+
+       public static unsafe int test_0_ldobj ()
+       {
+               byte *ptr = stackalloc byte [20];
+               for (int i = 0; i < 20; ++i)
+                       ptr [i] = (byte)i;
+
+
+               if (Intrinsics.UnalignedLdobj<short> (ptr + 0) != 0x0100)
+                       return 1;
+
+               if (Intrinsics.UnalignedLdobj<short> (ptr + 1) != 0x0201)
+                       return 2;
+
+               if (Intrinsics.UnalignedLdobj<short> (ptr + 2) != 0x0302)
+                       return 3;
+
+               if (Intrinsics.UnalignedLdobj<int> (ptr + 1) != 0x04030201)
+                       return 4;
+
+               if (Intrinsics.UnalignedLdobj<int> (ptr + 2) != 0x05040302)
+                       return 5;
+
+               if (Intrinsics.UnalignedLdobj<long> (ptr + 1) != 0x0807060504030201)
+                       return 6;
+
+               if (Intrinsics.UnalignedLdobj<long> (ptr + 6) != 0xD0C0B0A09080706)
+                       return 7;
+
+               return 0;
+       }
+
+       public static unsafe int test_0_ldind ()
+       {
+               byte *ptr = stackalloc byte [20];
+               for (int i = 0; i < 20; ++i)
+                       ptr [i] = (byte)i;
+
+
+               if (Intrinsics.UnalignedLdInd2 (ptr + 0) != 0x0100)
+                       return 1;
+
+               if (Intrinsics.UnalignedLdInd2 (ptr + 1) != 0x0201)
+                       return 2;
+
+               if (Intrinsics.UnalignedLdInd2 (ptr + 2) != 0x0302)
+                       return 3;
+
+               if (Intrinsics.UnalignedLdInd4 (ptr + 1) != 0x04030201)
+                       return 4;
+
+               if (Intrinsics.UnalignedLdInd4 (ptr + 2) != 0x05040302)
+                       return 5;
+
+               if (Intrinsics.UnalignedLdInd8 (ptr + 1) != 0x0807060504030201)
+                       return 6;
+
+               if (Intrinsics.UnalignedLdInd8 (ptr + 6) != 0xD0C0B0A09080706)
+                       return 7;
+
+               return 0;
+       }
+       public static unsafe int test_0_cpobj ()
+       {
+               byte *dest = stackalloc byte [20];
+               byte *src = stackalloc byte [20];
+               for (int i = 0; i < 20; ++i)
+                       src [i] = (byte)i;
+
+               Intrinsics.UnalignedCpobj<short> (dest + 0, src + 0);
+               if (dest [0] != src [0] || dest [1] != src [1])
+                       return 1;
+
+               Intrinsics.UnalignedCpobj<short> (dest + 1, src + 0);
+               if (dest [1] != src [0] || dest [2] != src [1])
+                       return 2;
+
+               Intrinsics.UnalignedCpobj<short> (dest + 0, src + 1);
+               if (dest [0] != src [1] || dest [1] != src [2])
+                       return 3;
+
+               Intrinsics.UnalignedCpobj<short> (dest + 1, src + 1);
+               if (dest [1] != src [1] || dest [2] != src [2])
+                       return 3;
+
+               Intrinsics.UnalignedCpobj<int> (dest + 3, src);
+               for (int i = 0; i < 4; ++i) {
+                       if (dest [i + 3] != src [i])
+                               return 4;
+               }
+
+               Intrinsics.UnalignedCpobj<int> (dest + 1, src + 2);
+               for (int i = 0; i < 4; ++i) {
+                       if (dest [i + 1] != src [i + 2])
+                               return 5;
+               }
+
+               Intrinsics.UnalignedCpobj<long> (dest + 1, src + 2);
+               for (int i = 0; i < 8; ++i) {
+                       if (dest [i + 1] != src [i + 2])
+                               return 6;
+               }
+
+               Intrinsics.UnalignedCpobj<long> (dest + 7, src + 2);
+               for (int i = 0; i < 8; ++i) {
+                       if (dest [i + 7] != src [i + 2])
+                               return 7;
+               }
+
+               return 0;
+       }
+
+       public static unsafe int test_0_stobj ()
+       {
+               byte *ptr = stackalloc byte [20];
+
+               Intrinsics.UnalignedStobj <short> (ptr + 0, 0x6688);
+               if (ptr [0] != 0x88 || ptr [1] != 0x66)
+                       return 1;
+
+               Intrinsics.UnalignedStobj <short> (ptr + 1, 0x6589);
+               if (ptr [1] != 0x89 || ptr [2] != 0x65)
+                       return 2;
+
+               Intrinsics.UnalignedStobj <int> (ptr + 1, 0x60708090);
+               if (ptr [1] != 0x90 || ptr [2] != 0x80 || ptr [3] != 0x70 || ptr [4] != 0x60)
+                       return 3;
+
+               Intrinsics.UnalignedStobj <long> (ptr + 1, 0x405060708090);
+               if (ptr [1] != 0x90 || ptr [2] != 0x80 || ptr [3] != 0x70 || ptr [4] != 0x60 || ptr [5] != 0x50 || ptr [6] != 0x40)
+                       return 4;
+
+               return 0;
+       }
+
+       public static unsafe int test_0_ldobj_stobj ()
+       {
+               byte *dest = stackalloc byte [20];
+               byte *src = stackalloc byte [20];
+
+               for (int i = 0; i < 20; ++i)
+                       src [i] = (byte)i;
+
+               Intrinsics.UnalignedLdobjStObjPair<short> (dest + 0, src + 0);
+               if (dest [0] != src [0] || dest [1] != src [1])
+                       return 1;
+
+               Intrinsics.UnalignedLdobjStObjPair<short> (dest + 1, src + 0);
+               if (dest [1] != src [0] || dest [2] != src [1])
+                       return 2;
+
+               Intrinsics.UnalignedLdobjStObjPair<short> (dest + 0, src + 1);
+               if (dest [0] != src [1] || dest [1] != src [2])
+                       return 3;
+
+               Intrinsics.UnalignedLdobjStObjPair<short> (dest + 1, src + 1);
+               if (dest [1] != src [1] || dest [2] != src [2])
+                       return 3;
+
+               Intrinsics.UnalignedLdobjStObjPair<int> (dest + 1, src + 1);
+               if (dest [1] != src [1] || dest [2] != src [2])
+                       return 4;
+
+               Intrinsics.UnalignedLdobjStObjPair<long> (dest + 1, src + 1);
+               if (dest [1] != src [1] || dest [2] != src [2])
+                       return 5;
+
+
+               return 0;
+       }
+
+
+       public static unsafe int test_0_cpblk ()
+       {
+               byte *dest = stackalloc byte [20];
+               byte *src = stackalloc byte [20];
+               for (int i = 0; i < 20; ++i)
+                       src [i] = (byte)i;
+
+
+               Intrinsics.UnalignedCpblk (dest + 0, src + 0, 2);
+               if (dest [0] != src [0] || dest [1] != src [1])
+                       return 1;
+
+               Intrinsics.UnalignedCpblk (dest + 1, src + 0, 2);
+               if (dest [1] != src [0] || dest [2] != src [1])
+                       return 2;
+
+               Intrinsics.UnalignedCpblk (dest + 0, src + 1, 2);
+               if (dest [0] != src [1] || dest [1] != src [2])
+                       return 3;
+
+               Intrinsics.UnalignedCpblk (dest + 1, src + 1, 2);
+               if (dest [1] != src [1] || dest [2] != src [2])
+                       return 3;
+
+               Intrinsics.UnalignedCpblk (dest + 1, src + 1, 4);
+               for (int i = 0; i < 4; ++i) {
+                       if (dest [i + 1] != src [i + 1])
+                               return 4;
+               }
+
+               Intrinsics.UnalignedCpblk (dest + 1, src + 1, 8);
+               for (int i = 0; i < 8; ++i) {
+                       if (dest [i + 1] != src [i + 1])
+                               return 5;
+               }
+
+               return 0;
+       }
+
+
+       public static unsafe int test_0_initblk ()
+       {
+               byte *ptr = stackalloc byte [20];
+
+               for (int i = 0; i < 20; ++i)
+                       ptr [i] = (byte)i;
+
+               Intrinsics.UnalignedInit (ptr, 30, 2);
+               if (ptr [0] != 30 || ptr [1] != 30)
+                       return 1;
+
+               Intrinsics.UnalignedInit (ptr + 1, 31, 2);
+               if (ptr[0] != 30 || ptr [1] != 31 || ptr [2] != 31)
+                       return 2;
+
+               return 0;
+       }
+}
+
+#if __MOBILE__
+}
+#endif
+
+
+