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 assertIntEquals(int expected, int actual)19 public static void assertIntEquals(int expected, int actual) { 20 if (expected != actual) { 21 throw new Error("Expected: " + expected + ", found: " + actual); 22 } 23 } 24 assertLongEquals(long expected, long actual)25 public static void assertLongEquals(long expected, long actual) { 26 if (expected != actual) { 27 throw new Error("Expected: " + expected + ", found: " + actual); 28 } 29 } 30 31 /// CHECK-START: int Main.rotateIntegerRight(int, int) instruction_simplifier (before) 32 /// CHECK: <<ArgValue:i\d+>> ParameterValue 33 /// CHECK: <<ArgDistance:i\d+>> ParameterValue 34 /// CHECK: <<Invoke:i\d+>> InvokeStaticOrDirect intrinsic:IntegerRotateRight 35 36 /// CHECK-START: int Main.rotateIntegerRight(int, int) instruction_simplifier (after) 37 /// CHECK: <<ArgValue:i\d+>> ParameterValue 38 /// CHECK: <<ArgDistance:i\d+>> ParameterValue 39 /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<ArgDistance>>] 40 /// CHECK: Return [<<Ror>>] 41 42 /// CHECK-START: int Main.rotateIntegerRight(int, int) instruction_simplifier (after) 43 /// CHECK-NOT: LoadClass 44 /// CHECK-NOT: ClinitCheck 45 /// CHECK-NOT: InvokeStaticOrDirect rotateIntegerRight(int value, int distance)46 public static int rotateIntegerRight(int value, int distance) { 47 return java.lang.Integer.rotateRight(value, distance); 48 } 49 50 /// CHECK-START: int Main.rotateIntegerLeft(int, int) instruction_simplifier (before) 51 /// CHECK: <<ArgValue:i\d+>> ParameterValue 52 /// CHECK: <<ArgDistance:i\d+>> ParameterValue 53 /// CHECK: <<Invoke:i\d+>> InvokeStaticOrDirect intrinsic:IntegerRotateLeft 54 55 /// CHECK-START: int Main.rotateIntegerLeft(int, int) instruction_simplifier (after) 56 /// CHECK: <<ArgValue:i\d+>> ParameterValue 57 /// CHECK: <<ArgDistance:i\d+>> ParameterValue 58 /// CHECK: <<Neg:i\d+>> Neg [<<ArgDistance>>] 59 /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<Neg>>] 60 /// CHECK: Return [<<Ror>>] 61 62 /// CHECK-START: int Main.rotateIntegerLeft(int, int) instruction_simplifier (after) 63 /// CHECK-NOT: LoadClass 64 /// CHECK-NOT: ClinitCheck 65 /// CHECK-NOT: InvokeStaticOrDirect rotateIntegerLeft(int value, int distance)66 public static int rotateIntegerLeft(int value, int distance) { 67 return java.lang.Integer.rotateLeft(value, distance); 68 } 69 70 /// CHECK-START: long Main.rotateLongRight(long, int) instruction_simplifier (before) 71 /// CHECK: <<ArgValue:j\d+>> ParameterValue 72 /// CHECK: <<ArgDistance:i\d+>> ParameterValue 73 /// CHECK: <<Invoke:j\d+>> InvokeStaticOrDirect intrinsic:LongRotateRight 74 75 /// CHECK-START: long Main.rotateLongRight(long, int) instruction_simplifier (after) 76 /// CHECK: <<ArgValue:j\d+>> ParameterValue 77 /// CHECK: <<ArgDistance:i\d+>> ParameterValue 78 /// CHECK: <<Ror:j\d+>> Ror [<<ArgValue>>,<<ArgDistance>>] 79 /// CHECK: Return [<<Ror>>] 80 81 /// CHECK-START: long Main.rotateLongRight(long, int) instruction_simplifier (after) 82 /// CHECK-NOT: LoadClass 83 /// CHECK-NOT: ClinitCheck 84 /// CHECK-NOT: InvokeStaticOrDirect rotateLongRight(long value, int distance)85 public static long rotateLongRight(long value, int distance) { 86 return java.lang.Long.rotateRight(value, distance); 87 } 88 89 /// CHECK-START: long Main.rotateLongLeft(long, int) instruction_simplifier (before) 90 /// CHECK: <<ArgValue:j\d+>> ParameterValue 91 /// CHECK: <<ArgDistance:i\d+>> ParameterValue 92 /// CHECK: <<Invoke:j\d+>> InvokeStaticOrDirect intrinsic:LongRotateLeft 93 94 /// CHECK-START: long Main.rotateLongLeft(long, int) instruction_simplifier (after) 95 /// CHECK: <<ArgValue:j\d+>> ParameterValue 96 /// CHECK: <<ArgDistance:i\d+>> ParameterValue 97 /// CHECK: <<Neg:i\d+>> Neg [<<ArgDistance>>] 98 /// CHECK: <<Ror:j\d+>> Ror [<<ArgValue>>,<<Neg>>] 99 /// CHECK: Return [<<Ror>>] 100 101 /// CHECK-START: long Main.rotateLongLeft(long, int) instruction_simplifier (after) 102 /// CHECK-NOT: LoadClass 103 /// CHECK-NOT: ClinitCheck 104 /// CHECK-NOT: InvokeStaticOrDirect rotateLongLeft(long value, int distance)105 public static long rotateLongLeft(long value, int distance) { 106 return java.lang.Long.rotateLeft(value, distance); 107 } 108 109 // (i >>> #distance) | (i << #(reg_bits - distance)) 110 111 /// CHECK-START: int Main.ror_int_constant_c_c(int) instruction_simplifier (before) 112 /// CHECK: <<ArgValue:i\d+>> ParameterValue 113 /// CHECK: <<Const2:i\d+>> IntConstant 2 114 /// CHECK: <<Const30:i\d+>> IntConstant 30 115 /// CHECK-DAG: <<UShr:i\d+>> UShr [<<ArgValue>>,<<Const2>>] 116 /// CHECK-DAG: <<Shl:i\d+>> Shl [<<ArgValue>>,<<Const30>>] 117 /// CHECK: <<Or:i\d+>> Or [<<UShr>>,<<Shl>>] 118 /// CHECK: Return [<<Or>>] 119 120 /// CHECK-START: int Main.ror_int_constant_c_c(int) instruction_simplifier (after) 121 /// CHECK: <<ArgValue:i\d+>> ParameterValue 122 /// CHECK: <<Const2:i\d+>> IntConstant 2 123 /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<Const2>>] 124 /// CHECK: Return [<<Ror>>] 125 126 /// CHECK-START: int Main.ror_int_constant_c_c(int) instruction_simplifier (after) 127 /// CHECK-NOT: UShr 128 /// CHECK-NOT: Shl ror_int_constant_c_c(int value)129 public static int ror_int_constant_c_c(int value) { 130 return (value >>> 2) | (value << 30); 131 } 132 133 /// CHECK-START: int Main.ror_int_constant_c_c_0(int) instruction_simplifier (after) 134 /// CHECK: <<ArgValue:i\d+>> ParameterValue 135 /// CHECK: <<Const2:i\d+>> IntConstant 2 136 /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<Const2>>] 137 /// CHECK: Return [<<Ror>>] 138 139 /// CHECK-START: int Main.ror_int_constant_c_c_0(int) instruction_simplifier (after) 140 /// CHECK-NOT: UShr 141 /// CHECK-NOT: Shl ror_int_constant_c_c_0(int value)142 public static int ror_int_constant_c_c_0(int value) { 143 return (value >>> 2) | (value << 62); 144 } 145 146 // (j >>> #distance) | (j << #(reg_bits - distance)) 147 148 /// CHECK-START: long Main.ror_long_constant_c_c(long) instruction_simplifier (before) 149 /// CHECK: <<ArgValue:j\d+>> ParameterValue 150 /// CHECK: <<Const2:i\d+>> IntConstant 2 151 /// CHECK: <<Const62:i\d+>> IntConstant 62 152 /// CHECK-DAG: <<UShr:j\d+>> UShr [<<ArgValue>>,<<Const2>>] 153 /// CHECK-DAG: <<Shl:j\d+>> Shl [<<ArgValue>>,<<Const62>>] 154 /// CHECK: <<Or:j\d+>> Or [<<UShr>>,<<Shl>>] 155 /// CHECK: Return [<<Or>>] 156 157 /// CHECK-START: long Main.ror_long_constant_c_c(long) instruction_simplifier (after) 158 /// CHECK: <<ArgValue:j\d+>> ParameterValue 159 /// CHECK: <<Const2:i\d+>> IntConstant 2 160 /// CHECK: <<Ror:j\d+>> Ror [<<ArgValue>>,<<Const2>>] 161 /// CHECK: Return [<<Ror>>] 162 163 /// CHECK-START: long Main.ror_long_constant_c_c(long) instruction_simplifier (after) 164 /// CHECK-NOT: UShr 165 /// CHECK-NOT: Shl ror_long_constant_c_c(long value)166 public static long ror_long_constant_c_c(long value) { 167 return (value >>> 2) | (value << 62); 168 } 169 170 /// CHECK-START: long Main.ror_long_constant_c_c_0(long) instruction_simplifier (after) 171 /// CHECK-NOT: Ror ror_long_constant_c_c_0(long value)172 public static long ror_long_constant_c_c_0(long value) { 173 return (value >>> 2) | (value << 30); 174 } 175 176 // (i >>> #distance) | (i << #-distance) 177 178 /// CHECK-START: int Main.ror_int_constant_c_negc(int) instruction_simplifier$after_inlining (before) 179 /// CHECK: <<ArgValue:i\d+>> ParameterValue 180 /// CHECK: <<Const2:i\d+>> IntConstant 2 181 /// CHECK: <<ConstNeg2:i\d+>> IntConstant -2 182 /// CHECK-DAG: <<UShr:i\d+>> UShr [<<ArgValue>>,<<Const2>>] 183 /// CHECK-DAG: <<Shl:i\d+>> Shl [<<ArgValue>>,<<ConstNeg2>>] 184 /// CHECK: <<Or:i\d+>> Or [<<UShr>>,<<Shl>>] 185 /// CHECK: Return [<<Or>>] 186 187 /// CHECK-START: int Main.ror_int_constant_c_negc(int) instruction_simplifier$after_inlining (after) 188 /// CHECK: <<ArgValue:i\d+>> ParameterValue 189 /// CHECK: <<Const2:i\d+>> IntConstant 2 190 /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<Const2>>] 191 /// CHECK: Return [<<Ror>>] 192 193 /// CHECK-START: int Main.ror_int_constant_c_negc(int) instruction_simplifier$after_inlining (after) 194 /// CHECK-NOT: UShr 195 /// CHECK-NOT: Shl ror_int_constant_c_negc(int value)196 public static int ror_int_constant_c_negc(int value) { 197 return (value >>> 2) | (value << $opt$inline$IntConstantM2()); 198 } 199 200 // Hiding constants outside the range [0, 32) used for int shifts from Jack. 201 // (Jack extracts only the low 5 bits.) $opt$inline$IntConstantM2()202 public static int $opt$inline$IntConstantM2() { return -2; } 203 204 // (j >>> #distance) | (j << #-distance) 205 206 /// CHECK-START: long Main.ror_long_constant_c_negc(long) instruction_simplifier (before) 207 /// CHECK: <<ArgValue:j\d+>> ParameterValue 208 /// CHECK: <<Const2:i\d+>> IntConstant 2 209 /// CHECK: <<ConstNeg2:i\d+>> IntConstant -2 210 /// CHECK-DAG: <<UShr:j\d+>> UShr [<<ArgValue>>,<<Const2>>] 211 /// CHECK-DAG: <<Shl:j\d+>> Shl [<<ArgValue>>,<<ConstNeg2>>] 212 /// CHECK: <<Or:j\d+>> Or [<<UShr>>,<<Shl>>] 213 /// CHECK: Return [<<Or>>] 214 215 /// CHECK-START: long Main.ror_long_constant_c_negc(long) instruction_simplifier (after) 216 /// CHECK: <<ArgValue:j\d+>> ParameterValue 217 /// CHECK: <<Const2:i\d+>> IntConstant 2 218 /// CHECK: <<Ror:j\d+>> Ror [<<ArgValue>>,<<Const2>>] 219 /// CHECK: Return [<<Ror>>] 220 221 /// CHECK-START: long Main.ror_long_constant_c_negc(long) instruction_simplifier (after) 222 /// CHECK-NOT: UShr 223 /// CHECK-NOT: Shl ror_long_constant_c_negc(long value)224 public static long ror_long_constant_c_negc(long value) { 225 return (value >>> 2) | (value << -2); 226 } 227 228 // (i >>> distance) | (i << (#reg_bits - distance) 229 230 /// CHECK-START: int Main.ror_int_reg_v_csubv(int, int) instruction_simplifier (before) 231 /// CHECK: <<ArgValue:i\d+>> ParameterValue 232 /// CHECK: <<ArgDistance:i\d+>> ParameterValue 233 /// CHECK: <<Const32:i\d+>> IntConstant 32 234 /// CHECK-DAG: <<UShr:i\d+>> UShr [<<ArgValue>>,<<ArgDistance>>] 235 /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Const32>>,<<ArgDistance>>] 236 /// CHECK-DAG: <<Shl:i\d+>> Shl [<<ArgValue>>,<<Sub>>] 237 /// CHECK: <<Or:i\d+>> Or [<<UShr>>,<<Shl>>] 238 /// CHECK: Return [<<Or>>] 239 240 /// CHECK-START: int Main.ror_int_reg_v_csubv(int, int) instruction_simplifier (after) 241 /// CHECK: <<ArgValue:i\d+>> ParameterValue 242 /// CHECK: <<ArgDistance:i\d+>> ParameterValue 243 /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<ArgDistance>>] 244 /// CHECK: Return [<<Ror>>] 245 246 /// CHECK-START: int Main.ror_int_reg_v_csubv(int, int) instruction_simplifier (after) 247 /// CHECK-NOT: UShr 248 /// CHECK-NOT: Shl 249 /// CHECK-NOT: Sub ror_int_reg_v_csubv(int value, int distance)250 public static int ror_int_reg_v_csubv(int value, int distance) { 251 return (value >>> distance) | (value << (32 - distance)); 252 } 253 254 // (distance = x - y) 255 // (i >>> distance) | (i << (#reg_bits - distance) 256 257 /// CHECK-START: int Main.ror_int_subv_csubv(int, int, int) instruction_simplifier (before) 258 /// CHECK: <<ArgValue:i\d+>> ParameterValue 259 /// CHECK: <<ArgX:i\d+>> ParameterValue 260 /// CHECK: <<ArgY:i\d+>> ParameterValue 261 /// CHECK: <<Const32:i\d+>> IntConstant 32 262 /// CHECK-DAG: <<SubDistance:i\d+>> Sub [<<ArgX>>,<<ArgY>>] 263 /// CHECK-DAG: <<Sub32:i\d+>> Sub [<<Const32>>,<<SubDistance>>] 264 /// CHECK-DAG: <<Shl:i\d+>> Shl [<<ArgValue>>,<<Sub32>>] 265 /// CHECK-DAG: <<UShr:i\d+>> UShr [<<ArgValue>>,<<SubDistance>>] 266 /// CHECK: <<Or:i\d+>> Or [<<UShr>>,<<Shl>>] 267 /// CHECK: Return [<<Or>>] 268 269 /// CHECK-START: int Main.ror_int_subv_csubv(int, int, int) instruction_simplifier (after) 270 /// CHECK: <<ArgValue:i\d+>> ParameterValue 271 /// CHECK: <<ArgX:i\d+>> ParameterValue 272 /// CHECK: <<ArgY:i\d+>> ParameterValue 273 /// CHECK: <<SubDistance:i\d+>> Sub [<<ArgX>>,<<ArgY>>] 274 /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<SubDistance>>] 275 /// CHECK: Return [<<Ror>>] 276 277 /// CHECK-START: int Main.ror_int_subv_csubv(int, int, int) instruction_simplifier (after) 278 /// CHECK: Sub 279 /// CHECK-NOT: Sub 280 281 /// CHECK-START: int Main.ror_int_subv_csubv(int, int, int) instruction_simplifier (after) 282 /// CHECK-NOT: UShr 283 /// CHECK-NOT: Shl ror_int_subv_csubv(int value, int x, int y)284 public static int ror_int_subv_csubv(int value, int x, int y) { 285 int distance = x - y; 286 return (value >>> distance) | (value << (32 - distance)); 287 } 288 289 /// CHECK-START: int Main.ror_int_subv_csubv_env(int, int, int) instruction_simplifier (before) 290 /// CHECK: <<ArgValue:i\d+>> ParameterValue 291 /// CHECK: <<ArgX:i\d+>> ParameterValue 292 /// CHECK: <<ArgY:i\d+>> ParameterValue 293 /// CHECK: <<Const32:i\d+>> IntConstant 32 294 /// CHECK-DAG: <<SubDistance:i\d+>> Sub [<<ArgX>>,<<ArgY>>] 295 /// CHECK-DAG: <<Sub32:i\d+>> Sub [<<Const32>>,<<SubDistance>>] 296 /// CHECK-DAG: <<UShr:i\d+>> UShr [<<ArgValue>>,<<SubDistance>>] 297 /// CHECK-DAG: <<Shl:i\d+>> Shl [<<ArgValue>>,<<Sub32>>] 298 /// CHECK: <<Or:i\d+>> Or [<<UShr>>,<<Shl>>] 299 /// CHECK: <<Add:i\d+>> Add [<<Or>>,<<Sub32>>] 300 /// CHECK: Return [<<Add>>] 301 302 /// CHECK-START: int Main.ror_int_subv_csubv_env(int, int, int) instruction_simplifier (after) 303 /// CHECK: <<ArgValue:i\d+>> ParameterValue 304 /// CHECK: <<ArgX:i\d+>> ParameterValue 305 /// CHECK: <<ArgY:i\d+>> ParameterValue 306 /// CHECK: <<Const32:i\d+>> IntConstant 32 307 /// CHECK-DAG: <<SubDistance:i\d+>> Sub [<<ArgX>>,<<ArgY>>] 308 /// CHECK-DAG: <<Sub32:i\d+>> Sub [<<Const32>>,<<SubDistance>>] 309 /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<SubDistance>>] 310 /// CHECK: <<Add:i\d+>> Add [<<Ror>>,<<Sub32>>] 311 /// CHECK: Return [<<Add>>] 312 313 /// CHECK-START: int Main.ror_int_subv_csubv_env(int, int, int) instruction_simplifier (after) 314 /// CHECK-NOT: UShr 315 /// CHECK-NOT: Shl ror_int_subv_csubv_env(int value, int x, int y)316 public static int ror_int_subv_csubv_env(int value, int x, int y) { 317 int distance = x - y; 318 int bits_minus_dist = 32 - distance; 319 return ((value >>> distance) | (value << bits_minus_dist)) + bits_minus_dist; 320 } 321 322 // (j >>> distance) | (j << (#reg_bits - distance) 323 324 /// CHECK-START: long Main.ror_long_reg_v_csubv(long, int) instruction_simplifier (before) 325 /// CHECK: <<ArgValue:j\d+>> ParameterValue 326 /// CHECK: <<ArgDistance:i\d+>> ParameterValue 327 /// CHECK: <<Const64:i\d+>> IntConstant 64 328 /// CHECK-DAG: <<UShr:j\d+>> UShr [<<ArgValue>>,<<ArgDistance>>] 329 /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Const64>>,<<ArgDistance>>] 330 /// CHECK-DAG: <<Shl:j\d+>> Shl [<<ArgValue>>,<<Sub>>] 331 /// CHECK: <<Or:j\d+>> Or [<<UShr>>,<<Shl>>] 332 /// CHECK: Return [<<Or>>] 333 334 /// CHECK-START: long Main.ror_long_reg_v_csubv(long, int) instruction_simplifier (after) 335 /// CHECK: <<ArgValue:j\d+>> ParameterValue 336 /// CHECK: <<ArgDistance:i\d+>> ParameterValue 337 /// CHECK: <<Ror:j\d+>> Ror [<<ArgValue>>,<<ArgDistance>>] 338 /// CHECK: Return [<<Ror>>] 339 340 /// CHECK-START: long Main.ror_long_reg_v_csubv(long, int) instruction_simplifier (after) 341 /// CHECK-NOT: UShr 342 /// CHECK-NOT: Shl 343 /// CHECK-NOT: Sub ror_long_reg_v_csubv(long value, int distance)344 public static long ror_long_reg_v_csubv(long value, int distance) { 345 return (value >>> distance) | (value << (64 - distance)); 346 } 347 348 /// CHECK-START: long Main.ror_long_reg_v_csubv_0(long, int) instruction_simplifier (after) 349 /// CHECK-NOT: Ror ror_long_reg_v_csubv_0(long value, int distance)350 public static long ror_long_reg_v_csubv_0(long value, int distance) { 351 return (value >>> distance) | (value << (32 - distance)); 352 } 353 354 /// CHECK-START: long Main.ror_long_subv_csubv_0(long, int, int) instruction_simplifier (after) 355 /// CHECK-NOT: Ror ror_long_subv_csubv_0(long value, int x, int y)356 public static long ror_long_subv_csubv_0(long value, int x, int y) { 357 int distance = x - y; 358 return (value >>> distance) | (value << (32 - distance)); 359 } 360 361 // (i >>> (#reg_bits - distance)) | (i << distance) 362 363 /// CHECK-START: int Main.rol_int_reg_csubv_v(int, int) instruction_simplifier (before) 364 /// CHECK: <<ArgValue:i\d+>> ParameterValue 365 /// CHECK: <<ArgDistance:i\d+>> ParameterValue 366 /// CHECK: <<Const32:i\d+>> IntConstant 32 367 /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Const32>>,<<ArgDistance>>] 368 /// CHECK-DAG: <<UShr:i\d+>> UShr [<<ArgValue>>,<<Sub>>] 369 /// CHECK-DAG: <<Shl:i\d+>> Shl [<<ArgValue>>,<<ArgDistance>>] 370 /// CHECK: <<Or:i\d+>> Or [<<UShr>>,<<Shl>>] 371 /// CHECK: Return [<<Or>>] 372 373 /// CHECK-START: int Main.rol_int_reg_csubv_v(int, int) instruction_simplifier (after) 374 /// CHECK: <<ArgValue:i\d+>> ParameterValue 375 /// CHECK: <<ArgDistance:i\d+>> ParameterValue 376 /// CHECK: <<Const32:i\d+>> IntConstant 32 377 /// CHECK: <<Sub:i\d+>> Sub [<<Const32>>,<<ArgDistance>>] 378 /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<Sub>>] 379 /// CHECK: Return [<<Ror>>] 380 381 /// CHECK-START: int Main.rol_int_reg_csubv_v(int, int) instruction_simplifier (after) 382 /// CHECK-NOT: UShr 383 /// CHECK-NOT: Shl rol_int_reg_csubv_v(int value, int distance)384 public static int rol_int_reg_csubv_v(int value, int distance) { 385 return (value >>> (32 - distance)) | (value << distance); 386 } 387 388 // (distance = x - y) 389 // (i >>> (#reg_bits - distance)) | (i << distance) 390 391 /// CHECK-START: int Main.rol_int_csubv_subv(int, int, int) instruction_simplifier (before) 392 /// CHECK: <<ArgValue:i\d+>> ParameterValue 393 /// CHECK: <<ArgX:i\d+>> ParameterValue 394 /// CHECK: <<ArgY:i\d+>> ParameterValue 395 /// CHECK: <<Const32:i\d+>> IntConstant 32 396 /// CHECK-DAG: <<SubDistance:i\d+>> Sub [<<ArgX>>,<<ArgY>>] 397 /// CHECK-DAG: <<Sub32:i\d+>> Sub [<<Const32>>,<<SubDistance>>] 398 /// CHECK-DAG: <<Shl:i\d+>> Shl [<<ArgValue>>,<<SubDistance>>] 399 /// CHECK-DAG: <<UShr:i\d+>> UShr [<<ArgValue>>,<<Sub32>>] 400 /// CHECK: <<Or:i\d+>> Or [<<UShr>>,<<Shl>>] 401 /// CHECK: Return [<<Or>>] 402 403 /// CHECK-START: int Main.rol_int_csubv_subv(int, int, int) instruction_simplifier (after) 404 /// CHECK: <<ArgValue:i\d+>> ParameterValue 405 /// CHECK: <<ArgX:i\d+>> ParameterValue 406 /// CHECK: <<ArgY:i\d+>> ParameterValue 407 /// CHECK: <<Const32:i\d+>> IntConstant 32 408 /// CHECK: <<SubDistance:i\d+>> Sub [<<ArgX>>,<<ArgY>>] 409 /// CHECK: <<Sub:i\d+>> Sub [<<Const32>>,<<SubDistance>>] 410 /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<Sub>>] 411 /// CHECK: Return [<<Ror>>] 412 413 /// CHECK-START: int Main.rol_int_csubv_subv(int, int, int) instruction_simplifier (after) 414 /// CHECK: Sub 415 /// CHECK: Sub 416 417 /// CHECK-START: int Main.rol_int_csubv_subv(int, int, int) instruction_simplifier (after) 418 /// CHECK-NOT: UShr 419 /// CHECK-NOT: Shl rol_int_csubv_subv(int value, int x, int y)420 public static int rol_int_csubv_subv(int value, int x, int y) { 421 int distance = x - y; 422 return (value >>> (32 - distance)) | (value << distance); 423 } 424 425 // (j >>> (#reg_bits - distance)) | (j << distance) 426 427 /// CHECK-START: long Main.rol_long_reg_csubv_v(long, int) instruction_simplifier (before) 428 /// CHECK: <<ArgValue:j\d+>> ParameterValue 429 /// CHECK: <<ArgDistance:i\d+>> ParameterValue 430 /// CHECK: <<Const64:i\d+>> IntConstant 64 431 /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Const64>>,<<ArgDistance>>] 432 /// CHECK-DAG: <<UShr:j\d+>> UShr [<<ArgValue>>,<<Sub>>] 433 /// CHECK-DAG: <<Shl:j\d+>> Shl [<<ArgValue>>,<<ArgDistance>>] 434 /// CHECK: <<Or:j\d+>> Or [<<UShr>>,<<Shl>>] 435 /// CHECK: Return [<<Or>>] 436 437 /// CHECK-START: long Main.rol_long_reg_csubv_v(long, int) instruction_simplifier (after) 438 /// CHECK: <<ArgValue:j\d+>> ParameterValue 439 /// CHECK: <<ArgDistance:i\d+>> ParameterValue 440 /// CHECK: <<Const64:i\d+>> IntConstant 64 441 /// CHECK: <<Sub:i\d+>> Sub [<<Const64>>,<<ArgDistance>>] 442 /// CHECK: <<Ror:j\d+>> Ror [<<ArgValue>>,<<Sub>>] 443 /// CHECK: Return [<<Ror>>] 444 445 /// CHECK-START: long Main.rol_long_reg_csubv_v(long, int) instruction_simplifier (after) 446 /// CHECK-NOT: UShr 447 /// CHECK-NOT: Shl rol_long_reg_csubv_v(long value, int distance)448 public static long rol_long_reg_csubv_v(long value, int distance) { 449 return (value >>> (64 - distance)) | (value << distance); 450 } 451 452 /// CHECK-START: long Main.rol_long_reg_csubv_v_0(long, int) instruction_simplifier (after) 453 /// CHECK-NOT: Ror rol_long_reg_csubv_v_0(long value, int distance)454 public static long rol_long_reg_csubv_v_0(long value, int distance) { 455 return (value >>> (32 - distance)) | (value << distance); 456 } 457 458 // (i >>> distance) | (i << -distance) (i.e. libcore's Integer.rotateRight) 459 460 /// CHECK-START: int Main.ror_int_reg_v_negv(int, int) instruction_simplifier (before) 461 /// CHECK: <<ArgValue:i\d+>> ParameterValue 462 /// CHECK: <<ArgDistance:i\d+>> ParameterValue 463 /// CHECK-DAG: <<UShr:i\d+>> UShr [<<ArgValue>>,<<ArgDistance>>] 464 /// CHECK-DAG: <<Neg:i\d+>> Neg [<<ArgDistance>>] 465 /// CHECK-DAG: <<Shl:i\d+>> Shl [<<ArgValue>>,<<Neg>>] 466 /// CHECK: <<Or:i\d+>> Or [<<UShr>>,<<Shl>>] 467 /// CHECK: Return [<<Or>>] 468 469 /// CHECK-START: int Main.ror_int_reg_v_negv(int, int) instruction_simplifier (after) 470 /// CHECK: <<ArgValue:i\d+>> ParameterValue 471 /// CHECK: <<ArgDistance:i\d+>> ParameterValue 472 /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<ArgDistance>>] 473 /// CHECK: Return [<<Ror>>] 474 475 /// CHECK-START: int Main.ror_int_reg_v_negv(int, int) instruction_simplifier (after) 476 /// CHECK-NOT: UShr 477 /// CHECK-NOT: Shl 478 /// CHECK-NOT: Neg ror_int_reg_v_negv(int value, int distance)479 public static int ror_int_reg_v_negv(int value, int distance) { 480 return (value >>> distance) | (value << -distance); 481 } 482 483 /// CHECK-START: int Main.ror_int_reg_v_negv_env(int, int) instruction_simplifier (before) 484 /// CHECK: <<ArgValue:i\d+>> ParameterValue 485 /// CHECK: <<ArgDistance:i\d+>> ParameterValue 486 /// CHECK-DAG: <<Neg:i\d+>> Neg [<<ArgDistance>>] 487 /// CHECK-DAG: <<UShr:i\d+>> UShr [<<ArgValue>>,<<ArgDistance>>] 488 /// CHECK-DAG: <<Shl:i\d+>> Shl [<<ArgValue>>,<<Neg>>] 489 /// CHECK: <<Or:i\d+>> Or [<<UShr>>,<<Shl>>] 490 /// CHECK: <<Add:i\d+>> Add [<<Or>>,<<Neg>>] 491 /// CHECK: Return [<<Add>>] 492 493 /// CHECK-START: int Main.ror_int_reg_v_negv_env(int, int) instruction_simplifier (after) 494 /// CHECK: <<ArgValue:i\d+>> ParameterValue 495 /// CHECK: <<ArgDistance:i\d+>> ParameterValue 496 /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<ArgDistance>>] 497 /// CHECK: <<Sub:i\d+>> Sub [<<Ror>>,<<ArgDistance>>] 498 /// CHECK: Return [<<Sub>>] 499 500 /// CHECK-START: int Main.ror_int_reg_v_negv_env(int, int) instruction_simplifier (after) 501 /// CHECK-NOT: UShr 502 /// CHECK-NOT: Shl ror_int_reg_v_negv_env(int value, int distance)503 public static int ror_int_reg_v_negv_env(int value, int distance) { 504 int neg_distance = -distance; 505 return ((value >>> distance) | (value << neg_distance)) + neg_distance; 506 } 507 508 // (j >>> distance) | (j << -distance) (i.e. libcore's Long.rotateRight) 509 510 /// CHECK-START: long Main.ror_long_reg_v_negv(long, int) instruction_simplifier (before) 511 /// CHECK: <<ArgValue:j\d+>> ParameterValue 512 /// CHECK: <<ArgDistance:i\d+>> ParameterValue 513 /// CHECK-DAG: <<UShr:j\d+>> UShr [<<ArgValue>>,<<ArgDistance>>] 514 /// CHECK-DAG: <<Neg:i\d+>> Neg [<<ArgDistance>>] 515 /// CHECK-DAG: <<Shl:j\d+>> Shl [<<ArgValue>>,<<Neg>>] 516 /// CHECK: <<Or:j\d+>> Or [<<UShr>>,<<Shl>>] 517 /// CHECK: Return [<<Or>>] 518 519 /// CHECK-START: long Main.ror_long_reg_v_negv(long, int) instruction_simplifier (after) 520 /// CHECK: <<ArgValue:j\d+>> ParameterValue 521 /// CHECK: <<ArgDistance:i\d+>> ParameterValue 522 /// CHECK: <<Ror:j\d+>> Ror [<<ArgValue>>,<<ArgDistance>>] 523 /// CHECK: Return [<<Ror>>] 524 525 /// CHECK-START: long Main.ror_long_reg_v_negv(long, int) instruction_simplifier (after) 526 /// CHECK-NOT: UShr 527 /// CHECK-NOT: Shl 528 /// CHECK-NOT: Neg ror_long_reg_v_negv(long value, int distance)529 public static long ror_long_reg_v_negv(long value, int distance) { 530 return (value >>> distance) | (value << -distance); 531 } 532 533 // (i << distance) | (i >>> -distance) (i.e. libcore's Integer.rotateLeft) 534 535 /// CHECK-START: int Main.rol_int_reg_negv_v(int, int) instruction_simplifier (before) 536 /// CHECK: <<ArgValue:i\d+>> ParameterValue 537 /// CHECK: <<ArgDistance:i\d+>> ParameterValue 538 /// CHECK-DAG: <<Neg:i\d+>> Neg [<<ArgDistance>>] 539 /// CHECK-DAG: <<UShr:i\d+>> UShr [<<ArgValue>>,<<Neg>>] 540 /// CHECK-DAG: <<Shl:i\d+>> Shl [<<ArgValue>>,<<ArgDistance>>] 541 /// CHECK: <<Or:i\d+>> Or [<<Shl>>,<<UShr>>] 542 /// CHECK: Return [<<Or>>] 543 544 /// CHECK-START: int Main.rol_int_reg_negv_v(int, int) instruction_simplifier (after) 545 /// CHECK: <<ArgValue:i\d+>> ParameterValue 546 /// CHECK: <<ArgDistance:i\d+>> ParameterValue 547 /// CHECK: <<Neg:i\d+>> Neg [<<ArgDistance>>] 548 /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<Neg>>] 549 /// CHECK: Return [<<Ror>>] 550 551 /// CHECK-START: int Main.rol_int_reg_negv_v(int, int) instruction_simplifier (after) 552 /// CHECK-NOT: UShr 553 /// CHECK-NOT: Shl rol_int_reg_negv_v(int value, int distance)554 public static int rol_int_reg_negv_v(int value, int distance) { 555 return (value << distance) | (value >>> -distance); 556 } 557 558 // (j << distance) | (j >>> -distance) (i.e. libcore's Long.rotateLeft) 559 560 /// CHECK-START: long Main.rol_long_reg_negv_v(long, int) instruction_simplifier (before) 561 /// CHECK: <<ArgValue:j\d+>> ParameterValue 562 /// CHECK: <<ArgDistance:i\d+>> ParameterValue 563 /// CHECK-DAG: <<Neg:i\d+>> Neg [<<ArgDistance>>] 564 /// CHECK-DAG: <<UShr:j\d+>> UShr [<<ArgValue>>,<<Neg>>] 565 /// CHECK-DAG: <<Shl:j\d+>> Shl [<<ArgValue>>,<<ArgDistance>>] 566 /// CHECK: <<Or:j\d+>> Or [<<Shl>>,<<UShr>>] 567 /// CHECK: Return [<<Or>>] 568 569 /// CHECK-START: long Main.rol_long_reg_negv_v(long, int) instruction_simplifier (after) 570 /// CHECK: <<ArgValue:j\d+>> ParameterValue 571 /// CHECK: <<ArgDistance:i\d+>> ParameterValue 572 /// CHECK: <<Neg:i\d+>> Neg [<<ArgDistance>>] 573 /// CHECK: <<Ror:j\d+>> Ror [<<ArgValue>>,<<Neg>>] 574 /// CHECK: Return [<<Ror>>] 575 576 /// CHECK-START: long Main.rol_long_reg_negv_v(long, int) instruction_simplifier (after) 577 /// CHECK-NOT: UShr 578 /// CHECK-NOT: Shl rol_long_reg_negv_v(long value, int distance)579 public static long rol_long_reg_negv_v(long value, int distance) { 580 return (value << distance) | (value >>> -distance); 581 } 582 583 // (j << distance) + (j >>> -distance) 584 585 /// CHECK-START: long Main.rol_long_reg_v_negv_add(long, int) instruction_simplifier (before) 586 /// CHECK: <<ArgValue:j\d+>> ParameterValue 587 /// CHECK: <<ArgDistance:i\d+>> ParameterValue 588 /// CHECK-DAG: <<Neg:i\d+>> Neg [<<ArgDistance>>] 589 /// CHECK-DAG: <<UShr:j\d+>> UShr [<<ArgValue>>,<<Neg>>] 590 /// CHECK-DAG: <<Shl:j\d+>> Shl [<<ArgValue>>,<<ArgDistance>>] 591 /// CHECK: <<Add:j\d+>> Add [<<Shl>>,<<UShr>>] 592 /// CHECK: Return [<<Add>>] 593 594 /// CHECK-START: long Main.rol_long_reg_v_negv_add(long, int) instruction_simplifier (after) 595 /// CHECK: <<ArgValue:j\d+>> ParameterValue 596 /// CHECK: <<ArgDistance:i\d+>> ParameterValue 597 /// CHECK: <<Neg:i\d+>> Neg [<<ArgDistance>>] 598 /// CHECK: <<Ror:j\d+>> Ror [<<ArgValue>>,<<Neg>>] 599 /// CHECK: Return [<<Ror>>] 600 601 /// CHECK-START: long Main.rol_long_reg_v_negv_add(long, int) instruction_simplifier (after) 602 /// CHECK-NOT: Add 603 /// CHECK-NOT: Shl 604 /// CHECK-NOT: UShr rol_long_reg_v_negv_add(long value, int distance)605 public static long rol_long_reg_v_negv_add(long value, int distance) { 606 return (value << distance) + (value >>> -distance); 607 } 608 609 // (j << distance) ^ (j >>> -distance) 610 611 /// CHECK-START: long Main.rol_long_reg_v_negv_xor(long, int) instruction_simplifier (before) 612 /// CHECK: <<ArgValue:j\d+>> ParameterValue 613 /// CHECK: <<ArgDistance:i\d+>> ParameterValue 614 /// CHECK-DAG: <<Neg:i\d+>> Neg [<<ArgDistance>>] 615 /// CHECK-DAG: <<UShr:j\d+>> UShr [<<ArgValue>>,<<Neg>>] 616 /// CHECK-DAG: <<Shl:j\d+>> Shl [<<ArgValue>>,<<ArgDistance>>] 617 /// CHECK: <<Xor:j\d+>> Xor [<<Shl>>,<<UShr>>] 618 /// CHECK: Return [<<Xor>>] 619 620 /// CHECK-START: long Main.rol_long_reg_v_negv_xor(long, int) instruction_simplifier (after) 621 /// CHECK: <<ArgValue:j\d+>> ParameterValue 622 /// CHECK: <<ArgDistance:i\d+>> ParameterValue 623 /// CHECK: <<Neg:i\d+>> Neg [<<ArgDistance>>] 624 /// CHECK: <<Ror:j\d+>> Ror [<<ArgValue>>,<<Neg>>] 625 /// CHECK: Return [<<Ror>>] 626 627 /// CHECK-START: long Main.rol_long_reg_v_negv_xor(long, int) instruction_simplifier (after) 628 /// CHECK-NOT: Xor 629 /// CHECK-NOT: Shl 630 /// CHECK-NOT: UShr rol_long_reg_v_negv_xor(long value, int distance)631 public static long rol_long_reg_v_negv_xor(long value, int distance) { 632 return (value << distance) ^ (value >>> -distance); 633 } 634 main(String[] args)635 public static void main(String[] args) { 636 assertIntEquals(2, ror_int_constant_c_c(8)); 637 assertIntEquals(2, ror_int_constant_c_c_0(8)); 638 assertLongEquals(2L, ror_long_constant_c_c(8L)); 639 640 assertIntEquals(2, ror_int_constant_c_negc(8)); 641 assertLongEquals(2L, ror_long_constant_c_negc(8L)); 642 643 assertIntEquals(2, ror_int_reg_v_csubv(8, 2)); 644 assertLongEquals(2L, ror_long_reg_v_csubv(8L, 2)); 645 646 assertIntEquals(2, ror_int_subv_csubv(8, 2, 0)); 647 assertIntEquals(32, ror_int_subv_csubv_env(8, 2, 0)); 648 assertIntEquals(32, rol_int_csubv_subv(8, 2, 0)); 649 650 assertIntEquals(32, rol_int_reg_csubv_v(8, 2)); 651 assertLongEquals(32L, rol_long_reg_csubv_v(8L, 2)); 652 653 assertIntEquals(2, ror_int_reg_v_negv(8, 2)); 654 assertIntEquals(0, ror_int_reg_v_negv_env(8, 2)); 655 assertLongEquals(2L, ror_long_reg_v_negv(8L, 2)); 656 657 assertIntEquals(32, rol_int_reg_negv_v(8, 2)); 658 assertLongEquals(32L, rol_long_reg_negv_v(8L, 2)); 659 660 assertLongEquals(32L, rol_long_reg_v_negv_add(8L, 2)); 661 assertLongEquals(32L, rol_long_reg_v_negv_xor(8L, 2)); 662 } 663 } 664