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