1 /* 2 * Copyright (C) 2015 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 public class Main { 18 19 public static void assertIntEquals(int expected, int result) { 20 if (expected != result) { 21 throw new Error("Expected: " + expected + ", found: " + result); 22 } 23 } 24 25 public static void assertLongEquals(long expected, long result) { 26 if (expected != result) { 27 throw new Error("Expected: " + expected + ", found: " + result); 28 } 29 } 30 31 /// CHECK-START-ARM: int Main.and255(int) disassembly (after) 32 /// CHECK-NOT: movs {{r\d+}}, #255 33 /// CHECK: and {{r\d+}}, {{r\d+}}, #0xff 34 35 public static int and255(int arg) { 36 return arg & 255; 37 } 38 39 /// CHECK-START-ARM: int Main.and511(int) disassembly (after) 40 /// CHECK: ubfx {{r\d+}}, {{r\d+}}, #0, #9 41 42 public static int and511(int arg) { 43 return arg & 511; 44 } 45 46 /// CHECK-START-ARM: int Main.andF00D(int) disassembly (after) 47 /// CHECK: mov {{r\d+}}, #61453 48 /// CHECK: and{{(\.w)?}} {{r\d+}}, {{r\d+}}, {{r\d+}} 49 50 public static int andF00D(int arg) { 51 return arg & 0xF00D; 52 } 53 54 /// CHECK-START-ARM: int Main.andNot15(int) disassembly (after) 55 /// CHECK-NOT: mvn {{r\d+}}, #15 56 /// CHECK: bic {{r\d+}}, {{r\d+}}, #0xf 57 58 public static int andNot15(int arg) { 59 return arg & ~15; 60 } 61 62 /// CHECK-START-ARM: int Main.or255(int) disassembly (after) 63 /// CHECK-NOT: movs {{r\d+}}, #255 64 /// CHECK: orr {{r\d+}}, {{r\d+}}, #0xff 65 66 public static int or255(int arg) { 67 return arg | 255; 68 } 69 70 /// CHECK-START-ARM: int Main.or511(int) disassembly (after) 71 /// CHECK: mov {{r\d+}}, #511 72 /// CHECK: orr{{(\.w)?}} {{r\d+}}, {{r\d+}}, {{r\d+}} 73 74 public static int or511(int arg) { 75 return arg | 511; 76 } 77 78 /// CHECK-START-ARM: int Main.orNot15(int) disassembly (after) 79 /// CHECK-NOT: mvn {{r\d+}}, #15 80 /// CHECK: orn {{r\d+}}, {{r\d+}}, #0xf 81 82 public static int orNot15(int arg) { 83 return arg | ~15; 84 } 85 86 /// CHECK-START-ARM: int Main.xor255(int) disassembly (after) 87 /// CHECK-NOT: movs {{r\d+}}, #255 88 /// CHECK: eor {{r\d+}}, {{r\d+}}, #0xff 89 90 public static int xor255(int arg) { 91 return arg ^ 255; 92 } 93 94 /// CHECK-START-ARM: int Main.xor511(int) disassembly (after) 95 /// CHECK: mov {{r\d+}}, #511 96 /// CHECK: eor{{(\.w)?}} {{r\d+}}, {{r\d+}}, {{r\d+}} 97 98 public static int xor511(int arg) { 99 return arg ^ 511; 100 } 101 102 /// CHECK-START-ARM: int Main.xorNot15(int) disassembly (after) 103 /// CHECK: mvn {{r\d+}}, #15 104 /// CHECK: eor{{(\.w)?}} {{r\d+}}, {{r\d+}}, {{r\d+}} 105 106 public static int xorNot15(int arg) { 107 return arg ^ ~15; 108 } 109 110 /// CHECK-START-ARM: long Main.and255(long) disassembly (after) 111 /// CHECK-NOT: movs {{r\d+}}, #255 112 /// CHECK-NOT: and{{(\.w)?}} 113 /// CHECK-NOT: bic{{(\.w)?}} 114 /// CHECK-DAG: and {{r\d+}}, {{r\d+}}, #0xff 115 /// CHECK-DAG: mov{{s?}} {{r\d+}}, #0 116 /// CHECK-NOT: and{{(\.w)?}} 117 /// CHECK-NOT: bic{{(\.w)?}} 118 119 public static long and255(long arg) { 120 return arg & 255L; 121 } 122 123 /// CHECK-START-ARM: long Main.and511(long) disassembly (after) 124 /// CHECK: ubfx {{r\d+}}, {{r\d+}}, #0, #9 125 /// CHECK-NEXT: mov{{s?}} {{r\d+}}, #0 126 /// CHECK-NOT: and{{(\.w)?}} 127 /// CHECK-NOT: bic{{(\.w)?}} 128 129 public static long and511(long arg) { 130 return arg & 511L; 131 } 132 133 /// CHECK-START-ARM: long Main.andF00D(long) disassembly (after) 134 /// CHECK: mov {{r\d+}}, #61453 135 /// CHECK-NEXT: mov{{s?}} {{r\d+}}, #0 136 /// CHECK-NOT: and{{(\.w)?}} 137 /// CHECK-NOT: bic{{(\.w)?}} 138 /// CHECK-NOT: ubfx 139 /// CHECK: and{{(\.w)?}} {{r\d+}}, {{r\d+}}, {{r\d+}} 140 /// CHECK-NEXT: and{{(\.w)?}} {{r\d+}}, {{r\d+}}, {{r\d+}} 141 /// CHECK-NOT: and{{(\.w)?}} 142 /// CHECK-NOT: bic{{(\.w)?}} 143 /// CHECK-NOT: ubfx 144 145 public static long andF00D(long arg) { 146 return arg & 0xF00DL; 147 } 148 149 /// CHECK-START-ARM: long Main.andNot15(long) disassembly (after) 150 /// CHECK-NOT: mvn {{r\d+}}, #15 151 /// CHECK-NOT: and{{(\.w)?}} 152 /// CHECK-NOT: bic{{(\.w)?}} 153 /// CHECK: bic {{r\d+}}, {{r\d+}}, #0xf 154 /// CHECK-NOT: and{{(\.w)?}} 155 /// CHECK-NOT: bic{{(\.w)?}} 156 157 public static long andNot15(long arg) { 158 return arg & ~15L; 159 } 160 161 /// CHECK-START-ARM: long Main.and0xfffffff00000000f(long) disassembly (after) 162 /// CHECK-NOT: movs {{r\d+}}, #15 163 /// CHECK-NOT: mvn {{r\d+}}, #15 164 /// CHECK-NOT: and{{(\.w)?}} 165 /// CHECK-NOT: bic{{(\.w)?}} 166 /// CHECK-DAG: and {{r\d+}}, {{r\d+}}, #0xf 167 /// CHECK-DAG: bic {{r\d+}}, {{r\d+}}, #0xf 168 /// CHECK-NOT: and{{(\.w)?}} 169 /// CHECK-NOT: bic{{(\.w)?}} 170 171 public static long and0xfffffff00000000f(long arg) { 172 return arg & 0xfffffff00000000fL; 173 } 174 175 /// CHECK-START-ARM: long Main.or255(long) disassembly (after) 176 /// CHECK-NOT: movs {{r\d+}}, #255 177 /// CHECK-NOT: orr{{(\.w)?}} 178 /// CHECK-NOT: orn 179 /// CHECK: orr {{r\d+}}, {{r\d+}}, #0xff 180 /// CHECK-NOT: orr{{(\.w)?}} 181 /// CHECK-NOT: orn 182 183 public static long or255(long arg) { 184 return arg | 255L; 185 } 186 187 /// CHECK-START-ARM: long Main.or511(long) disassembly (after) 188 /// CHECK: mov {{r\d+}}, #511 189 /// CHECK-NEXT: mov{{s?}} {{r\d+}}, #0 190 /// CHECK-NOT: orr{{(\.w)?}} 191 /// CHECK-NOT: orn 192 /// CHECK: orr{{(\.w)?}} {{r\d+}}, {{r\d+}}, {{r\d+}} 193 /// CHECK-NEXT: orr{{(\.w)?}} {{r\d+}}, {{r\d+}}, {{r\d+}} 194 /// CHECK-NOT: orr{{(\.w)?}} 195 /// CHECK-NOT: orn 196 197 public static long or511(long arg) { 198 return arg | 511L; 199 } 200 201 /// CHECK-START-ARM: long Main.orNot15(long) disassembly (after) 202 /// CHECK-NOT: mvn {{r\d+}}, #15 203 /// CHECK-NOT: orr{{(\.w)?}} 204 /// CHECK-NOT: orn 205 /// CHECK-DAG: orn {{r\d+}}, {{r\d+}}, #0xf 206 /// CHECK-DAG: mvn {{r\d+}}, #0 207 /// CHECK-NOT: orr{{(\.w)?}} 208 /// CHECK-NOT: orn 209 210 public static long orNot15(long arg) { 211 return arg | ~15L; 212 } 213 214 /// CHECK-START-ARM: long Main.or0xfffffff00000000f(long) disassembly (after) 215 /// CHECK-NOT: movs {{r\d+}}, #15 216 /// CHECK-NOT: mvn {{r\d+}}, #15 217 /// CHECK-NOT: orr{{(\.w)?}} 218 /// CHECK-NOT: orn 219 /// CHECK-DAG: orr {{r\d+}}, {{r\d+}}, #0xf 220 /// CHECK-DAG: orn {{r\d+}}, {{r\d+}}, #0xf 221 /// CHECK-NOT: orr{{(\.w)?}} 222 /// CHECK-NOT: orn 223 224 public static long or0xfffffff00000000f(long arg) { 225 return arg | 0xfffffff00000000fL; 226 } 227 228 /// CHECK-START-ARM: long Main.xor255(long) disassembly (after) 229 /// CHECK-NOT: movs {{r\d+}}, #255 230 /// CHECK-NOT: eor{{(\.w)?}} 231 /// CHECK: eor {{r\d+}}, {{r\d+}}, #0xff 232 /// CHECK-NOT: eor{{(\.w)?}} 233 234 public static long xor255(long arg) { 235 return arg ^ 255L; 236 } 237 238 /// CHECK-START-ARM: long Main.xor511(long) disassembly (after) 239 /// CHECK: mov {{r\d+}}, #511 240 /// CHECK-NEXT: mov{{s?}} {{r\d+}}, #0 241 /// CHECK-NOT: eor{{(\.w)?}} 242 /// CHECK: eor{{(\.w)?}} {{r\d+}}, {{r\d+}}, {{r\d+}} 243 /// CHECK-NEXT: eor{{(\.w)?}} {{r\d+}}, {{r\d+}}, {{r\d+}} 244 /// CHECK-NOT: eor{{(\.w)?}} 245 246 public static long xor511(long arg) { 247 return arg ^ 511L; 248 } 249 250 /// CHECK-START-ARM: long Main.xorNot15(long) disassembly (after) 251 /// CHECK-DAG: mvn {{r\d+}}, #15 252 /// CHECK-DAG: mov {{r\d+}}, #4294967295 253 /// CHECK-NOT: eor{{(\.w)?}} 254 /// CHECK-DAG: eor{{(\.w)?}} {{r\d+}}, {{r\d+}}, {{r\d+}} 255 /// CHECK-DAG: eor{{(\.w)?}} {{r\d+}}, {{r\d+}}, {{r\d+}} 256 /// CHECK-NOT: eor{{(\.w)?}} 257 258 public static long xorNot15(long arg) { 259 return arg ^ ~15L; 260 } 261 262 // Note: No support for partial long constant embedding. 263 /// CHECK-START-ARM: long Main.xor0xfffffff00000000f(long) disassembly (after) 264 /// CHECK-DAG: mov{{s?}} {{r\d+}}, #15 265 /// CHECK-DAG: mvn {{r\d+}}, #15 266 /// CHECK-NOT: eor{{(\.w)?}} 267 /// CHECK-DAG: eor{{(\.w)?}} {{r\d+}}, {{r\d+}}, {{r\d+}} 268 /// CHECK-DAG: eor{{(\.w)?}} {{r\d+}}, {{r\d+}}, {{r\d+}} 269 /// CHECK-NOT: eor{{(\.w)?}} 270 271 public static long xor0xfffffff00000000f(long arg) { 272 return arg ^ 0xfffffff00000000fL; 273 } 274 275 /// CHECK-START-ARM: long Main.xor0xf00000000000000f(long) disassembly (after) 276 /// CHECK-NOT: movs {{r\d+}}, #15 277 /// CHECK-NOT: mov.w {{r\d+}}, #-268435456 278 /// CHECK-NOT: eor{{(\.w)?}} 279 /// CHECK-DAG: eor {{r\d+}}, {{r\d+}}, #0xf 280 /// CHECK-DAG: eor {{r\d+}}, {{r\d+}}, #0xf0000000 281 /// CHECK-NOT: eor{{(\.w)?}} 282 283 public static long xor0xf00000000000000f(long arg) { 284 return arg ^ 0xf00000000000000fL; 285 } 286 287 /// CHECK-START-ARM: long Main.shl1(long) disassembly (after) 288 /// CHECK: lsls{{(\.w)?}} {{r\d+}}, {{r\d+}}, #1 289 /// CHECK: adc{{(\.w)?}} {{r\d+}}, {{r\d+}}, {{r\d+}} 290 291 /// CHECK-START-ARM: long Main.shl1(long) disassembly (after) 292 /// CHECK-NOT: lsl{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} 293 294 /// CHECK-START-X86: long Main.shl1(long) disassembly (after) 295 /// CHECK: add 296 /// CHECK: adc 297 298 /// CHECK-START-X86: long Main.shl1(long) disassembly (after) 299 /// CHECK-NOT: shl 300 301 public static long shl1(long arg) { 302 return arg << 1; 303 } 304 305 /// CHECK-START-ARM: long Main.shl2(long) disassembly (after) 306 /// CHECK: lsl{{s?|\.w}} <<oh:r\d+>>, {{r\d+}}, #2 307 /// CHECK: orr <<oh>>, <<low:r\d+>>, lsr #30 308 /// CHECK: lsl{{s?|\.w}} {{r\d+}}, <<low>>, #2 309 310 /// CHECK-START-ARM: long Main.shl2(long) disassembly (after) 311 /// CHECK-NOT: lsl{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} 312 313 public static long shl2(long arg) { 314 return arg << 2; 315 } 316 317 /// CHECK-START-ARM: long Main.shl31(long) disassembly (after) 318 /// CHECK: lsl{{s?|\.w}} <<oh:r\d+>>, {{r\d+}}, #31 319 /// CHECK: orr <<oh>>, <<low:r\d+>>, lsr #1 320 /// CHECK: lsl{{s?|\.w}} {{r\d+}}, <<low>>, #31 321 322 /// CHECK-START-ARM: long Main.shl31(long) disassembly (after) 323 /// CHECK-NOT: lsl{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} 324 325 public static long shl31(long arg) { 326 return arg << 31; 327 } 328 329 /// CHECK-START-ARM: long Main.shl32(long) disassembly (after) 330 /// CHECK-DAG: mov{{s?}} {{r\d+}}, {{r\d+}} 331 /// CHECK-DAG: mov{{s?|\.w}} {{r\d+}}, #0 332 333 /// CHECK-START-ARM: long Main.shl32(long) disassembly (after) 334 /// CHECK-NOT: lsl{{s?|\.w}} 335 336 public static long shl32(long arg) { 337 return arg << 32; 338 } 339 340 /// CHECK-START-ARM: long Main.shl33(long) disassembly (after) 341 /// CHECK-DAG: lsl{{s?|\.w}} {{r\d+}}, <<high:r\d+>>, #1 342 /// CHECK-DAG: mov{{s?|\.w}} {{r\d+}}, #0 343 344 /// CHECK-START-ARM: long Main.shl33(long) disassembly (after) 345 /// CHECK-NOT: lsl{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} 346 347 public static long shl33(long arg) { 348 return arg << 33; 349 } 350 351 /// CHECK-START-ARM: long Main.shl63(long) disassembly (after) 352 /// CHECK-DAG: lsl{{s?|\.w}} {{r\d+}}, <<high:r\d+>>, #31 353 /// CHECK-DAG: mov{{s?|\.w}} {{r\d+}}, #0 354 355 /// CHECK-START-ARM: long Main.shl63(long) disassembly (after) 356 /// CHECK-NOT: lsl{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} 357 358 public static long shl63(long arg) { 359 return arg << 63; 360 } 361 362 /// CHECK-START-ARM: long Main.shr1(long) disassembly (after) 363 /// CHECK: asrs{{(\.w)?}} {{r\d+}}, {{r\d+}}, #1 364 /// CHECK: rrx {{r\d+}}, {{r\d+}} 365 366 /// CHECK-START-ARM: long Main.shr1(long) disassembly (after) 367 /// CHECK-NOT: asr{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} 368 369 public static long shr1(long arg) { 370 return arg >> 1; 371 } 372 373 /// CHECK-START-ARM: long Main.shr2(long) disassembly (after) 374 /// CHECK: lsr{{s?|\.w}} <<ol:r\d+>>, {{r\d+}}, #2 375 /// CHECK: orr <<ol>>, <<high:r\d+>>, lsl #30 376 /// CHECK-DAG: asr{{s?|\.w}} {{r\d+}}, <<high>>, #2 377 378 /// CHECK-START-ARM: long Main.shr2(long) disassembly (after) 379 /// CHECK-NOT: asr{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} 380 381 public static long shr2(long arg) { 382 return arg >> 2; 383 } 384 385 /// CHECK-START-ARM: long Main.shr31(long) disassembly (after) 386 /// CHECK: lsr{{s?|\.w}} <<ol:r\d+>>, {{r\d+}}, #31 387 /// CHECK: orr <<ol>>, <<high:r\d+>>, lsl #1 388 /// CHECK: asr{{s?|\.w}} {{r\d+}}, <<high>>, #31 389 390 /// CHECK-START-ARM: long Main.shr31(long) disassembly (after) 391 /// CHECK-NOT: asr{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} 392 393 public static long shr31(long arg) { 394 return arg >> 31; 395 } 396 397 /// CHECK-START-ARM: long Main.shr32(long) disassembly (after) 398 /// CHECK-DAG: asr{{s?|\.w}} {{r\d+}}, <<high:r\d+>>, #31 399 /// CHECK-DAG: mov{{s?}} {{r\d+}}, <<high>> 400 401 /// CHECK-START-ARM: long Main.shr32(long) disassembly (after) 402 /// CHECK-NOT: asr{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} 403 /// CHECK-NOT: lsr{{s?|\.w}} 404 405 public static long shr32(long arg) { 406 return arg >> 32; 407 } 408 409 /// CHECK-START-ARM: long Main.shr33(long) disassembly (after) 410 /// CHECK-DAG: asr{{s?|\.w}} {{r\d+}}, <<high:r\d+>>, #1 411 /// CHECK-DAG: asr{{s?|\.w}} {{r\d+}}, <<high>>, #31 412 413 /// CHECK-START-ARM: long Main.shr33(long) disassembly (after) 414 /// CHECK-NOT: asr{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} 415 416 public static long shr33(long arg) { 417 return arg >> 33; 418 } 419 420 /// CHECK-START-ARM: long Main.shr63(long) disassembly (after) 421 /// CHECK-DAG: asr{{s?|\.w}} {{r\d+}}, <<high:r\d+>>, #31 422 /// CHECK-DAG: asr{{s?|\.w}} {{r\d+}}, <<high>>, #31 423 424 /// CHECK-START-ARM: long Main.shr63(long) disassembly (after) 425 /// CHECK-NOT: asr{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} 426 427 public static long shr63(long arg) { 428 return arg >> 63; 429 } 430 431 /// CHECK-START-ARM: long Main.ushr1(long) disassembly (after) 432 /// CHECK: lsrs{{|.w}} {{r\d+}}, {{r\d+}}, #1 433 /// CHECK: rrx {{r\d+}}, {{r\d+}} 434 435 /// CHECK-START-ARM: long Main.ushr1(long) disassembly (after) 436 /// CHECK-NOT: lsr{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} 437 438 public static long ushr1(long arg) { 439 return arg >>> 1; 440 } 441 442 /// CHECK-START-ARM: long Main.ushr2(long) disassembly (after) 443 /// CHECK: lsr{{s?|\.w}} <<ol:r\d+>>, {{r\d+}}, #2 444 /// CHECK: orr <<ol>>, <<high:r\d+>>, lsl #30 445 /// CHECK-DAG: lsr{{s?|\.w}} {{r\d+}}, <<high>>, #2 446 447 /// CHECK-START-ARM: long Main.ushr2(long) disassembly (after) 448 /// CHECK-NOT: lsr{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} 449 450 public static long ushr2(long arg) { 451 return arg >>> 2; 452 } 453 454 /// CHECK-START-ARM: long Main.ushr31(long) disassembly (after) 455 /// CHECK: lsr{{s?|\.w}} <<ol:r\d+>>, {{r\d+}}, #31 456 /// CHECK: orr <<ol>>, <<high:r\d+>>, lsl #1 457 /// CHECK: lsr{{s?|\.w}} {{r\d+}}, <<high>>, #31 458 459 /// CHECK-START-ARM: long Main.ushr31(long) disassembly (after) 460 /// CHECK-NOT: lsr{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} 461 462 public static long ushr31(long arg) { 463 return arg >>> 31; 464 } 465 466 /// CHECK-START-ARM: long Main.ushr32(long) disassembly (after) 467 /// CHECK-DAG: mov{{s?}} {{r\d+}}, {{r\d+}} 468 /// CHECK-DAG: mov{{s?|\.w}} {{r\d+}}, #0 469 470 /// CHECK-START-ARM: long Main.ushr32(long) disassembly (after) 471 /// CHECK-NOT: lsr{{s?|\.w}} 472 473 public static long ushr32(long arg) { 474 return arg >>> 32; 475 } 476 477 /// CHECK-START-ARM: long Main.ushr33(long) disassembly (after) 478 /// CHECK-DAG: lsr{{s?|\.w}} {{r\d+}}, {{r\d+}}, #1 479 /// CHECK-DAG: mov{{s?|\.w}} {{r\d+}}, #0 480 481 /// CHECK-START-ARM: long Main.ushr33(long) disassembly (after) 482 /// CHECK-NOT: lsr{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} 483 484 public static long ushr33(long arg) { 485 return arg >>> 33; 486 } 487 488 /// CHECK-START-ARM: long Main.ushr63(long) disassembly (after) 489 /// CHECK-DAG: lsr{{s?|\.w}} {{r\d+}}, {{r\d+}}, #31 490 /// CHECK-DAG: mov{{s?|\.w}} {{r\d+}}, #0 491 492 /// CHECK-START-ARM: long Main.ushr63(long) disassembly (after) 493 /// CHECK-NOT: lsr{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} 494 495 public static long ushr63(long arg) { 496 return arg >>> 63; 497 } 498 499 /** 500 * ARM/ARM64: Test that the `-1` constant is not synthesized in a register and that we 501 * instead simply switch between `add` and `sub` instructions with the 502 * constant embedded. 503 * We need two uses (or more) of the constant because the compiler always 504 * defers to immediate value handling to VIXL when it has only one use. 505 */ 506 507 /// CHECK-START-ARM64: long Main.addM1(long) register (after) 508 /// CHECK: <<Arg:j\d+>> ParameterValue 509 /// CHECK: <<ConstM1:j\d+>> LongConstant -1 510 /// CHECK-NOT: ParallelMove 511 /// CHECK: Add [<<Arg>>,<<ConstM1>>] 512 /// CHECK: Sub [<<Arg>>,<<ConstM1>>] 513 514 /// CHECK-START-ARM64: long Main.addM1(long) disassembly (after) 515 /// CHECK: sub x{{\d+}}, x{{\d+}}, #0x1 516 /// CHECK: add x{{\d+}}, x{{\d+}}, #0x1 517 518 /// CHECK-START-ARM: long Main.addM1(long) register (after) 519 /// CHECK: <<Arg:j\d+>> ParameterValue 520 /// CHECK: <<ConstM1:j\d+>> LongConstant -1 521 /// CHECK-NOT: ParallelMove 522 /// CHECK: Add [<<Arg>>,<<ConstM1>>] 523 /// CHECK: Sub [<<Arg>>,<<ConstM1>>] 524 525 /// CHECK-START-ARM: long Main.addM1(long) disassembly (after) 526 /// CHECK: <<Arg:j\d+>> ParameterValue 527 /// CHECK: <<ConstM1:j\d+>> LongConstant -1 528 /// CHECK: Add [<<Arg>>,<<ConstM1>>] 529 /// CHECK-NEXT: {{adds|subs}} r{{\d+}}, #{{4294967295|1}} 530 /// CHECK-NEXT: adc r{{\d+}}, r{{\d+}}, #4294967295 531 /// CHECK: Sub [<<Arg>>,<<ConstM1>>] 532 /// CHECK-NEXT: adds r{{\d+}}, #1 533 /// CHECK-NEXT: adc r{{\d+}}, #0 534 535 public static long addM1(long arg) { 536 return (arg + (-1)) | (arg - (-1)); 537 } 538 539 /** 540 * ARM: Test that some long constants are not synthesized in a register for add-long. 541 * Also test some negative cases where we do synthetize constants in registers. 542 */ 543 544 /// CHECK-START-ARM: long Main.addLongConstants(long) disassembly (after) 545 /// CHECK: <<Arg:j\d+>> ParameterValue 546 /// CHECK-DAG: <<ConstA:j\d+>> LongConstant 4486007727657233 547 /// CHECK-DAG: <<ConstB:j\d+>> LongConstant 4486011735248896 548 /// CHECK-DAG: <<ConstC:j\d+>> LongConstant -1071856711330889728 549 /// CHECK-DAG: <<ConstD:j\d+>> LongConstant 17587891077120 550 /// CHECK-DAG: <<ConstE:j\d+>> LongConstant -8808977924096 551 /// CHECK-DAG: <<ConstF:j\d+>> LongConstant 17587891077121 552 /// CHECK-DAG: <<ConstG:j\d+>> LongConstant 4095 553 /// CHECK: Add [<<Arg>>,<<ConstA>>] 554 /// CHECK-NEXT: adds r{{\d+}}, r{{\d+}}, #286331153 555 /// CHECK-NEXT: adc r{{\d+}}, r{{\d+}}, #1044480 556 /// CHECK: Add [<<Arg>>,<<ConstB>>] 557 /// CHECK-NEXT: subs r{{\d+}}, r{{\d+}}, #1044480 558 /// CHECK-NEXT: adc r{{\d+}}, r{{\d+}}, #1044480 559 /// CHECK: Add [<<Arg>>,<<ConstC>>] 560 /// CHECK-NEXT: subs r{{\d+}}, r{{\d+}}, #16711680 561 /// CHECK-NEXT: sbc r{{\d+}}, r{{\d+}}, #249561088 562 /// CHECK: Add [<<Arg>>,<<ConstD>>] 563 // There may or may not be a MOV here. 564 /// CHECK: add r{{\d+}}, r{{\d+}}, #4095 565 /// CHECK: Add [<<Arg>>,<<ConstE>>] 566 // There may or may not be a MOV here. 567 /// CHECK: sub r{{\d+}}, r{{\d+}}, #2051 568 /// CHECK: Add [<<Arg>>,<<ConstF>>] 569 /// CHECK-NEXT: adds{{(\.w)?}} r{{\d+}}, r{{\d+}}, r{{\d+}} 570 /// CHECK-NEXT: adc{{(\.w)?}} r{{\d+}}, r{{\d+}}, r{{\d+}} 571 /// CHECK: Add [<<Arg>>,<<ConstG>>] 572 /// CHECK-NEXT: adds{{(\.w)?}} r{{\d+}}, r{{\d+}}, r{{\d+}} 573 /// CHECK-NEXT: adc{{(\.w)?}} r{{\d+}}, r{{\d+}}, r{{\d+}} 574 575 public static long addLongConstants(long arg) { 576 return 577 // Modified immediates. 578 (arg + 0x000ff00011111111L) ^ // 4486007727657233 579 // Modified immediates high and -low. 580 (arg + 0x000ff000fff01000L) ^ // 4486011735248896 581 // Modified immediates ~high and -low. 582 (arg + 0xf11fffffff010000L) ^ // -1071856711330889728 583 // Low word 0 (no carry), high is imm12. 584 (arg + 0x00000fff00000000L) ^ // 17587891077120 585 // Low word 0 (no carry), -high is imm12. 586 (arg + 0xfffff7fd00000000L) ^ // -8808977924096 587 // Cannot embed imm12 in ADC/SBC for high word. 588 (arg + 0x00000fff00000001L) ^ // 17587891077121 589 // Cannot embed imm12 in ADDS/SUBS for low word (need to set flags). 590 (arg + 0x0000000000000fffL) ^ // 4095 591 arg; 592 } 593 594 /** 595 * ARM: Test that some long constants are not synthesized in a register for add-long. 596 * Also test some negative cases where we do synthetize constants in registers. 597 */ 598 599 /// CHECK-START-ARM: long Main.subLongConstants(long) disassembly (after) 600 /// CHECK: <<Arg:j\d+>> ParameterValue 601 /// CHECK-DAG: <<ConstA:j\d+>> LongConstant 4486007727657233 602 /// CHECK-DAG: <<ConstB:j\d+>> LongConstant 4486011735248896 603 /// CHECK-DAG: <<ConstC:j\d+>> LongConstant -1071856711330889728 604 /// CHECK-DAG: <<ConstD:j\d+>> LongConstant 17587891077120 605 /// CHECK-DAG: <<ConstE:j\d+>> LongConstant -8808977924096 606 /// CHECK-DAG: <<ConstF:j\d+>> LongConstant 17587891077121 607 /// CHECK-DAG: <<ConstG:j\d+>> LongConstant 4095 608 /// CHECK: Sub [<<Arg>>,<<ConstA>>] 609 /// CHECK-NEXT: subs r{{\d+}}, r{{\d+}}, #286331153 610 /// CHECK-NEXT: sbc r{{\d+}}, r{{\d+}}, #1044480 611 /// CHECK: Sub [<<Arg>>,<<ConstB>>] 612 /// CHECK-NEXT: adds r{{\d+}}, r{{\d+}}, #1044480 613 /// CHECK-NEXT: sbc r{{\d+}}, r{{\d+}}, #1044480 614 /// CHECK: Sub [<<Arg>>,<<ConstC>>] 615 /// CHECK-NEXT: adds r{{\d+}}, r{{\d+}}, #16711680 616 /// CHECK-NEXT: adc r{{\d+}}, r{{\d+}}, #249561088 617 /// CHECK: Sub [<<Arg>>,<<ConstD>>] 618 // There may or may not be a MOV here. 619 /// CHECK: sub r{{\d+}}, r{{\d+}}, #4095 620 /// CHECK: Sub [<<Arg>>,<<ConstE>>] 621 // There may or may not be a MOV here. 622 /// CHECK: add r{{\d+}}, r{{\d+}}, #2051 623 /// CHECK: Sub [<<Arg>>,<<ConstF>>] 624 /// CHECK-NEXT: subs{{(\.w)?}} r{{\d+}}, r{{\d+}}, r{{\d+}} 625 /// CHECK-NEXT: sbc{{(\.w)?}} r{{\d+}}, r{{\d+}}, r{{\d+}} 626 /// CHECK: Sub [<<Arg>>,<<ConstG>>] 627 /// CHECK-NEXT: subs{{(\.w)?}} r{{\d+}}, r{{\d+}}, r{{\d+}} 628 /// CHECK-NEXT: sbc{{(\.w)?}} r{{\d+}}, r{{\d+}}, r{{\d+}} 629 630 public static long subLongConstants(long arg) { 631 return 632 // Modified immediates. 633 (arg - 0x000ff00011111111L) ^ // 4486007727657233 634 // Modified immediates high and -low. 635 (arg - 0x000ff000fff01000L) ^ // 4486011735248896 636 // Modified immediates ~high and -low. 637 (arg - 0xf11fffffff010000L) ^ // -1071856711330889728 638 // Low word 0 (no carry), high is imm12. 639 (arg - 0x00000fff00000000L) ^ // 17587891077120 640 // Low word 0 (no carry), -high is imm12. 641 (arg - 0xfffff7fd00000000L) ^ // -8808977924096 642 // Cannot embed imm12 in ADC/SBC for high word. 643 (arg - 0x00000fff00000001L) ^ // 17587891077121 644 // Cannot embed imm12 in ADDS/SUBS for low word (need to set flags). 645 (arg - 0x0000000000000fffL) ^ // 4095 646 arg; 647 } 648 649 public static void main(String[] args) { 650 int arg = 0x87654321; 651 assertIntEquals(and255(arg), 0x21); 652 assertIntEquals(and511(arg), 0x121); 653 assertIntEquals(andF00D(arg), 0x4001); 654 assertIntEquals(andNot15(arg), 0x87654320); 655 assertIntEquals(or255(arg), 0x876543ff); 656 assertIntEquals(or511(arg), 0x876543ff); 657 assertIntEquals(orNot15(arg), 0xfffffff1); 658 assertIntEquals(xor255(arg), 0x876543de); 659 assertIntEquals(xor511(arg), 0x876542de); 660 assertIntEquals(xorNot15(arg), 0x789abcd1); 661 662 long longArg = 0x1234567887654321L; 663 assertLongEquals(and255(longArg), 0x21L); 664 assertLongEquals(and511(longArg), 0x121L); 665 assertLongEquals(andF00D(longArg), 0x4001L); 666 assertLongEquals(andNot15(longArg), 0x1234567887654320L); 667 assertLongEquals(and0xfffffff00000000f(longArg), 0x1234567000000001L); 668 assertLongEquals(or255(longArg), 0x12345678876543ffL); 669 assertLongEquals(or511(longArg), 0x12345678876543ffL); 670 assertLongEquals(orNot15(longArg), 0xfffffffffffffff1L); 671 assertLongEquals(or0xfffffff00000000f(longArg), 0xfffffff88765432fL); 672 assertLongEquals(xor255(longArg), 0x12345678876543deL); 673 assertLongEquals(xor511(longArg), 0x12345678876542deL); 674 assertLongEquals(xorNot15(longArg), 0xedcba987789abcd1L); 675 assertLongEquals(xor0xfffffff00000000f(longArg), 0xedcba9888765432eL); 676 assertLongEquals(xor0xf00000000000000f(longArg), 0xe23456788765432eL); 677 678 assertLongEquals(14L, addM1(7)); 679 680 assertLongEquals(shl1(longArg), 0x2468acf10eca8642L); 681 assertLongEquals(shl2(longArg), 0x48d159e21d950c84L); 682 assertLongEquals(shl31(longArg), 0x43b2a19080000000L); 683 assertLongEquals(shl32(longArg), 0x8765432100000000L); 684 assertLongEquals(shl33(longArg), 0x0eca864200000000L); 685 assertLongEquals(shl63(longArg), 0x8000000000000000L); 686 assertLongEquals(shl1(~longArg), 0xdb97530ef13579bcL); 687 assertLongEquals(shl2(~longArg), 0xb72ea61de26af378L); 688 assertLongEquals(shl31(~longArg), 0xbc4d5e6f00000000L); 689 assertLongEquals(shl32(~longArg), 0x789abcde00000000L); 690 assertLongEquals(shl33(~longArg), 0xf13579bc00000000L); 691 assertLongEquals(shl63(~longArg), 0x0000000000000000L); 692 693 assertLongEquals(shr1(longArg), 0x091a2b3c43b2a190L); 694 assertLongEquals(shr2(longArg), 0x048d159e21d950c8L); 695 assertLongEquals(shr31(longArg), 0x000000002468acf1L); 696 assertLongEquals(shr32(longArg), 0x0000000012345678L); 697 assertLongEquals(shr33(longArg), 0x00000000091a2b3cL); 698 assertLongEquals(shr63(longArg), 0x0000000000000000L); 699 assertLongEquals(shr1(~longArg), 0xf6e5d4c3bc4d5e6fL); 700 assertLongEquals(shr2(~longArg), 0xfb72ea61de26af37L); 701 assertLongEquals(shr31(~longArg), 0xffffffffdb97530eL); 702 assertLongEquals(shr32(~longArg), 0xffffffffedcba987L); 703 assertLongEquals(shr33(~longArg), 0xfffffffff6e5d4c3L); 704 assertLongEquals(shr63(~longArg), 0xffffffffffffffffL); 705 706 assertLongEquals(ushr1(longArg), 0x091a2b3c43b2a190L); 707 assertLongEquals(ushr2(longArg), 0x048d159e21d950c8L); 708 assertLongEquals(ushr31(longArg), 0x000000002468acf1L); 709 assertLongEquals(ushr32(longArg), 0x0000000012345678L); 710 assertLongEquals(ushr33(longArg), 0x00000000091a2b3cL); 711 assertLongEquals(ushr63(longArg), 0x0000000000000000L); 712 assertLongEquals(ushr1(~longArg), 0x76e5d4c3bc4d5e6fL); 713 assertLongEquals(ushr2(~longArg), 0x3b72ea61de26af37L); 714 assertLongEquals(ushr31(~longArg), 0x00000001db97530eL); 715 assertLongEquals(ushr32(~longArg), 0x00000000edcba987L); 716 assertLongEquals(ushr33(~longArg), 0x0000000076e5d4c3L); 717 assertLongEquals(ushr63(~longArg), 0x0000000000000001L); 718 719 // Test -1, 0, +1 and arbitrary constants just before and after overflow 720 // on low word in subexpressions of addLongConstants()/subLongConstants(), 721 // so that we check that we carry the overflow correctly to the high word. 722 // For example 723 // 0x111eeeeeeee+0x000ff00011111111 = 0x000ff111ffffffff (carry=0), 724 // 0x111eeeeeeef+0x000ff00011111111 = 0x000ff11200000000 (carry=1). 725 assertLongEquals(0xf11ff7fdee1e1111L, addLongConstants(0xffffffffffffffffL)); 726 assertLongEquals(0xee0080211e00eefL, addLongConstants(0x0L)); 727 assertLongEquals(0xee0080211e01111L, addLongConstants(0x1L)); 728 assertLongEquals(0xedff81c12201113L, addLongConstants(0x111eeeeeeeeL)); 729 assertLongEquals(0xedff81feddfeef1L, addLongConstants(0x111eeeeeeefL)); 730 assertLongEquals(0xedff83e11c1f111L, addLongConstants(0x222000fefffL)); 731 assertLongEquals(0xedff83fee3e0eefL, addLongConstants(0x222000ff000L)); 732 assertLongEquals(0xedff805edfe1111L, addLongConstants(0x33300feffffL)); 733 assertLongEquals(0xedff80412000eefL, addLongConstants(0x33300ff0000L)); 734 assertLongEquals(0xee0080211e00eefL, subLongConstants(0xffffffffffffffffL)); 735 assertLongEquals(0xf11ff7fdee1e1111L, subLongConstants(0x0L)); 736 assertLongEquals(0xf11ff7fc11e1eef3L, subLongConstants(0x1L)); 737 assertLongEquals(0xee0080412201113L, subLongConstants(0x44411111111L)); 738 assertLongEquals(0xee0080412201111L, subLongConstants(0x44411111112L)); 739 assertLongEquals(0xee0080e11c1f111L, subLongConstants(0x555fff01000L)); 740 assertLongEquals(0xee0080e11c1eef3L, subLongConstants(0x555fff01001L)); 741 assertLongEquals(0xee0080dedfe1111L, subLongConstants(0x666ff010000L)); 742 assertLongEquals(0xee0080dedffeef3L, subLongConstants(0x666ff010001L)); 743 } 744 } 745