4 * Register allocator tests.
9 public static int Main (String
[] args
) {
10 return TestDriver
.RunTests (typeof (Tests
));
13 static void call_clobber_inner () {
16 public static int test_15_clobber_1 () {
19 for (int i
= 0; i
< 10; ++i
)
21 for (int i
= 0; i
< 5; ++i
)
24 // clob == '1' and dreg == sreg2
29 public static int test_15_clobber_1_fp () {
32 for (int i
= 0; i
< 10; ++i
)
34 for (int i
= 0; i
< 5; ++i
)
37 // clob == '1' and dreg == sreg2
42 public static int test_5_call_clobber () {
43 // A call clobbers some registers so variables in those registers need to be spilled
44 // and later reloaded to a register
48 call_clobber_inner ();
53 static int call_clobber_inner2 () {
57 public static int test_7_call_clobber_dreg () {
58 // A call doesn't clobber its dreg
62 a
= call_clobber_inner2 ();
67 public static int test_9_spill_if_then_else () {
68 // Spilling variables in one branch of an if-then-else
74 call_clobber_inner ();
80 public static int test_3_spill_reload_if_then_else () {
81 // Spilling and reloading variables in one branch of an if-then-else
88 call_clobber_inner ();
95 public static int test_5_spill_loop () {
98 for (i
= 0; i
< 5; ++i
)
99 call_clobber_inner ();
104 public unsafe static int test_0_volatile () {
124 public unsafe static int test_0_volatile_unused () {
134 public unsafe static int test_0_volatile_unused_2 () {
145 static int ref_int (int i
, ref int b
, int j
) {
151 public static int test_0_volatile_unused_3 () {
152 // b's def has no use so its interval is split at a position not covered by the interval
154 if (ref_int (99, ref b
, 100) != 42)
157 if (ref_int (99, ref b
, 100) != 43)
164 static int ref_bool (int i
, ref bool b1
, ref bool b2
, ref bool b3
) {
172 public static int test_0_volatile_regress_1 () {
173 // Spill stores should precede spill loads at a given position
174 for (int i
= 0; i
< 8; i
++) {
175 bool b1
= (i
& 4) != 0;
176 bool b2
= (i
& 2) != 0;
177 bool b3
= (i
& 1) != 0;
178 bool orig_b1
= b1
, orig_b2
= b2
, orig_b3
= b3
;
179 if (ref_bool(i
, ref b1
, ref b2
, ref b3
) != 0)
192 static int decode_len (out int pos
) {
197 static void clobber_all (int pos
) {
198 for (int i
= 0; i
< 10; ++i
)
199 for (int j
= 0; j
< 10; ++j
)
200 for (int k
= 0; k
< 10; ++k
)
201 for (int l
= 0; l
< 10; ++l
)
205 public static int test_29_volatile_regress_2 () {
208 int len
= decode_len (out pos
);
209 call_clobber_inner ();
216 public static int test_0_clobber_regress_1 () {
217 object[] a11
= new object [10];
218 object o
= new Object ();
219 // A spill load is inserted before the backward branch, clobbering one of the
220 // registers used in the comparison
221 for (int i
= 0; i
< 10; ++i
)
227 static int return_arg (int i
) {
231 public static int test_0_spill_regress_1 () {
233 for (int i
= 0; i
< 3; i
++) {
234 // i is spilled by the call, then reloaded for the loop check
235 // make sure the move from its first reg to its second is inserted in the
236 // if body bblock, not the for body bblock
239 if (return_arg (j
) != 5)
247 public static int test_0_spill_regress_2 () {
248 double[] temporaries
= new double[3];
249 for (int i
= 0; i
< 3; i
++) {
250 // i and temporaries are spilled by the call, then reloaded after the call
251 // make sure the two moves inserted in the if bblock are in the proper order
254 temporaries
[i
] = return_arg (i
);
261 static int many_args_unused (int i
, int j
, int k
, int l
, int m
, int n
, int p
, int q
) {
265 public static int test_0_unused_args () {
266 return many_args_unused (0, 1, 2, 3, 4, 5, 6, 7);
269 public unsafe void ClearBuffer (byte *buffer
, int i
) {
271 byte *b
= stackalloc byte [4];
274 public unsafe bool instance_method_1 (string s
, string target
, int start
, int length
, int opt
) {
275 byte* alwaysMatchFlags
= stackalloc byte [16];
276 byte* neverMatchFlags
= stackalloc byte [16];
277 byte* targetSortKey
= stackalloc byte [4];
278 byte* sk1
= stackalloc byte [4];
279 byte* sk2
= stackalloc byte [4];
280 ClearBuffer (alwaysMatchFlags
, 16);
281 ClearBuffer (neverMatchFlags
, 16);
282 ClearBuffer (targetSortKey
, 4);
283 ClearBuffer (sk1
, 4);
284 ClearBuffer (sk2
, 4);
286 return this == null && s
== target
&& start
== length
&& length
== opt
&& alwaysMatchFlags
== neverMatchFlags
&& neverMatchFlags
== targetSortKey
&& sk1
== sk2
;
289 public static int test_0_spill_regress_3 () {
290 new Tests ().instance_method_1 (null, null, 0, 0, 0);
294 unsafe bool MatchesBackward (string s
, ref int idx
, int end
, int orgStart
, int ti
, byte* sortkey
, bool noLv4
, ref object ctx
) {
296 byte *b
= stackalloc byte [4];
299 throw new Exception ();
305 unsafe int LastIndexOfSortKey (string s
, int start
, int orgStart
, int length
, byte* sortkey
, int ti
, bool noLv4
, ref object ctx
)
307 // ctx is initially allocated to the stack, when it is reloaded before the call,
308 // %rax is spilled to free up the register, then ctx is allocated to %rax for its
309 // whole lifetime, but %rax is not available for this since it is clobbered by the
311 int end
= start
- length
;
315 if (MatchesBackward (s
, ref idx
, end
, orgStart
,
316 ti
, sortkey
, noLv4
, ref ctx
))
322 public unsafe static int test_0_spill_regress_4 () {
323 object o
= new Object ();
324 new Tests ().LastIndexOfSortKey ("", 10, 0, 5, null, 0, false, ref o
);
329 public static bool IsEqual (Type type
, Type base_type
) {
330 return (type
.GetHashCode () == base_type
.GetHashCode ());
333 public static bool IsNestedFamilyAccessible (Type type
, Type base_type
)
336 if (IsEqual (type
, base_type
))
339 type
= type
.DeclaringType
;
340 } while (type
!= null);
345 public static int test_0_do_while_critical_edges () {
346 IsNestedFamilyAccessible (typeof (int), typeof (object));
351 public static string return_string (string s
) {
352 for (int i
= 0; i
< 1000; ++i
)
357 public static int test_0_switch_critical_edges () {
358 // A spill load is inserted at the end of the bblock containing the OP_BR_REG,
359 // overwriting the source reg of the OP_BR_REG. The edge is not really
360 // a critical edge, since its source bblock only has 1 exit, but it must
361 // be treated as such.
362 for (int i
=0; i
< UInt16
.MaxValue
; i
++) {
363 Char c
= Convert
.ToChar (i
);
373 //Console.WriteLine ((i.ToString () + (int)c));
374 return_string ((i
.ToString () + (int)c
));