Merge pull request #5714 from alexischr/update_bockbuild
[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
74         public static unsafe int test_0_ldobj ()
75         {
76                 byte *ptr = stackalloc byte [20];
77                 for (int i = 0; i < 20; ++i)
78                         ptr [i] = (byte)i;
79
80                 if (BitConverter.IsLittleEndian) {
81
82                         if (Intrinsics.UnalignedLdobj<short> (ptr + 0) != 0x0100)
83                                 return 1;
84
85                         if (Intrinsics.UnalignedLdobj<short> (ptr + 1) != 0x0201)
86                                 return 2;
87
88                         if (Intrinsics.UnalignedLdobj<short> (ptr + 2) != 0x0302)
89                                 return 3;
90
91                         if (Intrinsics.UnalignedLdobj<int> (ptr + 1) != 0x04030201)
92                                 return 4;
93
94                         if (Intrinsics.UnalignedLdobj<int> (ptr + 2) != 0x05040302)
95                                 return 5;
96
97                         if (Intrinsics.UnalignedLdobj<long> (ptr + 1) != 0x0807060504030201)
98                                 return 6;
99
100                         if (Intrinsics.UnalignedLdobj<long> (ptr + 6) != 0xD0C0B0A09080706)
101                                 return 7;
102                 } else {
103
104                         if (Intrinsics.UnalignedLdobj<short> (ptr + 0) != 0x0001)
105                                 return 1;
106
107                         if (Intrinsics.UnalignedLdobj<short> (ptr + 1) != 0x0102)
108                                 return 2;
109
110                         if (Intrinsics.UnalignedLdobj<short> (ptr + 2) != 0x0203)
111                                 return 3;
112
113                         if (Intrinsics.UnalignedLdobj<int> (ptr + 1) != 0x01020304)
114                                 return 4;
115
116                         if (Intrinsics.UnalignedLdobj<int> (ptr + 2) != 0x02030405)
117                                 return 5;
118
119                         if (Intrinsics.UnalignedLdobj<long> (ptr + 1) != 0x0102030405060708)
120                                 return 6;
121
122                         if (Intrinsics.UnalignedLdobj<long> (ptr + 6) != 0x60708090A0B0C0D)
123                                 return 7;
124                 }
125
126                 return 0;
127         }
128
129         public static unsafe int test_0_ldind ()
130         {
131                 byte *ptr = stackalloc byte [20];
132                 for (int i = 0; i < 20; ++i)
133                         ptr [i] = (byte)i;
134
135
136                 if (BitConverter.IsLittleEndian) {
137
138                         if (Intrinsics.UnalignedLdInd2 (ptr + 0) != 0x0100)
139                                 return 1;
140
141                         if (Intrinsics.UnalignedLdInd2 (ptr + 1) != 0x0201)
142                                 return 2;
143
144                         if (Intrinsics.UnalignedLdInd2 (ptr + 2) != 0x0302)
145                                 return 3;
146
147                         if (Intrinsics.UnalignedLdInd4 (ptr + 1) != 0x04030201)
148                                 return 4;
149
150                         if (Intrinsics.UnalignedLdInd4 (ptr + 2) != 0x05040302)
151                                 return 5;
152
153                         if (Intrinsics.UnalignedLdInd8 (ptr + 1) != 0x0807060504030201)
154                                 return 6;
155
156                         if (Intrinsics.UnalignedLdInd8 (ptr + 6) != 0xD0C0B0A09080706)
157                                 return 7;
158                 } else {
159
160                         if (Intrinsics.UnalignedLdInd2 (ptr + 0) != 0x0001)
161                                 return 1;
162
163                         if (Intrinsics.UnalignedLdInd2 (ptr + 1) != 0x0102)
164                                 return 2;
165
166                         if (Intrinsics.UnalignedLdInd2 (ptr + 2) != 0x0203)
167                                 return 3;
168
169                         if (Intrinsics.UnalignedLdInd4 (ptr + 1) != 0x01020304)
170                                 return 4;
171
172                         if (Intrinsics.UnalignedLdInd4 (ptr + 2) != 0x02030405)
173                                 return 5;
174
175                         if (Intrinsics.UnalignedLdInd8 (ptr + 1) != 0x0102030405060708)
176                                 return 6;
177
178                         if (Intrinsics.UnalignedLdInd8 (ptr + 6) != 0x60708090A0B0C0D)
179                                 return 7;
180                 }
181
182                 return 0;
183         }
184         public static unsafe int test_0_cpobj ()
185         {
186                 byte *dest = stackalloc byte [20];
187                 byte *src = stackalloc byte [20];
188                 for (int i = 0; i < 20; ++i)
189                         src [i] = (byte)i;
190
191                 Intrinsics.UnalignedCpobj<short> (dest + 0, src + 0);
192                 if (dest [0] != src [0] || dest [1] != src [1])
193                         return 1;
194
195                 Intrinsics.UnalignedCpobj<short> (dest + 1, src + 0);
196                 if (dest [1] != src [0] || dest [2] != src [1])
197                         return 2;
198
199                 Intrinsics.UnalignedCpobj<short> (dest + 0, src + 1);
200                 if (dest [0] != src [1] || dest [1] != src [2])
201                         return 3;
202
203                 Intrinsics.UnalignedCpobj<short> (dest + 1, src + 1);
204                 if (dest [1] != src [1] || dest [2] != src [2])
205                         return 3;
206
207                 Intrinsics.UnalignedCpobj<int> (dest + 3, src);
208                 for (int i = 0; i < 4; ++i) {
209                         if (dest [i + 3] != src [i])
210                                 return 4;
211                 }
212
213                 Intrinsics.UnalignedCpobj<int> (dest + 1, src + 2);
214                 for (int i = 0; i < 4; ++i) {
215                         if (dest [i + 1] != src [i + 2])
216                                 return 5;
217                 }
218
219                 Intrinsics.UnalignedCpobj<long> (dest + 1, src + 2);
220                 for (int i = 0; i < 8; ++i) {
221                         if (dest [i + 1] != src [i + 2])
222                                 return 6;
223                 }
224
225                 Intrinsics.UnalignedCpobj<long> (dest + 7, src + 2);
226                 for (int i = 0; i < 8; ++i) {
227                         if (dest [i + 7] != src [i + 2])
228                                 return 7;
229                 }
230
231                 return 0;
232         }
233
234         public static unsafe int test_0_stobj ()
235         {
236                 byte *ptr = stackalloc byte [20];
237
238                 if (BitConverter.IsLittleEndian) {
239                         Intrinsics.UnalignedStobj <short> (ptr + 0, 0x6688);
240                         if (ptr [0] != 0x88 || ptr [1] != 0x66)
241                                 return 1;
242
243                         Intrinsics.UnalignedStobj <short> (ptr + 1, 0x6589);
244                         if (ptr [1] != 0x89 || ptr [2] != 0x65)
245                                 return 2;
246
247                         Intrinsics.UnalignedStobj <int> (ptr + 1, 0x60708090);
248                         if (ptr [1] != 0x90 || ptr [2] != 0x80 || ptr [3] != 0x70 || ptr [4] != 0x60)
249                                 return 3;
250
251                         Intrinsics.UnalignedStobj <long> (ptr + 1, 0x405060708090);
252                         if (ptr [1] != 0x90 || ptr [2] != 0x80 || ptr [3] != 0x70 || 
253                             ptr [4] != 0x60 || ptr [5] != 0x50 || ptr [6] != 0x40)
254                                 return 4;
255                 } else {
256                         Intrinsics.UnalignedStobj <short> (ptr + 0, 0x6688);
257                         if (ptr [0] != 0x66 || ptr [1] != 0x88)
258                                 return 1;
259
260                         Intrinsics.UnalignedStobj <short> (ptr + 1, 0x6589);
261                         if (ptr [1] != 0x65 || ptr [2] != 0x89)
262                                 return 2;
263
264                         Intrinsics.UnalignedStobj <int> (ptr + 1, 0x60708090);
265                         if (ptr [1] != 0x60 || ptr [2] != 0x70 || ptr [3] != 0x80 || ptr [4] != 0x90)
266                                 return 3;
267
268                         Intrinsics.UnalignedStobj <long> (ptr + 1, 0x2030405060708090);
269                         if (ptr [1] != 0x20 || ptr [2] != 0x30 || ptr [3] != 0x40 || 
270                             ptr [4] != 0x50 || ptr [5] != 0x60 || ptr [6] != 0x70)
271                                 return 4;
272                 }
273
274                 return 0;
275         }
276
277         public static unsafe int test_0_ldobj_stobj ()
278         {
279                 byte *dest = stackalloc byte [20];
280                 byte *src = stackalloc byte [20];
281
282                 for (int i = 0; i < 20; ++i)
283                         src [i] = (byte)i;
284
285                 Intrinsics.UnalignedLdobjStObjPair<short> (dest + 0, src + 0);
286                 if (dest [0] != src [0] || dest [1] != src [1])
287                         return 1;
288
289                 Intrinsics.UnalignedLdobjStObjPair<short> (dest + 1, src + 0);
290                 if (dest [1] != src [0] || dest [2] != src [1])
291                         return 2;
292
293                 Intrinsics.UnalignedLdobjStObjPair<short> (dest + 0, src + 1);
294                 if (dest [0] != src [1] || dest [1] != src [2])
295                         return 3;
296
297                 Intrinsics.UnalignedLdobjStObjPair<short> (dest + 1, src + 1);
298                 if (dest [1] != src [1] || dest [2] != src [2])
299                         return 3;
300
301                 Intrinsics.UnalignedLdobjStObjPair<int> (dest + 1, src + 1);
302                 if (dest [1] != src [1] || dest [2] != src [2])
303                         return 4;
304
305                 Intrinsics.UnalignedLdobjStObjPair<long> (dest + 1, src + 1);
306                 if (dest [1] != src [1] || dest [2] != src [2])
307                         return 5;
308
309
310                 return 0;
311         }
312
313
314         public static unsafe int test_0_cpblk ()
315         {
316                 byte *dest = stackalloc byte [20];
317                 byte *src = stackalloc byte [20];
318                 for (int i = 0; i < 20; ++i)
319                         src [i] = (byte)i;
320
321
322                 Intrinsics.UnalignedCpblk (dest + 0, src + 0, 2);
323                 if (dest [0] != src [0] || dest [1] != src [1])
324                         return 1;
325
326                 Intrinsics.UnalignedCpblk (dest + 1, src + 0, 2);
327                 if (dest [1] != src [0] || dest [2] != src [1])
328                         return 2;
329
330                 Intrinsics.UnalignedCpblk (dest + 0, src + 1, 2);
331                 if (dest [0] != src [1] || dest [1] != src [2])
332                         return 3;
333
334                 Intrinsics.UnalignedCpblk (dest + 1, src + 1, 2);
335                 if (dest [1] != src [1] || dest [2] != src [2])
336                         return 3;
337
338                 Intrinsics.UnalignedCpblk (dest + 1, src + 1, 4);
339                 for (int i = 0; i < 4; ++i) {
340                         if (dest [i + 1] != src [i + 1])
341                                 return 4;
342                 }
343
344                 Intrinsics.UnalignedCpblk (dest + 1, src + 1, 8);
345                 for (int i = 0; i < 8; ++i) {
346                         if (dest [i + 1] != src [i + 1])
347                                 return 5;
348                 }
349
350                 return 0;
351         }
352
353
354         public static unsafe int test_0_initblk ()
355         {
356                 byte *ptr = stackalloc byte [20];
357
358                 for (int i = 0; i < 20; ++i)
359                         ptr [i] = (byte)i;
360
361                 Intrinsics.UnalignedInit (ptr, 30, 2);
362                 if (ptr [0] != 30 || ptr [1] != 30)
363                         return 1;
364
365                 Intrinsics.UnalignedInit (ptr + 1, 31, 2);
366                 if (ptr[0] != 30 || ptr [1] != 31 || ptr [2] != 31)
367                         return 2;
368
369                 return 0;
370         }
371 }
372
373 #if __MOBILE__
374 }
375 #endif
376
377
378