Merge pull request #5406 from kumpera/fix_12157
[mono.git] / mono / mini / unaligned.cs
1 using System;
2 using System.Runtime.CompilerServices;
3 using Mono;
4
5 /*
6  * Regression tests for the mono JIT.
7  *
8  * Each test needs to be of the form:
9  *
10  * static int test_<result>_<name> ();
11  *
12  * where <result> is an integer (the value that needs to be returned by
13  * the method to make it pass.
14  * <name> is a user-displayed name used to identify the test.
15  *
16  * The tests can be driven in two ways:
17  * *) running the program directly: Main() uses reflection to find and invoke
18  *      the test methods (this is useful mostly to check that the tests are correct)
19  * *) with the --regression switch of the jit (this is the preferred way since
20  *      all the tests will be run with optimizations on and off)
21  *
22  * The reflection logic could be moved to a .dll since we need at least another
23  * regression test file written in IL code to have better control on how
24  * the IL code looks.
25  */
26
27 #if __MOBILE__
28 namespace UnalignedTests
29 {
30 #endif
31
32
33 class Tests {
34
35 #if !__MOBILE__
36         public static int Main (string[] args) {
37                 return TestDriver.RunTests (typeof (Tests), args);
38         }
39 #endif
40
41
42         public static unsafe int test_0_ldobj_r4 ()
43         {
44                 byte *ptr = stackalloc byte [32];
45                 float f = (float)123.44f;
46                 *(float*)ptr = (float)f;
47
48                 int expected = *(int*)ptr;
49
50                 Intrinsics.UnalignedStobj<int> (ptr + 1, expected);
51                 /* we can loose some precision due to r4<->r8 conversions */
52                 if (Math.Abs (Intrinsics.UnalignedLdobj<float> (ptr + 1) - f) > 0.01f)
53                         return 1;
54
55                 return 0;
56         }
57
58         public static unsafe int test_0_ldobj_r8 ()
59         {
60                 byte *ptr = stackalloc byte [32];
61                 double f = 34423.44f;
62                 *(double*)ptr = (double)f;
63
64                 long expected = *(long*)ptr;
65
66                 Intrinsics.UnalignedStobj<long> (ptr + 3, expected);
67                 if (Intrinsics.UnalignedLdobj<double> (ptr + 3) != f)
68                         return 1;
69
70                 return 0;
71         }
72
73         public static unsafe int test_0_ldobj ()
74         {
75                 byte *ptr = stackalloc byte [20];
76                 for (int i = 0; i < 20; ++i)
77                         ptr [i] = (byte)i;
78
79
80                 if (Intrinsics.UnalignedLdobj<short> (ptr + 0) != 0x0100)
81                         return 1;
82
83                 if (Intrinsics.UnalignedLdobj<short> (ptr + 1) != 0x0201)
84                         return 2;
85
86                 if (Intrinsics.UnalignedLdobj<short> (ptr + 2) != 0x0302)
87                         return 3;
88
89                 if (Intrinsics.UnalignedLdobj<int> (ptr + 1) != 0x04030201)
90                         return 4;
91
92                 if (Intrinsics.UnalignedLdobj<int> (ptr + 2) != 0x05040302)
93                         return 5;
94
95                 if (Intrinsics.UnalignedLdobj<long> (ptr + 1) != 0x0807060504030201)
96                         return 6;
97
98                 if (Intrinsics.UnalignedLdobj<long> (ptr + 6) != 0xD0C0B0A09080706)
99                         return 7;
100
101                 return 0;
102         }
103
104         public static unsafe int test_0_ldind ()
105         {
106                 byte *ptr = stackalloc byte [20];
107                 for (int i = 0; i < 20; ++i)
108                         ptr [i] = (byte)i;
109
110
111                 if (Intrinsics.UnalignedLdInd2 (ptr + 0) != 0x0100)
112                         return 1;
113
114                 if (Intrinsics.UnalignedLdInd2 (ptr + 1) != 0x0201)
115                         return 2;
116
117                 if (Intrinsics.UnalignedLdInd2 (ptr + 2) != 0x0302)
118                         return 3;
119
120                 if (Intrinsics.UnalignedLdInd4 (ptr + 1) != 0x04030201)
121                         return 4;
122
123                 if (Intrinsics.UnalignedLdInd4 (ptr + 2) != 0x05040302)
124                         return 5;
125
126                 if (Intrinsics.UnalignedLdInd8 (ptr + 1) != 0x0807060504030201)
127                         return 6;
128
129                 if (Intrinsics.UnalignedLdInd8 (ptr + 6) != 0xD0C0B0A09080706)
130                         return 7;
131
132                 return 0;
133         }
134         public static unsafe int test_0_cpobj ()
135         {
136                 byte *dest = stackalloc byte [20];
137                 byte *src = stackalloc byte [20];
138                 for (int i = 0; i < 20; ++i)
139                         src [i] = (byte)i;
140
141                 Intrinsics.UnalignedCpobj<short> (dest + 0, src + 0);
142                 if (dest [0] != src [0] || dest [1] != src [1])
143                         return 1;
144
145                 Intrinsics.UnalignedCpobj<short> (dest + 1, src + 0);
146                 if (dest [1] != src [0] || dest [2] != src [1])
147                         return 2;
148
149                 Intrinsics.UnalignedCpobj<short> (dest + 0, src + 1);
150                 if (dest [0] != src [1] || dest [1] != src [2])
151                         return 3;
152
153                 Intrinsics.UnalignedCpobj<short> (dest + 1, src + 1);
154                 if (dest [1] != src [1] || dest [2] != src [2])
155                         return 3;
156
157                 Intrinsics.UnalignedCpobj<int> (dest + 3, src);
158                 for (int i = 0; i < 4; ++i) {
159                         if (dest [i + 3] != src [i])
160                                 return 4;
161                 }
162
163                 Intrinsics.UnalignedCpobj<int> (dest + 1, src + 2);
164                 for (int i = 0; i < 4; ++i) {
165                         if (dest [i + 1] != src [i + 2])
166                                 return 5;
167                 }
168
169                 Intrinsics.UnalignedCpobj<long> (dest + 1, src + 2);
170                 for (int i = 0; i < 8; ++i) {
171                         if (dest [i + 1] != src [i + 2])
172                                 return 6;
173                 }
174
175                 Intrinsics.UnalignedCpobj<long> (dest + 7, src + 2);
176                 for (int i = 0; i < 8; ++i) {
177                         if (dest [i + 7] != src [i + 2])
178                                 return 7;
179                 }
180
181                 return 0;
182         }
183
184         public static unsafe int test_0_stobj ()
185         {
186                 byte *ptr = stackalloc byte [20];
187
188                 Intrinsics.UnalignedStobj <short> (ptr + 0, 0x6688);
189                 if (ptr [0] != 0x88 || ptr [1] != 0x66)
190                         return 1;
191
192                 Intrinsics.UnalignedStobj <short> (ptr + 1, 0x6589);
193                 if (ptr [1] != 0x89 || ptr [2] != 0x65)
194                         return 2;
195
196                 Intrinsics.UnalignedStobj <int> (ptr + 1, 0x60708090);
197                 if (ptr [1] != 0x90 || ptr [2] != 0x80 || ptr [3] != 0x70 || ptr [4] != 0x60)
198                         return 3;
199
200                 Intrinsics.UnalignedStobj <long> (ptr + 1, 0x405060708090);
201                 if (ptr [1] != 0x90 || ptr [2] != 0x80 || ptr [3] != 0x70 || ptr [4] != 0x60 || ptr [5] != 0x50 || ptr [6] != 0x40)
202                         return 4;
203
204                 return 0;
205         }
206
207         public static unsafe int test_0_ldobj_stobj ()
208         {
209                 byte *dest = stackalloc byte [20];
210                 byte *src = stackalloc byte [20];
211
212                 for (int i = 0; i < 20; ++i)
213                         src [i] = (byte)i;
214
215                 Intrinsics.UnalignedLdobjStObjPair<short> (dest + 0, src + 0);
216                 if (dest [0] != src [0] || dest [1] != src [1])
217                         return 1;
218
219                 Intrinsics.UnalignedLdobjStObjPair<short> (dest + 1, src + 0);
220                 if (dest [1] != src [0] || dest [2] != src [1])
221                         return 2;
222
223                 Intrinsics.UnalignedLdobjStObjPair<short> (dest + 0, src + 1);
224                 if (dest [0] != src [1] || dest [1] != src [2])
225                         return 3;
226
227                 Intrinsics.UnalignedLdobjStObjPair<short> (dest + 1, src + 1);
228                 if (dest [1] != src [1] || dest [2] != src [2])
229                         return 3;
230
231                 Intrinsics.UnalignedLdobjStObjPair<int> (dest + 1, src + 1);
232                 if (dest [1] != src [1] || dest [2] != src [2])
233                         return 4;
234
235                 Intrinsics.UnalignedLdobjStObjPair<long> (dest + 1, src + 1);
236                 if (dest [1] != src [1] || dest [2] != src [2])
237                         return 5;
238
239
240                 return 0;
241         }
242
243
244         public static unsafe int test_0_cpblk ()
245         {
246                 byte *dest = stackalloc byte [20];
247                 byte *src = stackalloc byte [20];
248                 for (int i = 0; i < 20; ++i)
249                         src [i] = (byte)i;
250
251
252                 Intrinsics.UnalignedCpblk (dest + 0, src + 0, 2);
253                 if (dest [0] != src [0] || dest [1] != src [1])
254                         return 1;
255
256                 Intrinsics.UnalignedCpblk (dest + 1, src + 0, 2);
257                 if (dest [1] != src [0] || dest [2] != src [1])
258                         return 2;
259
260                 Intrinsics.UnalignedCpblk (dest + 0, src + 1, 2);
261                 if (dest [0] != src [1] || dest [1] != src [2])
262                         return 3;
263
264                 Intrinsics.UnalignedCpblk (dest + 1, src + 1, 2);
265                 if (dest [1] != src [1] || dest [2] != src [2])
266                         return 3;
267
268                 Intrinsics.UnalignedCpblk (dest + 1, src + 1, 4);
269                 for (int i = 0; i < 4; ++i) {
270                         if (dest [i + 1] != src [i + 1])
271                                 return 4;
272                 }
273
274                 Intrinsics.UnalignedCpblk (dest + 1, src + 1, 8);
275                 for (int i = 0; i < 8; ++i) {
276                         if (dest [i + 1] != src [i + 1])
277                                 return 5;
278                 }
279
280                 return 0;
281         }
282
283
284         public static unsafe int test_0_initblk ()
285         {
286                 byte *ptr = stackalloc byte [20];
287
288                 for (int i = 0; i < 20; ++i)
289                         ptr [i] = (byte)i;
290
291                 Intrinsics.UnalignedInit (ptr, 30, 2);
292                 if (ptr [0] != 30 || ptr [1] != 30)
293                         return 1;
294
295                 Intrinsics.UnalignedInit (ptr + 1, 31, 2);
296                 if (ptr[0] != 30 || ptr [1] != 31 || ptr [2] != 31)
297                         return 2;
298
299                 return 0;
300         }
301 }
302
303 #if __MOBILE__
304 }
305 #endif
306
307
308