/* * Copyright (C) 2007 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Test switch() blocks */ public class Main { // TODO: This should be translated to smali tests, so it is guaranteed we have the right kind // of switch. // Simple packed-switch. public static void packedSwitch(int value) { switch (value) { case 0: System.out.println("0"); break; case 1: System.out.println("1"); break; case 2: System.out.println("2"); break; case 3: System.out.println("3"); break; case 4: System.out.println("4"); break; default: System.out.println("default"); break; } } // Simple packed-switch starting at a negative index. public static void packedSwitch2(int value) { switch (value) { case -3: System.out.println("-3"); break; case -2: System.out.println("-2"); break; case -1: System.out.println("-1"); break; case 0: System.out.println("0"); break; case 1: System.out.println("1"); break; case 2: System.out.println("2"); break; default: System.out.println("default"); break; } } // Simple packed-switch starting above 0. public static void packedSwitch3(int value) { switch (value) { case 2: System.out.println("2"); break; case 3: System.out.println("3"); break; case 4: System.out.println("4"); break; case 5: System.out.println("5"); break; case 6: System.out.println("6"); break; default: System.out.println("default"); break; } } // Simple packed-switch going up to max_int. public static void packedSwitch4(int value) { switch (value) { case Integer.MAX_VALUE - 1: System.out.println(Integer.MAX_VALUE - 1); break; case Integer.MAX_VALUE: System.out.println(Integer.MAX_VALUE); break; default: System.out.println("default"); break; } } // Simple packed-switch starting at min_int. public static void packedSwitch5(int value) { switch (value) { case Integer.MIN_VALUE: System.out.println(Integer.MIN_VALUE); break; case Integer.MIN_VALUE + 1: System.out.println(Integer.MIN_VALUE + 1); break; default: System.out.println("default"); break; } } // Simple (packed-)switch with only min_int. public static void packedSwitch6(int value) { switch (value) { case Integer.MIN_VALUE: System.out.println(Integer.MIN_VALUE); break; default: System.out.println("default"); break; } } // Long packed-switch that might lead to not creating chained-ifs. public static long packedSwitch7(int value) { switch (value) { case 1: System.out.println(1); break; case 2: System.out.println(2); break; case 3: System.out.println(3); break; case 4: System.out.println(4); break; case 5: System.out.println(5); break; case 6: System.out.println(6); break; case 7: System.out.println(7); break; case 8: System.out.println(8); break; case 9: System.out.println(9); break; case 10: System.out.println(10); break; case 11: System.out.println(11); break; case 12: System.out.println(12); break; case 13: System.out.println(13); break; case 14: System.out.println(14); break; case 15: System.out.println(15); break; default: System.out.println("default"); break; } // Jump tables previously were emitted in the end of the method code buffer. The // following boilerplate code aims to fill the emitted code buffer extensively // and check that even for big method jump table is correctly emitted, its address // is within a range of corresponded pc-relative instructions (this applies to // ARM mainly). long temp = value; temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); temp = Long.rotateLeft(temp, value); return temp; } // Sparse switch, just leave a gap. public static void sparseSwitch(int value) { switch (value) { case 0: System.out.println("0"); break; case 1: System.out.println("1"); break; case 3: System.out.println("3"); break; case 4: System.out.println("4"); break; default: System.out.println("default"); break; } } // Simple sparse-switch starting at a negative index. public static void sparseSwitch2(int value) { switch (value) { case -3: System.out.println("-3"); break; case -2: System.out.println("-2"); break; case -1: System.out.println("-1"); break; case 0: System.out.println("0"); break; case 2: System.out.println("2"); break; default: System.out.println("default"); break; } } // Simple sparse-switch starting above 0. public static void sparseSwitch3(int value) { switch (value) { case 2: System.out.println("2"); break; case 4: System.out.println("4"); break; case 5: System.out.println("5"); break; case 6: System.out.println("6"); break; default: System.out.println("default"); break; } } // Simple sparse-switch going up to max_int. public static void sparseSwitch4(int value) { switch (value) { case Integer.MAX_VALUE - 2: System.out.println(Integer.MAX_VALUE - 2); break; case Integer.MAX_VALUE: System.out.println(Integer.MAX_VALUE); break; default: System.out.println("default"); break; } } // Simple sparse-switch starting at min_int. public static void sparseSwitch5(int value) { switch (value) { case Integer.MIN_VALUE: System.out.println(Integer.MIN_VALUE); break; case Integer.MIN_VALUE + 2: System.out.println(Integer.MIN_VALUE + 2); break; default: System.out.println("default"); break; } } // Long sparse-switch that might lead to not creating chained-ifs. public static void sparseSwitch7(int value) { switch (value) { case 1: System.out.println(1); break; case 2: System.out.println(2); break; case 4: System.out.println(4); break; case 5: System.out.println(5); break; case 6: System.out.println(6); break; case 7: System.out.println(7); break; case 8: System.out.println(8); break; case 9: System.out.println(9); break; case 10: System.out.println(10); break; case 11: System.out.println(11); break; case 12: System.out.println(12); break; case 13: System.out.println(13); break; case 14: System.out.println(14); break; case 15: System.out.println(15); break; default: System.out.println("default"); break; } } public static void main(String args[]) { /* * Note: We are using for loops and calls to hopefully avoid simplifying the switch * structure from constant propagation. When inlining is supported, this needs to * be revisited. */ System.out.println("packed"); for (int i = -2; i < 3; i++) { packedSwitch(i); } packedSwitch(Integer.MIN_VALUE); packedSwitch(Integer.MAX_VALUE); System.out.println("packed2"); for (int i = -2; i < 3; i++) { packedSwitch2(i); } packedSwitch2(Integer.MIN_VALUE); packedSwitch2(Integer.MAX_VALUE); System.out.println("packed3"); for (int i = -2; i < 7; i++) { packedSwitch3(i); } packedSwitch3(Integer.MIN_VALUE); packedSwitch3(Integer.MAX_VALUE); System.out.println("packed4"); for (int i = Integer.MAX_VALUE - 2; i > 0; i++) { packedSwitch4(i); } packedSwitch4(Integer.MIN_VALUE); System.out.println("packed5"); for (int i = Integer.MIN_VALUE; i < Integer.MIN_VALUE + 2; i++) { packedSwitch5(i); } packedSwitch5(Integer.MAX_VALUE); System.out.println("packed6"); packedSwitch6(Integer.MIN_VALUE); packedSwitch6(Integer.MAX_VALUE); System.out.println("packed7"); for (int i = -1; i < 17; i++) { packedSwitch7(i); } System.out.println("sparse"); for (int i = -2; i < 4; i++) { sparseSwitch(i); } sparseSwitch(Integer.MIN_VALUE); sparseSwitch(Integer.MAX_VALUE); System.out.println("sparse2"); for (int i = -2; i < 3; i++) { sparseSwitch2(i); } sparseSwitch2(Integer.MIN_VALUE); sparseSwitch2(Integer.MAX_VALUE); System.out.println("sparse3"); for (int i = -2; i < 7; i++) { sparseSwitch3(i); } sparseSwitch3(Integer.MIN_VALUE); sparseSwitch3(Integer.MAX_VALUE); System.out.println("sparse4"); for (int i = Integer.MAX_VALUE - 2; i > 0; i++) { sparseSwitch4(i); } sparseSwitch4(Integer.MIN_VALUE); System.out.println("sparse5"); for (int i = Integer.MIN_VALUE; i < Integer.MIN_VALUE + 2; i++) { sparseSwitch5(i); } sparseSwitch5(Integer.MAX_VALUE); System.out.println("sparse7"); for (int i = -1; i < 17; i++) { sparseSwitch7(i); } // Older tests. int a = 1; switch (a) { case -1: System.out.print("neg one\n"); break; case 0: System.out.print("zero\n"); break; case 1: System.out.print("CORRECT (one)\n"); break; case 2: System.out.print("two\n"); break; case 3: System.out.print("three\n"); break; case 4: System.out.print("four\n"); break; default: System.out.print("???\n"); break; } switch (a) { case 3: System.out.print("three\n"); break; case 4: System.out.print("four\n"); break; default: System.out.print("CORRECT (not found)\n"); break; } a = 0x12345678; switch (a) { case 0x12345678: System.out.print("CORRECT (large)\n"); break; case 0x12345679: System.out.print("large+1\n"); break; default: System.out.print("nuts\n"); break; } switch (a) { case 0x12345678: System.out.print("CORRECT (large2)\n"); break; case 0x12345700: System.out.print("large+many\n"); break; default: System.out.print("nuts\n"); break; } switch (a) { case 57: System.out.print("fifty-seven!\n"); break; case -6: System.out.print("neg six!\n"); break; case 0x12345678: System.out.print("CORRECT (large3)\n"); break; case 22: System.out.print("twenty-two!\n"); break; case 3: System.out.print("three!\n"); break; default: System.out.print("huh?\n"); break; } switch (a) { case -6: System.out.print("neg six!\n"); break; case 3: System.out.print("three!\n"); break; default: System.out.print("CORRECT (not found)\n"); break; } a = -5; switch (a) { case 12: System.out.print("twelve\n"); break; case -5: System.out.print("CORRECT (not found)\n"); break; case 0: System.out.print("zero\n"); break; default: System.out.print("wah?\n"); break; } switch (a) { default: System.out.print("CORRECT (default only)\n"); break; } a = -10; switch (a) { case -10: System.out.print("CORRECT big sparse / first\n"); break; case -5: System.out.print("neg five\n"); break; case 0: System.out.print("zero\n"); break; case 5: System.out.print("five\n"); break; case 10: System.out.print("ten\n"); break; case 15: System.out.print("fifteen\n"); break; case 20: System.out.print("twenty\n"); break; case 50: System.out.print("fifty\n"); break; case 100: System.out.print("hundred\n"); break; default: System.out.print("blah!\n"); break; } a = 100; switch (a) { case -10: System.out.print("neg ten\n"); break; case -5: System.out.print("neg five\n"); break; case 0: System.out.print("zero\n"); break; case 5: System.out.print("five\n"); break; case 10: System.out.print("ten\n"); break; case 15: System.out.print("fifteen\n"); break; case 20: System.out.print("twenty\n"); break; case 50: System.out.print("fifty\n"); break; case 100: System.out.print("CORRECT big sparse / last\n"); break; default: System.out.print("blah!\n"); break; } for (a = 253; a <= 258; a++) { switch (a) { case 254: System.out.println("254"); break; case 255: System.out.println("255"); break; case 256: System.out.println("256"); break; case 257: System.out.println("257"); break; default: System.out.println("default"); break; } } } }