1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /**
18  * Test switch() blocks
19  */
20 public class Main {
21     /// CHECK-START: void Main.$noinline$packedSwitch(int) builder (after)
22     /// CHECK: PackedSwitch
23     // Simple packed-switch.
$noinline$packedSwitch(int value)24     public static void $noinline$packedSwitch(int value) {
25         switch (value) {
26             case 0:
27                 System.out.println("0"); break;
28             case 1:
29                 System.out.println("1"); break;
30             case 2:
31                 System.out.println("2"); break;
32             case 3:
33                 System.out.println("3"); break;
34             case 4:
35                 System.out.println("4"); break;
36             default:
37                 System.out.println("default"); break;
38         }
39     }
40 
41     /// CHECK-START: void Main.$noinline$packedSwitch2(int) builder (after)
42     /// CHECK: PackedSwitch
43     // Simple packed-switch starting at a negative index.
$noinline$packedSwitch2(int value)44     public static void $noinline$packedSwitch2(int value) {
45         switch (value) {
46             case -3:
47                 System.out.println("-3"); break;
48             case -2:
49                 System.out.println("-2"); break;
50             case -1:
51                 System.out.println("-1"); break;
52             case 0:
53                 System.out.println("0"); break;
54             case 1:
55                 System.out.println("1"); break;
56             case 2:
57                 System.out.println("2"); break;
58             default:
59                 System.out.println("default"); break;
60         }
61     }
62 
63     /// CHECK-START: void Main.$noinline$packedSwitch3(int) builder (after)
64     /// CHECK: PackedSwitch
65     // Simple packed-switch starting above 0.
$noinline$packedSwitch3(int value)66     public static void $noinline$packedSwitch3(int value) {
67         switch (value) {
68             case 2:
69                 System.out.println("2"); break;
70             case 3:
71                 System.out.println("3"); break;
72             case 4:
73                 System.out.println("4"); break;
74             case 5:
75                 System.out.println("5"); break;
76             case 6:
77                 System.out.println("6"); break;
78             default:
79                 System.out.println("default"); break;
80         }
81     }
82 
83     /// CHECK-START: void Main.$noinline$packedSwitch4(int) builder (after)
84     /// CHECK: PackedSwitch
85     // Simple packed-switch going up to max_int.
$noinline$packedSwitch4(int value)86     public static void $noinline$packedSwitch4(int value) {
87         switch (value) {
88             case Integer.MAX_VALUE - 3:
89                 System.out.println(Integer.MAX_VALUE - 3); break;
90             case Integer.MAX_VALUE - 2:
91                 System.out.println(Integer.MAX_VALUE - 2); break;
92             case Integer.MAX_VALUE - 1:
93                 System.out.println(Integer.MAX_VALUE - 1); break;
94             case Integer.MAX_VALUE:
95                 System.out.println(Integer.MAX_VALUE); break;
96             default:
97                 System.out.println("default"); break;
98         }
99     }
100 
101     /// CHECK-START: void Main.$noinline$packedSwitch5(int) builder (after)
102     /// CHECK: PackedSwitch
103     // Simple packed-switch starting at min_int.
$noinline$packedSwitch5(int value)104     public static void $noinline$packedSwitch5(int value) {
105         switch (value) {
106             case Integer.MIN_VALUE:
107                 System.out.println(Integer.MIN_VALUE); break;
108             case Integer.MIN_VALUE + 1:
109                 System.out.println(Integer.MIN_VALUE + 1); break;
110             case Integer.MIN_VALUE + 2:
111                 System.out.println(Integer.MIN_VALUE + 2); break;
112             case Integer.MIN_VALUE + 3:
113                 System.out.println(Integer.MIN_VALUE + 3); break;
114             default:
115                 System.out.println("default"); break;
116         }
117     }
118 
119     /// CHECK-START: long Main.$noinline$packedSwitch7(int) builder (after)
120     /// CHECK: PackedSwitch
121     // Long packed-switch that might lead to not creating chained-ifs.
$noinline$packedSwitch7(int value)122     public static long $noinline$packedSwitch7(int value) {
123         switch (value) {
124             case 1:
125                 System.out.println(1); break;
126             case 2:
127                 System.out.println(2); break;
128             case 3:
129                 System.out.println(3); break;
130             case 4:
131                 System.out.println(4); break;
132             case 5:
133                 System.out.println(5); break;
134             case 6:
135                 System.out.println(6); break;
136             case 7:
137                 System.out.println(7); break;
138             case 8:
139                 System.out.println(8); break;
140             case 9:
141                 System.out.println(9); break;
142             case 10:
143                 System.out.println(10); break;
144             case 11:
145                 System.out.println(11); break;
146             case 12:
147                 System.out.println(12); break;
148             case 13:
149                 System.out.println(13); break;
150             case 14:
151                 System.out.println(14); break;
152             case 15:
153                 System.out.println(15); break;
154             default:
155                 System.out.println("default"); break;
156         }
157 
158         // Jump tables previously were emitted in the end of the method code buffer. The
159         // following boilerplate code aims to fill the emitted code buffer extensively
160         // and check that even for big method jump table is correctly emitted, its address
161         // is within a range of corresponded pc-relative instructions (this applies to
162         // ARM mainly).
163         long temp = value;
164         temp = Long.rotateLeft(temp, value);
165         temp = Long.rotateLeft(temp, value);
166         temp = Long.rotateLeft(temp, value);
167         temp = Long.rotateLeft(temp, value);
168         temp = Long.rotateLeft(temp, value);
169         temp = Long.rotateLeft(temp, value);
170         temp = Long.rotateLeft(temp, value);
171         temp = Long.rotateLeft(temp, value);
172         temp = Long.rotateLeft(temp, value);
173         temp = Long.rotateLeft(temp, value);
174         temp = Long.rotateLeft(temp, value);
175         temp = Long.rotateLeft(temp, value);
176         temp = Long.rotateLeft(temp, value);
177         temp = Long.rotateLeft(temp, value);
178         temp = Long.rotateLeft(temp, value);
179         temp = Long.rotateLeft(temp, value);
180         temp = Long.rotateLeft(temp, value);
181         temp = Long.rotateLeft(temp, value);
182         temp = Long.rotateLeft(temp, value);
183         temp = Long.rotateLeft(temp, value);
184         temp = Long.rotateLeft(temp, value);
185         temp = Long.rotateLeft(temp, value);
186         temp = Long.rotateLeft(temp, value);
187         temp = Long.rotateLeft(temp, value);
188         temp = Long.rotateLeft(temp, value);
189         temp = Long.rotateLeft(temp, value);
190         temp = Long.rotateLeft(temp, value);
191         temp = Long.rotateLeft(temp, value);
192         temp = Long.rotateLeft(temp, value);
193         temp = Long.rotateLeft(temp, value);
194         temp = Long.rotateLeft(temp, value);
195         temp = Long.rotateLeft(temp, value);
196         temp = Long.rotateLeft(temp, value);
197         temp = Long.rotateLeft(temp, value);
198         temp = Long.rotateLeft(temp, value);
199         temp = Long.rotateLeft(temp, value);
200         temp = Long.rotateLeft(temp, value);
201         temp = Long.rotateLeft(temp, value);
202         temp = Long.rotateLeft(temp, value);
203         temp = Long.rotateLeft(temp, value);
204         temp = Long.rotateLeft(temp, value);
205         temp = Long.rotateLeft(temp, value);
206         temp = Long.rotateLeft(temp, value);
207         temp = Long.rotateLeft(temp, value);
208         temp = Long.rotateLeft(temp, value);
209         temp = Long.rotateLeft(temp, value);
210         temp = Long.rotateLeft(temp, value);
211         temp = Long.rotateLeft(temp, value);
212         temp = Long.rotateLeft(temp, value);
213         temp = Long.rotateLeft(temp, value);
214         temp = Long.rotateLeft(temp, value);
215         temp = Long.rotateLeft(temp, value);
216         temp = Long.rotateLeft(temp, value);
217         temp = Long.rotateLeft(temp, value);
218         temp = Long.rotateLeft(temp, value);
219         temp = Long.rotateLeft(temp, value);
220         temp = Long.rotateLeft(temp, value);
221         temp = Long.rotateLeft(temp, value);
222         temp = Long.rotateLeft(temp, value);
223         temp = Long.rotateLeft(temp, value);
224         temp = Long.rotateLeft(temp, value);
225         temp = Long.rotateLeft(temp, value);
226         temp = Long.rotateLeft(temp, value);
227         temp = Long.rotateLeft(temp, value);
228         temp = Long.rotateLeft(temp, value);
229         temp = Long.rotateLeft(temp, value);
230         temp = Long.rotateLeft(temp, value);
231         temp = Long.rotateLeft(temp, value);
232         temp = Long.rotateLeft(temp, value);
233         temp = Long.rotateLeft(temp, value);
234         temp = Long.rotateLeft(temp, value);
235         temp = Long.rotateLeft(temp, value);
236         temp = Long.rotateLeft(temp, value);
237         temp = Long.rotateLeft(temp, value);
238         temp = Long.rotateLeft(temp, value);
239         temp = Long.rotateLeft(temp, value);
240         temp = Long.rotateLeft(temp, value);
241         temp = Long.rotateLeft(temp, value);
242         temp = Long.rotateLeft(temp, value);
243         temp = Long.rotateLeft(temp, value);
244         temp = Long.rotateLeft(temp, value);
245         temp = Long.rotateLeft(temp, value);
246         temp = Long.rotateLeft(temp, value);
247         temp = Long.rotateLeft(temp, value);
248         temp = Long.rotateLeft(temp, value);
249         temp = Long.rotateLeft(temp, value);
250         temp = Long.rotateLeft(temp, value);
251         temp = Long.rotateLeft(temp, value);
252         temp = Long.rotateLeft(temp, value);
253         temp = Long.rotateLeft(temp, value);
254         temp = Long.rotateLeft(temp, value);
255         temp = Long.rotateLeft(temp, value);
256         temp = Long.rotateLeft(temp, value);
257         temp = Long.rotateLeft(temp, value);
258         temp = Long.rotateLeft(temp, value);
259         temp = Long.rotateLeft(temp, value);
260         temp = Long.rotateLeft(temp, value);
261         temp = Long.rotateLeft(temp, value);
262 
263         return temp;
264     }
265 
266     /// CHECK-START: void Main.$noinline$sparseSwitch(int) builder (after)
267     /// CHECK-NOT: PackedSwitch
268     // Sparse switch, just leave a large gap.
$noinline$sparseSwitch(int value)269     public static void $noinline$sparseSwitch(int value) {
270         switch (value) {
271             case 0:
272                 System.out.println("0"); break;
273             case 1:
274                 System.out.println("1"); break;
275             case 2:
276                 System.out.println("2"); break;
277             case Integer.MAX_VALUE:
278                 System.out.println(Integer.MAX_VALUE); break;
279             default:
280                 System.out.println("default"); break;
281         }
282     }
283 
284     /// CHECK-START: void Main.$noinline$sparseSwitch2(int) builder (after)
285     /// CHECK-NOT: PackedSwitch
286     // Simple sparse-switch starting at a negative index.
$noinline$sparseSwitch2(int value)287     public static void $noinline$sparseSwitch2(int value) {
288         switch (value) {
289             case -3:
290                 System.out.println("-3"); break;
291             case -2:
292                 System.out.println("-2"); break;
293             case -1:
294                 System.out.println("-1"); break;
295             case 0:
296                 System.out.println("0"); break;
297             case Integer.MAX_VALUE:
298                 System.out.println(Integer.MAX_VALUE); break;
299             default:
300                 System.out.println("default"); break;
301         }
302     }
303 
304     /// CHECK-START: void Main.$noinline$sparseSwitch3(int) builder (after)
305     /// CHECK-NOT: PackedSwitch
306     // Simple sparse-switch starting above 0.
$noinline$sparseSwitch3(int value)307     public static void $noinline$sparseSwitch3(int value) {
308         switch (value) {
309             case 2:
310                 System.out.println("2"); break;
311             case 4:
312                 System.out.println("4"); break;
313             case 5:
314                 System.out.println("5"); break;
315             case Integer.MAX_VALUE:
316                 System.out.println(Integer.MAX_VALUE); break;
317             default:
318                 System.out.println("default"); break;
319         }
320     }
321 
322     /// CHECK-START: void Main.$noinline$sparseSwitch4(int) builder (after)
323     /// CHECK-NOT: PackedSwitch
324     // Simple sparse-switch going up to max_int.
$noinline$sparseSwitch4(int value)325     public static void $noinline$sparseSwitch4(int value) {
326         switch (value) {
327             case Integer.MIN_VALUE:
328                 System.out.println(Integer.MIN_VALUE); break;
329             case Integer.MAX_VALUE - 2:
330                 System.out.println(Integer.MAX_VALUE - 2); break;
331             case Integer.MAX_VALUE - 1:
332                 System.out.println(Integer.MAX_VALUE - 1); break;
333             case Integer.MAX_VALUE:
334                 System.out.println(Integer.MAX_VALUE); break;
335             default:
336                 System.out.println("default"); break;
337         }
338     }
339 
340     /// CHECK-START: void Main.$noinline$sparseSwitch5(int) builder (after)
341     /// CHECK-NOT: PackedSwitch
342     // Simple sparse-switch starting at min_int.
$noinline$sparseSwitch5(int value)343     public static void $noinline$sparseSwitch5(int value) {
344         switch (value) {
345             case Integer.MIN_VALUE:
346                 System.out.println(Integer.MIN_VALUE); break;
347             case Integer.MIN_VALUE + 2:
348                 System.out.println(Integer.MIN_VALUE + 2); break;
349             default:
350                 System.out.println("default"); break;
351         }
352     }
353 
354     /// CHECK-START: void Main.$noinline$sparseSwitch6(int) builder (after)
355     /// CHECK-NOT: PackedSwitch
356     // Simple switch with only min_int. It is sparse since it has less than kSmallSwitchThreshold
357     // values.
$noinline$sparseSwitch6(int value)358     public static void $noinline$sparseSwitch6(int value) {
359         switch (value) {
360             case Integer.MIN_VALUE:
361                 System.out.println(Integer.MIN_VALUE); break;
362             default:
363                 System.out.println("default"); break;
364         }
365     }
366 
367     /// CHECK-START: void Main.$noinline$sparseSwitch7(int) builder (after)
368     /// CHECK-NOT: PackedSwitch
369     // Long sparse-switch that might lead to not creating chained-ifs.
$noinline$sparseSwitch7(int value)370     public static void $noinline$sparseSwitch7(int value) {
371         switch (value) {
372             case 1:
373                 System.out.println(1); break;
374             case 2:
375                 System.out.println(2); break;
376             case 4:
377                 System.out.println(4); break;
378             case 5:
379                 System.out.println(5); break;
380             case 15:
381                 System.out.println(15); break;
382             default:
383                 System.out.println("default"); break;
384         }
385     }
386 
main(String args[])387     public static void main(String args[]) {
388         System.out.println("packed");
389         for (int i = -2; i < 3; i++) {
390             $noinline$packedSwitch(i);
391         }
392         $noinline$packedSwitch(Integer.MIN_VALUE);
393         $noinline$packedSwitch(Integer.MAX_VALUE);
394 
395         System.out.println("packed2");
396         for (int i = -2; i < 3; i++) {
397             $noinline$packedSwitch2(i);
398         }
399         $noinline$packedSwitch2(Integer.MIN_VALUE);
400         $noinline$packedSwitch2(Integer.MAX_VALUE);
401 
402         System.out.println("packed3");
403         for (int i = -2; i < 7; i++) {
404             $noinline$packedSwitch3(i);
405         }
406         $noinline$packedSwitch3(Integer.MIN_VALUE);
407         $noinline$packedSwitch3(Integer.MAX_VALUE);
408 
409         System.out.println("packed4");
410         for (int i = Integer.MAX_VALUE - 4; i > 0; i++) {
411             $noinline$packedSwitch4(i);
412         }
413         $noinline$packedSwitch4(Integer.MIN_VALUE);
414 
415         System.out.println("packed5");
416         for (int i = Integer.MIN_VALUE; i < Integer.MIN_VALUE + 4; i++) {
417             $noinline$packedSwitch5(i);
418         }
419         $noinline$packedSwitch5(Integer.MAX_VALUE);
420 
421         System.out.println("packed7");
422         for (int i = -1; i < 17; i++) {
423             $noinline$packedSwitch7(i);
424         }
425 
426 
427         System.out.println("sparse");
428         for (int i = -2; i < 4; i++) {
429             $noinline$sparseSwitch(i);
430         }
431         $noinline$sparseSwitch(Integer.MIN_VALUE);
432         $noinline$sparseSwitch(Integer.MAX_VALUE);
433 
434         System.out.println("sparse2");
435         for (int i = -2; i < 3; i++) {
436             $noinline$sparseSwitch2(i);
437         }
438         $noinline$sparseSwitch2(Integer.MIN_VALUE);
439         $noinline$sparseSwitch2(Integer.MAX_VALUE);
440 
441         System.out.println("sparse3");
442         for (int i = -2; i < 7; i++) {
443             $noinline$sparseSwitch3(i);
444         }
445         $noinline$sparseSwitch3(Integer.MIN_VALUE);
446         $noinline$sparseSwitch3(Integer.MAX_VALUE);
447 
448         System.out.println("sparse4");
449         for (int i = Integer.MAX_VALUE - 3; i > 0; i++) {
450             $noinline$sparseSwitch4(i);
451         }
452         $noinline$sparseSwitch4(Integer.MIN_VALUE);
453 
454         System.out.println("sparse5");
455         for (int i = Integer.MIN_VALUE; i < Integer.MIN_VALUE + 2; i++) {
456             $noinline$sparseSwitch5(i);
457         }
458         $noinline$sparseSwitch5(Integer.MAX_VALUE);
459 
460         System.out.println("sparse6");
461         $noinline$sparseSwitch6(Integer.MIN_VALUE);
462         $noinline$sparseSwitch6(Integer.MAX_VALUE);
463 
464         System.out.println("sparse7");
465         for (int i = -1; i < 17; i++) {
466             $noinline$sparseSwitch7(i);
467         }
468 
469         // Older tests.
470 
471         int a = 1;
472 
473         switch (a) {
474             case -1: System.out.print("neg one\n"); break;
475             case 0: System.out.print("zero\n"); break;
476             case 1: System.out.print("CORRECT (one)\n"); break;
477             case 2: System.out.print("two\n"); break;
478             case 3: System.out.print("three\n"); break;
479             case 4: System.out.print("four\n"); break;
480             default: System.out.print("???\n"); break;
481         }
482         switch (a) {
483             case 3: System.out.print("three\n"); break;
484             case 4: System.out.print("four\n"); break;
485             default: System.out.print("CORRECT (not found)\n"); break;
486         }
487 
488         a = 0x12345678;
489 
490         switch (a) {
491             case 0x12345678: System.out.print("CORRECT (large)\n"); break;
492             case 0x12345679: System.out.print("large+1\n"); break;
493             default: System.out.print("nuts\n"); break;
494         }
495         switch (a) {
496             case 0x12345678: System.out.print("CORRECT (large2)\n"); break;
497             case 0x12345700: System.out.print("large+many\n"); break;
498             default: System.out.print("nuts\n"); break;
499         }
500         switch (a) {
501             case 57: System.out.print("fifty-seven!\n"); break;
502             case -6: System.out.print("neg six!\n"); break;
503             case 0x12345678: System.out.print("CORRECT (large3)\n"); break;
504             case 22: System.out.print("twenty-two!\n"); break;
505             case 3: System.out.print("three!\n"); break;
506             default: System.out.print("huh?\n"); break;
507         }
508         switch (a) {
509             case -6: System.out.print("neg six!\n"); break;
510             case 3: System.out.print("three!\n"); break;
511             default: System.out.print("CORRECT (not found)\n"); break;
512         }
513 
514         a = -5;
515         switch (a) {
516             case 12: System.out.print("twelve\n"); break;
517             case -5: System.out.print("CORRECT (not found)\n"); break;
518             case 0: System.out.print("zero\n"); break;
519             default: System.out.print("wah?\n"); break;
520         }
521 
522         switch (a) {
523             default: System.out.print("CORRECT (default only)\n"); break;
524         }
525 
526         a = -10;
527         switch (a) {
528             case -10: System.out.print("CORRECT big sparse / first\n"); break;
529             case -5: System.out.print("neg five\n"); break;
530             case 0: System.out.print("zero\n"); break;
531             case 5: System.out.print("five\n"); break;
532             case 10: System.out.print("ten\n"); break;
533             case 15: System.out.print("fifteen\n"); break;
534             case 20: System.out.print("twenty\n"); break;
535             case 50: System.out.print("fifty\n"); break;
536             case 100: System.out.print("hundred\n"); break;
537             default: System.out.print("blah!\n"); break;
538         }
539 
540         a = 100;
541         switch (a) {
542             case -10: System.out.print("neg ten\n"); break;
543             case -5: System.out.print("neg five\n"); break;
544             case 0: System.out.print("zero\n"); break;
545             case 5: System.out.print("five\n"); break;
546             case 10: System.out.print("ten\n"); break;
547             case 15: System.out.print("fifteen\n"); break;
548             case 20: System.out.print("twenty\n"); break;
549             case 50: System.out.print("fifty\n"); break;
550             case 100: System.out.print("CORRECT big sparse / last\n"); break;
551             default: System.out.print("blah!\n"); break;
552         }
553 
554         for (a = 253; a <= 258; a++) {
555           switch (a) {
556             case 254: System.out.println("254"); break;
557             case 255: System.out.println("255"); break;
558             case 256: System.out.println("256"); break;
559             case 257: System.out.println("257"); break;
560             default: System.out.println("default"); break;
561           }
562         }
563     }
564 }
565