554 lines
19 KiB
Java
554 lines
19 KiB
Java
/*
|
|
* 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;
|
|
}
|
|
}
|
|
}
|
|
}
|