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 
22     // TODO: This should be translated to smali tests, so it is guaranteed we have the right kind
23     //       of switch.
24 
25     // Simple packed-switch.
packedSwitch(int value)26     public static void packedSwitch(int value) {
27         switch (value) {
28             case 0:
29                 System.out.println("0"); break;
30             case 1:
31                 System.out.println("1"); break;
32             case 2:
33                 System.out.println("2"); break;
34             case 3:
35                 System.out.println("3"); break;
36             case 4:
37                 System.out.println("4"); break;
38             default:
39                 System.out.println("default"); break;
40         }
41     }
42 
43     // Simple packed-switch starting at a negative index.
packedSwitch2(int value)44     public static void 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     // Simple packed-switch starting above 0.
packedSwitch3(int value)64     public static void packedSwitch3(int value) {
65         switch (value) {
66             case 2:
67                 System.out.println("2"); break;
68             case 3:
69                 System.out.println("3"); break;
70             case 4:
71                 System.out.println("4"); break;
72             case 5:
73                 System.out.println("5"); break;
74             case 6:
75                 System.out.println("6"); break;
76             default:
77                 System.out.println("default"); break;
78         }
79     }
80 
81     // Simple packed-switch going up to max_int.
packedSwitch4(int value)82     public static void packedSwitch4(int value) {
83         switch (value) {
84             case Integer.MAX_VALUE - 1:
85                 System.out.println(Integer.MAX_VALUE - 1); break;
86             case Integer.MAX_VALUE:
87                 System.out.println(Integer.MAX_VALUE); break;
88             default:
89                 System.out.println("default"); break;
90         }
91     }
92 
93     // Simple packed-switch starting at min_int.
packedSwitch5(int value)94     public static void packedSwitch5(int value) {
95         switch (value) {
96             case Integer.MIN_VALUE:
97                 System.out.println(Integer.MIN_VALUE); break;
98             case Integer.MIN_VALUE + 1:
99                 System.out.println(Integer.MIN_VALUE + 1); break;
100             default:
101                 System.out.println("default"); break;
102         }
103     }
104 
105     // Simple (packed-)switch with only min_int.
packedSwitch6(int value)106     public static void packedSwitch6(int value) {
107         switch (value) {
108             case Integer.MIN_VALUE:
109                 System.out.println(Integer.MIN_VALUE); break;
110             default:
111                 System.out.println("default"); break;
112         }
113     }
114 
115     // Long packed-switch that might lead to not creating chained-ifs.
packedSwitch7(int value)116     public static long packedSwitch7(int value) {
117         switch (value) {
118             case 1:
119                 System.out.println(1); break;
120             case 2:
121                 System.out.println(2); break;
122             case 3:
123                 System.out.println(3); break;
124             case 4:
125                 System.out.println(4); break;
126             case 5:
127                 System.out.println(5); break;
128             case 6:
129                 System.out.println(6); break;
130             case 7:
131                 System.out.println(7); break;
132             case 8:
133                 System.out.println(8); break;
134             case 9:
135                 System.out.println(9); break;
136             case 10:
137                 System.out.println(10); break;
138             case 11:
139                 System.out.println(11); break;
140             case 12:
141                 System.out.println(12); break;
142             case 13:
143                 System.out.println(13); break;
144             case 14:
145                 System.out.println(14); break;
146             case 15:
147                 System.out.println(15); break;
148             default:
149                 System.out.println("default"); break;
150         }
151 
152         // Jump tables previously were emitted in the end of the method code buffer. The
153         // following boilerplate code aims to fill the emitted code buffer extensively
154         // and check that even for big method jump table is correctly emitted, its address
155         // is within a range of corresponded pc-relative instructions (this applies to
156         // ARM mainly).
157         long temp = value;
158         temp = Long.rotateLeft(temp, value);
159         temp = Long.rotateLeft(temp, value);
160         temp = Long.rotateLeft(temp, value);
161         temp = Long.rotateLeft(temp, value);
162         temp = Long.rotateLeft(temp, value);
163         temp = Long.rotateLeft(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 
257         return temp;
258     }
259 
260     // Sparse switch, just leave a gap.
sparseSwitch(int value)261     public static void sparseSwitch(int value) {
262         switch (value) {
263             case 0:
264                 System.out.println("0"); break;
265             case 1:
266                 System.out.println("1"); break;
267             case 3:
268                 System.out.println("3"); break;
269             case 4:
270                 System.out.println("4"); break;
271             default:
272                 System.out.println("default"); break;
273         }
274     }
275 
276     // Simple sparse-switch starting at a negative index.
sparseSwitch2(int value)277     public static void sparseSwitch2(int value) {
278         switch (value) {
279             case -3:
280                 System.out.println("-3"); break;
281             case -2:
282                 System.out.println("-2"); break;
283             case -1:
284                 System.out.println("-1"); break;
285             case 0:
286                 System.out.println("0"); break;
287             case 2:
288                 System.out.println("2"); break;
289             default:
290                 System.out.println("default"); break;
291         }
292     }
293 
294     // Simple sparse-switch starting above 0.
sparseSwitch3(int value)295     public static void sparseSwitch3(int value) {
296         switch (value) {
297             case 2:
298                 System.out.println("2"); break;
299             case 4:
300                 System.out.println("4"); break;
301             case 5:
302                 System.out.println("5"); break;
303             case 6:
304                 System.out.println("6"); break;
305             default:
306                 System.out.println("default"); break;
307         }
308     }
309 
310     // Simple sparse-switch going up to max_int.
sparseSwitch4(int value)311     public static void sparseSwitch4(int value) {
312         switch (value) {
313             case Integer.MAX_VALUE - 2:
314                 System.out.println(Integer.MAX_VALUE - 2); 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     // Simple sparse-switch starting at min_int.
sparseSwitch5(int value)323     public static void sparseSwitch5(int value) {
324         switch (value) {
325             case Integer.MIN_VALUE:
326                 System.out.println(Integer.MIN_VALUE); break;
327             case Integer.MIN_VALUE + 2:
328                 System.out.println(Integer.MIN_VALUE + 2); break;
329             default:
330                 System.out.println("default"); break;
331         }
332     }
333 
334     // Long sparse-switch that might lead to not creating chained-ifs.
sparseSwitch7(int value)335     public static void sparseSwitch7(int value) {
336         switch (value) {
337             case 1:
338                 System.out.println(1); break;
339             case 2:
340                 System.out.println(2); break;
341             case 4:
342                 System.out.println(4); break;
343             case 5:
344                 System.out.println(5); break;
345             case 6:
346                 System.out.println(6); break;
347             case 7:
348                 System.out.println(7); break;
349             case 8:
350                 System.out.println(8); break;
351             case 9:
352                 System.out.println(9); break;
353             case 10:
354                 System.out.println(10); break;
355             case 11:
356                 System.out.println(11); break;
357             case 12:
358                 System.out.println(12); break;
359             case 13:
360                 System.out.println(13); break;
361             case 14:
362                 System.out.println(14); break;
363             case 15:
364                 System.out.println(15); break;
365             default:
366                 System.out.println("default"); break;
367         }
368     }
369 
main(String args[])370     public static void main(String args[]) {
371         /*
372          * Note: We are using for loops and calls to hopefully avoid simplifying the switch
373          *       structure from constant propagation. When inlining is supported, this needs to
374          *       be revisited.
375          */
376 
377         System.out.println("packed");
378         for (int i = -2; i < 3; i++) {
379             packedSwitch(i);
380         }
381         packedSwitch(Integer.MIN_VALUE);
382         packedSwitch(Integer.MAX_VALUE);
383 
384         System.out.println("packed2");
385         for (int i = -2; i < 3; i++) {
386             packedSwitch2(i);
387         }
388         packedSwitch2(Integer.MIN_VALUE);
389         packedSwitch2(Integer.MAX_VALUE);
390 
391         System.out.println("packed3");
392         for (int i = -2; i < 7; i++) {
393             packedSwitch3(i);
394         }
395         packedSwitch3(Integer.MIN_VALUE);
396         packedSwitch3(Integer.MAX_VALUE);
397 
398         System.out.println("packed4");
399         for (int i = Integer.MAX_VALUE - 2; i > 0; i++) {
400             packedSwitch4(i);
401         }
402         packedSwitch4(Integer.MIN_VALUE);
403 
404         System.out.println("packed5");
405         for (int i = Integer.MIN_VALUE; i < Integer.MIN_VALUE + 2; i++) {
406             packedSwitch5(i);
407         }
408         packedSwitch5(Integer.MAX_VALUE);
409 
410         System.out.println("packed6");
411         packedSwitch6(Integer.MIN_VALUE);
412         packedSwitch6(Integer.MAX_VALUE);
413 
414         System.out.println("packed7");
415         for (int i = -1; i < 17; i++) {
416             packedSwitch7(i);
417         }
418 
419 
420         System.out.println("sparse");
421         for (int i = -2; i < 4; i++) {
422             sparseSwitch(i);
423         }
424         sparseSwitch(Integer.MIN_VALUE);
425         sparseSwitch(Integer.MAX_VALUE);
426 
427         System.out.println("sparse2");
428         for (int i = -2; i < 3; i++) {
429             sparseSwitch2(i);
430         }
431         sparseSwitch2(Integer.MIN_VALUE);
432         sparseSwitch2(Integer.MAX_VALUE);
433 
434         System.out.println("sparse3");
435         for (int i = -2; i < 7; i++) {
436             sparseSwitch3(i);
437         }
438         sparseSwitch3(Integer.MIN_VALUE);
439         sparseSwitch3(Integer.MAX_VALUE);
440 
441         System.out.println("sparse4");
442         for (int i = Integer.MAX_VALUE - 2; i > 0; i++) {
443             sparseSwitch4(i);
444         }
445         sparseSwitch4(Integer.MIN_VALUE);
446 
447         System.out.println("sparse5");
448         for (int i = Integer.MIN_VALUE; i < Integer.MIN_VALUE + 2; i++) {
449             sparseSwitch5(i);
450         }
451         sparseSwitch5(Integer.MAX_VALUE);
452 
453         System.out.println("sparse7");
454         for (int i = -1; i < 17; i++) {
455             sparseSwitch7(i);
456         }
457 
458         // Older tests.
459 
460         int a = 1;
461 
462         switch (a) {
463             case -1: System.out.print("neg one\n"); break;
464             case 0: System.out.print("zero\n"); break;
465             case 1: System.out.print("CORRECT (one)\n"); break;
466             case 2: System.out.print("two\n"); break;
467             case 3: System.out.print("three\n"); break;
468             case 4: System.out.print("four\n"); break;
469             default: System.out.print("???\n"); break;
470         }
471         switch (a) {
472             case 3: System.out.print("three\n"); break;
473             case 4: System.out.print("four\n"); break;
474             default: System.out.print("CORRECT (not found)\n"); break;
475         }
476 
477         a = 0x12345678;
478 
479         switch (a) {
480             case 0x12345678: System.out.print("CORRECT (large)\n"); break;
481             case 0x12345679: System.out.print("large+1\n"); break;
482             default: System.out.print("nuts\n"); break;
483         }
484         switch (a) {
485             case 0x12345678: System.out.print("CORRECT (large2)\n"); break;
486             case 0x12345700: System.out.print("large+many\n"); break;
487             default: System.out.print("nuts\n"); break;
488         }
489         switch (a) {
490             case 57: System.out.print("fifty-seven!\n"); break;
491             case -6: System.out.print("neg six!\n"); break;
492             case 0x12345678: System.out.print("CORRECT (large3)\n"); break;
493             case 22: System.out.print("twenty-two!\n"); break;
494             case 3: System.out.print("three!\n"); break;
495             default: System.out.print("huh?\n"); break;
496         }
497         switch (a) {
498             case -6: System.out.print("neg six!\n"); break;
499             case 3: System.out.print("three!\n"); break;
500             default: System.out.print("CORRECT (not found)\n"); break;
501         }
502 
503         a = -5;
504         switch (a) {
505             case 12: System.out.print("twelve\n"); break;
506             case -5: System.out.print("CORRECT (not found)\n"); break;
507             case 0: System.out.print("zero\n"); break;
508             default: System.out.print("wah?\n"); break;
509         }
510 
511         switch (a) {
512             default: System.out.print("CORRECT (default only)\n"); break;
513         }
514 
515         a = -10;
516         switch (a) {
517             case -10: System.out.print("CORRECT big sparse / first\n"); break;
518             case -5: System.out.print("neg five\n"); break;
519             case 0: System.out.print("zero\n"); break;
520             case 5: System.out.print("five\n"); break;
521             case 10: System.out.print("ten\n"); break;
522             case 15: System.out.print("fifteen\n"); break;
523             case 20: System.out.print("twenty\n"); break;
524             case 50: System.out.print("fifty\n"); break;
525             case 100: System.out.print("hundred\n"); break;
526             default: System.out.print("blah!\n"); break;
527         }
528 
529         a = 100;
530         switch (a) {
531             case -10: System.out.print("neg ten\n"); break;
532             case -5: System.out.print("neg five\n"); break;
533             case 0: System.out.print("zero\n"); break;
534             case 5: System.out.print("five\n"); break;
535             case 10: System.out.print("ten\n"); break;
536             case 15: System.out.print("fifteen\n"); break;
537             case 20: System.out.print("twenty\n"); break;
538             case 50: System.out.print("fifty\n"); break;
539             case 100: System.out.print("CORRECT big sparse / last\n"); break;
540             default: System.out.print("blah!\n"); break;
541         }
542 
543         for (a = 253; a <= 258; a++) {
544           switch (a) {
545             case 254: System.out.println("254"); break;
546             case 255: System.out.println("255"); break;
547             case 256: System.out.println("256"); break;
548             case 257: System.out.println("257"); break;
549             default: System.out.println("default"); break;
550           }
551         }
552     }
553 }
554