1 /* 2 * Copyright (C) 2020 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 DivTest { expectEquals(int expected, int result)18 private static void expectEquals(int expected, int result) { 19 if (expected != result) { 20 throw new Error("Expected: " + expected + ", found: " + result); 21 } 22 } 23 expectEquals(long expected, long result)24 private static void expectEquals(long expected, long result) { 25 if (expected != result) { 26 throw new Error("Expected: " + expected + ", found: " + result); 27 } 28 } 29 expectEquals(String expected, String result)30 private static void expectEquals(String expected, String result) { 31 if (!expected.equals(result)) { 32 throw new Error("Expected: " + expected + ", found: " + result); 33 } 34 } 35 main()36 public static void main() { 37 divInt(); 38 divLong(); 39 } 40 divInt()41 private static void divInt() { 42 expectEquals(0, $noinline$IntDivBy18(0)); 43 expectEquals(0, $noinline$IntDivBy18(1)); 44 expectEquals(0, $noinline$IntDivBy18(-1)); 45 expectEquals(1, $noinline$IntDivBy18(18)); 46 expectEquals(-1, $noinline$IntDivBy18(-18)); 47 expectEquals(3, $noinline$IntDivBy18(65)); 48 expectEquals(-3, $noinline$IntDivBy18(-65)); 49 50 expectEquals(0, $noinline$IntALenDivBy18(new int[0])); 51 expectEquals(0, $noinline$IntALenDivBy18(new int[1])); 52 expectEquals(1, $noinline$IntALenDivBy18(new int[18])); 53 expectEquals(3, $noinline$IntALenDivBy18(new int[65])); 54 55 expectEquals(0, $noinline$IntDivByMinus18(0)); 56 expectEquals(0, $noinline$IntDivByMinus18(1)); 57 expectEquals(0, $noinline$IntDivByMinus18(-1)); 58 expectEquals(-1, $noinline$IntDivByMinus18(18)); 59 expectEquals(1, $noinline$IntDivByMinus18(-18)); 60 expectEquals(-3, $noinline$IntDivByMinus18(65)); 61 expectEquals(3, $noinline$IntDivByMinus18(-65)); 62 63 expectEquals(0, $noinline$IntDivBy7(0)); 64 expectEquals(0, $noinline$IntDivBy7(1)); 65 expectEquals(0, $noinline$IntDivBy7(-1)); 66 expectEquals(1, $noinline$IntDivBy7(7)); 67 expectEquals(-1, $noinline$IntDivBy7(-7)); 68 expectEquals(3, $noinline$IntDivBy7(22)); 69 expectEquals(-3, $noinline$IntDivBy7(-22)); 70 71 expectEquals(0, $noinline$IntALenDivBy7(new int[0])); 72 expectEquals(0, $noinline$IntALenDivBy7(new int[1])); 73 expectEquals(1, $noinline$IntALenDivBy7(new int[7])); 74 expectEquals(3, $noinline$IntALenDivBy7(new int[22])); 75 76 expectEquals(0, $noinline$IntDivByMinus7(0)); 77 expectEquals(0, $noinline$IntDivByMinus7(1)); 78 expectEquals(0, $noinline$IntDivByMinus7(-1)); 79 expectEquals(-1, $noinline$IntDivByMinus7(7)); 80 expectEquals(1, $noinline$IntDivByMinus7(-7)); 81 expectEquals(-3, $noinline$IntDivByMinus7(22)); 82 expectEquals(3, $noinline$IntDivByMinus7(-22)); 83 84 expectEquals(0, $noinline$IntDivBy6(0)); 85 expectEquals(0, $noinline$IntDivBy6(1)); 86 expectEquals(0, $noinline$IntDivBy6(-1)); 87 expectEquals(1, $noinline$IntDivBy6(6)); 88 expectEquals(-1, $noinline$IntDivBy6(-6)); 89 expectEquals(3, $noinline$IntDivBy6(19)); 90 expectEquals(-3, $noinline$IntDivBy6(-19)); 91 92 expectEquals(0, $noinline$IntALenDivBy6(new int[0])); 93 expectEquals(0, $noinline$IntALenDivBy6(new int[1])); 94 expectEquals(1, $noinline$IntALenDivBy6(new int[6])); 95 expectEquals(3, $noinline$IntALenDivBy6(new int[19])); 96 97 expectEquals(0, $noinline$IntDivByMinus6(0)); 98 expectEquals(0, $noinline$IntDivByMinus6(1)); 99 expectEquals(0, $noinline$IntDivByMinus6(-1)); 100 expectEquals(-1, $noinline$IntDivByMinus6(6)); 101 expectEquals(1, $noinline$IntDivByMinus6(-6)); 102 expectEquals(-3, $noinline$IntDivByMinus6(19)); 103 expectEquals(3, $noinline$IntDivByMinus6(-19)); 104 105 expectEquals(2, $noinline$UnsignedIntDiv01(12)); 106 expectEquals(2, $noinline$UnsignedIntDiv02(12)); 107 expectEquals(2, $noinline$UnsignedIntDiv03(12)); 108 expectEquals(2, $noinline$UnsignedIntDiv04(12)); 109 expectEquals("01", $noinline$UnsignedIntDiv05(10)); 110 expectEquals("321", $noinline$UnsignedIntDiv05(123)); 111 expectEquals(1, $noinline$UnsignedIntDiv06(101)); 112 expectEquals(1, $noinline$UnsignedIntDiv07(10)); 113 expectEquals(1, $noinline$UnsignedIntDiv07(100)); 114 expectEquals(10, $noinline$UnsignedIntDiv08(100)); 115 expectEquals(11, $noinline$UnsignedIntDiv08(101)); 116 117 expectEquals(-2, $noinline$SignedIntDiv01(-12)); 118 expectEquals(-2, $noinline$SignedIntDiv02(-12)); 119 expectEquals(2, $noinline$SignedIntDiv03(-12)); 120 expectEquals(2, $noinline$SignedIntDiv04(-12, true)); 121 expectEquals(-2, $noinline$SignedIntDiv05(-12, 0,-13)); 122 expectEquals(-2, $noinline$SignedIntDiv06(-12)); 123 } 124 125 // A test case to check that 'lsr' and 'asr' are combined into one 'asr'. 126 // For divisor 18 seen in an MP3 decoding workload there is no need 127 // to correct the result of get_high(dividend * magic). So there are no 128 // instructions between 'lsr' and 'asr'. In such a case they can be combined 129 // into one 'asr'. 130 // 131 /// CHECK-START-ARM64: int DivTest.$noinline$IntDivBy18(int) disassembly (after) 132 /// CHECK: asr x{{\d+}}, x{{\d+}}, #34 133 /// CHECK-NEXT: add w{{\d+}}, w{{\d+}}, w{{\d+}}, lsr #31 $noinline$IntDivBy18(int v)134 private static int $noinline$IntDivBy18(int v) { 135 int r = v / 18; 136 return r; 137 } 138 139 // A test case to check that a correcting 'add' is not generated for a non-negative 140 // dividend and a positive divisor. 141 // 142 /// CHECK-START-ARM: int DivTest.$noinline$IntALenDivBy18(int[]) disassembly (after) 143 /// CHECK: smull r{{\d+}}, r{{\d+}}, r{{\d+}}, r{{\d+}} 144 /// CHECK-NEXT: lsr{{s?}} r{{\d+}}, r{{\d+}}, #2 145 /// CHECK-NOT: sub r{{\d+}}, r{{\d+}}, r{{\d+}}, asr #31 146 // 147 /// CHECK-START-ARM64: int DivTest.$noinline$IntALenDivBy18(int[]) disassembly (after) 148 /// CHECK: lsr x{{\d+}}, x{{\d+}}, #34 149 /// CHECK-NOT: add w{{\d+}}, w{{\d+}}, w{{\d+}}, lsr #31 $noinline$IntALenDivBy18(int[] arr)150 private static int $noinline$IntALenDivBy18(int[] arr) { 151 int r = arr.length / 18; 152 return r; 153 } 154 155 // A test case to check that 'lsr' and 'asr' are combined into one 'asr'. 156 // Divisor -18 has the same property as divisor 18: no need to correct the 157 // result of get_high(dividend * magic). So there are no 158 // instructions between 'lsr' and 'asr'. In such a case they can be combined 159 // into one 'asr'. 160 // 161 /// CHECK-START-ARM64: int DivTest.$noinline$IntDivByMinus18(int) disassembly (after) 162 /// CHECK: asr x{{\d+}}, x{{\d+}}, #34 163 /// CHECK-NEXT: add w{{\d+}}, w{{\d+}}, w{{\d+}}, lsr #31 $noinline$IntDivByMinus18(int v)164 private static int $noinline$IntDivByMinus18(int v) { 165 int r = v / -18; 166 return r; 167 } 168 169 // A test case to check that 'lsr' and 'add' are combined into one 'adds'. 170 // For divisor 7 seen in the core library the result of get_high(dividend * magic) 171 // must be corrected by the 'add' instruction. 172 // 173 // The test case also checks 'add' and 'add_shift' are optimized into 'adds' and 'cinc'. 174 // 175 /// CHECK-START-ARM64: int DivTest.$noinline$IntDivBy7(int) disassembly (after) 176 /// CHECK: adds x{{\d+}}, x{{\d+}}, x{{\d+}}, lsl #32 177 /// CHECK-NEXT: asr x{{\d+}}, x{{\d+}}, #34 178 /// CHECK-NEXT: cinc w{{\d+}}, w{{\d+}}, mi $noinline$IntDivBy7(int v)179 private static int $noinline$IntDivBy7(int v) { 180 int r = v / 7; 181 return r; 182 } 183 184 // A test case to check that a correcting 'add' is not generated for a non-negative 185 // dividend and a positive divisor. 186 // 187 /// CHECK-START-ARM: int DivTest.$noinline$IntALenDivBy7(int[]) disassembly (after) 188 /// CHECK: smull r{{\d+}}, r{{\d+}}, r{{\d+}}, r{{\d+}} 189 /// CHECK-NEXT: add{{s?}} r{{\d+}}, r{{\d+}} 190 /// CHECK-NEXT: lsr{{s?}} r{{\d+}}, r{{\d+}}, #2 191 /// CHECK-NOT: sub r{{\d+}}, r{{\d+}}, r{{\d+}}, asr #31 192 // 193 /// CHECK-START-ARM64: int DivTest.$noinline$IntALenDivBy7(int[]) disassembly (after) 194 /// CHECK: adds x{{\d+}}, x{{\d+}}, x{{\d+}}, lsl #32 195 /// CHECK-NEXT: lsr x{{\d+}}, x{{\d+}}, #34 196 /// CHECK-NOT: cinc w{{\d+}}, w{{\d+}}, mi $noinline$IntALenDivBy7(int[] arr)197 private static int $noinline$IntALenDivBy7(int[] arr) { 198 int r = arr.length / 7; 199 return r; 200 } 201 202 // A test case to check that 'lsr' and 'add' are combined into one 'adds'. 203 // Divisor -7 has the same property as divisor 7: the result of get_high(dividend * magic) 204 // must be corrected. In this case it is a 'sub' instruction. 205 // 206 // The test case also checks 'sub' and 'add_shift' are optimized into 'subs' and 'cinc'. 207 // 208 /// CHECK-START-ARM64: int DivTest.$noinline$IntDivByMinus7(int) disassembly (after) 209 /// CHECK: subs x{{\d+}}, x{{\d+}}, x{{\d+}}, lsl #32 210 /// CHECK-NEXT: asr x{{\d+}}, x{{\d+}}, #34 211 /// CHECK-NEXT: cinc w{{\d+}}, w{{\d+}}, mi $noinline$IntDivByMinus7(int v)212 private static int $noinline$IntDivByMinus7(int v) { 213 int r = v / -7; 214 return r; 215 } 216 217 // A test case to check that 'asr' is used to get the high 32 bits of the result of 218 // 'dividend * magic'. 219 // For divisor 6 seen in the core library there is no need to correct the result of 220 // get_high(dividend * magic). Also there is no 'asr' before the final 'add' instruction 221 // which uses only the high 32 bits of the result. In such a case 'asr' getting the high 222 // 32 bits can be used as well. 223 // 224 /// CHECK-START-ARM64: int DivTest.$noinline$IntDivBy6(int) disassembly (after) 225 /// CHECK: asr x{{\d+}}, x{{\d+}}, #32 226 /// CHECK-NEXT: add w{{\d+}}, w{{\d+}}, w{{\d+}}, lsr #31 $noinline$IntDivBy6(int v)227 private static int $noinline$IntDivBy6(int v) { 228 int r = v / 6; 229 return r; 230 } 231 232 // A test case to check that a correcting 'add' is not generated for a non-negative 233 // dividend and a positive divisor. 234 // 235 /// CHECK-START-ARM: int DivTest.$noinline$IntALenDivBy6(int[]) disassembly (after) 236 /// CHECK: smull r{{\d+}}, r{{\d+}}, r{{\d+}}, r{{\d+}} 237 /// CHECK-NOT: sub r{{\d+}}, r{{\d+}}, r{{\d+}}, asr #31 238 // 239 /// CHECK-START-ARM64: int DivTest.$noinline$IntALenDivBy6(int[]) disassembly (after) 240 /// CHECK: lsr x{{\d+}}, x{{\d+}}, #32 241 /// CHECK-NOT: add w{{\d+}}, w{{\d+}}, w{{\d+}}, lsr #31 $noinline$IntALenDivBy6(int[] arr)242 private static int $noinline$IntALenDivBy6(int[] arr) { 243 int r = arr.length / 6; 244 return r; 245 } 246 247 // A test case to check that 'asr' is used to get the high 32 bits of the result of 248 // 'dividend * magic'. 249 // Divisor -6 has the same property as divisor 6: no need to correct the result of 250 // get_high(dividend * magic) and no 'asr' before the final 'add' instruction 251 // which uses only the high 32 bits of the result. In such a case 'asr' getting the high 252 // 32 bits can be used as well. 253 // 254 /// CHECK-START-ARM64: int DivTest.$noinline$IntDivByMinus6(int) disassembly (after) 255 /// CHECK: asr x{{\d+}}, x{{\d+}}, #32 256 /// CHECK-NEXT: add w{{\d+}}, w{{\d+}}, w{{\d+}}, lsr #31 $noinline$IntDivByMinus6(int v)257 private static int $noinline$IntDivByMinus6(int v) { 258 int r = v / -6; 259 return r; 260 } 261 $noinline$Negate(int v)262 private static int $noinline$Negate(int v) { 263 return -v; 264 } 265 $noinline$Decrement(int v)266 private static int $noinline$Decrement(int v) { 267 return v - 1; 268 } 269 $noinline$Increment(int v)270 private static int $noinline$Increment(int v) { 271 return v + 1; 272 } 273 274 // A test case to check that a correcting 'add' is not generated for a non-negative 275 // dividend and a positive divisor. 276 // 277 /// CHECK-START-ARM: int DivTest.$noinline$UnsignedIntDiv01(int) disassembly (after) 278 /// CHECK: smull r{{\d+}}, r{{\d+}}, r{{\d+}}, r{{\d+}} 279 /// CHECK-NOT: sub r{{\d+}}, r{{\d+}}, r{{\d+}}, asr #31 280 // 281 /// CHECK-START-ARM64: int DivTest.$noinline$UnsignedIntDiv01(int) disassembly (after) 282 /// CHECK: lsr x{{\d+}}, x{{\d+}}, #32 283 /// CHECK-NOT: add w{{\d+}}, w{{\d+}}, w{{\d+}}, lsr #31 $noinline$UnsignedIntDiv01(int v)284 private static int $noinline$UnsignedIntDiv01(int v) { 285 int c = 0; 286 if (v > 0) { 287 c = v / 6; 288 } else { 289 c = $noinline$Negate(v); // This is to prevent from using Select. 290 } 291 return c; 292 } 293 294 // A test case to check that a correcting 'add' is not generated for a non-negative 295 // dividend and a positive divisor. 296 // 297 /// CHECK-START-ARM: int DivTest.$noinline$UnsignedIntDiv02(int) disassembly (after) 298 /// CHECK: smull r{{\d+}}, r{{\d+}}, r{{\d+}}, r{{\d+}} 299 /// CHECK-NOT: sub r{{\d+}}, r{{\d+}}, r{{\d+}}, asr #31 300 // 301 /// CHECK-START-ARM64: int DivTest.$noinline$UnsignedIntDiv02(int) disassembly (after) 302 /// CHECK: lsr x{{\d+}}, x{{\d+}}, #32 303 /// CHECK-NOT: add w{{\d+}}, w{{\d+}}, w{{\d+}}, lsr #31 $noinline$UnsignedIntDiv02(int v)304 private static int $noinline$UnsignedIntDiv02(int v) { 305 int c = 0; 306 if (0 < v) { 307 c = v / 6; 308 } else { 309 c = $noinline$Negate(v); // This is to prevent from using Select. 310 } 311 return c; 312 } 313 314 // A test case to check that a correcting 'add' is not generated for a non-negative 315 // dividend and a positive divisor. 316 // 317 /// CHECK-START-ARM: int DivTest.$noinline$UnsignedIntDiv03(int) disassembly (after) 318 /// CHECK: smull r{{\d+}}, r{{\d+}}, r{{\d+}}, r{{\d+}} 319 /// CHECK-NOT: sub r{{\d+}}, r{{\d+}}, r{{\d+}}, asr #31 320 // 321 /// CHECK-START-ARM64: int DivTest.$noinline$UnsignedIntDiv03(int) disassembly (after) 322 /// CHECK: lsr x{{\d+}}, x{{\d+}}, #32 323 /// CHECK-NOT: add w{{\d+}}, w{{\d+}}, w{{\d+}}, lsr #31 $noinline$UnsignedIntDiv03(int v)324 private static int $noinline$UnsignedIntDiv03(int v) { 325 int c = 0; 326 if (v >= 0) { 327 c = v / 6; 328 } else { 329 c = $noinline$Negate(v); // This is to prevent from using Select. 330 } 331 return c; 332 } 333 334 // A test case to check that a correcting 'add' is not generated for a non-negative 335 // dividend and a positive divisor. 336 // 337 /// CHECK-START-ARM: int DivTest.$noinline$UnsignedIntDiv04(int) disassembly (after) 338 /// CHECK: smull r{{\d+}}, r{{\d+}}, r{{\d+}}, r{{\d+}} 339 /// CHECK-NOT: sub r{{\d+}}, r{{\d+}}, r{{\d+}}, asr #31 340 // 341 /// CHECK-START-ARM64: int DivTest.$noinline$UnsignedIntDiv04(int) disassembly (after) 342 /// CHECK: lsr x{{\d+}}, x{{\d+}}, #32 343 /// CHECK-NOT: add w{{\d+}}, w{{\d+}}, w{{\d+}}, lsr #31 $noinline$UnsignedIntDiv04(int v)344 private static int $noinline$UnsignedIntDiv04(int v) { 345 int c = 0; 346 if (0 <= v) { 347 c = v / 6; 348 } else { 349 c = $noinline$Negate(v); // This is to prevent from using Select. 350 } 351 return c; 352 } 353 354 // A test case to check that a correcting 'add' is not generated for a non-negative 355 // dividend and a positive divisor. 356 // 357 /// CHECK-START-ARM: java.lang.String DivTest.$noinline$UnsignedIntDiv05(int) disassembly (after) 358 /// CHECK: smull r{{\d+}}, r{{\d+}}, r{{\d+}}, r{{\d+}} 359 /// CHECK-NOT: sub r{{\d+}}, r{{\d+}}, r{{\d+}}, asr #31 360 // 361 /// CHECK-START-ARM64: java.lang.String DivTest.$noinline$UnsignedIntDiv05(int) disassembly (after) 362 /// CHECK: smull x{{\d+}}, w{{\d+}}, w{{\d+}} 363 /// CHECK: lsr x{{\d+}}, x{{\d+}}, #34 364 /// CHECK-NOT: add w{{\d+}}, w{{\d+}}, w{{\d+}}, lsr #31 $noinline$UnsignedIntDiv05(int v)365 private static String $noinline$UnsignedIntDiv05(int v) { 366 String r = ""; 367 while (v > 0) { 368 int d = v % 10; 369 r += (char)(d + '0'); 370 v /= 10; 371 } 372 return r; 373 } 374 375 // A test case to check that a correcting 'add' is not generated for a non-negative 376 // dividend and a positive divisor. 377 // 378 /// CHECK-START-ARM: int DivTest.$noinline$UnsignedIntDiv06(int) disassembly (after) 379 /// CHECK: smull r{{\d+}}, r{{\d+}}, r{{\d+}}, r{{\d+}} 380 /// CHECK-NOT: sub r{{\d+}}, r{{\d+}}, r{{\d+}}, asr #31 381 // 382 /// CHECK-START-ARM64: int DivTest.$noinline$UnsignedIntDiv06(int) disassembly (after) 383 /// CHECK: smull x{{\d+}}, w{{\d+}}, w{{\d+}} 384 /// CHECK: lsr x{{\d+}}, x{{\d+}}, #34 385 /// CHECK-NOT: add w{{\d+}}, w{{\d+}}, w{{\d+}}, lsr #31 $noinline$UnsignedIntDiv06(int v)386 private static int $noinline$UnsignedIntDiv06(int v) { 387 int c = 0; 388 for(; v > 100; ++c) { 389 v /= 10; 390 } 391 return c; 392 } 393 394 // A test case to check that a correcting 'add' is not generated for a non-negative 395 // dividend and a positive divisor. 396 // 397 /// CHECK-START-ARM: int DivTest.$noinline$UnsignedIntDiv07(int) disassembly (after) 398 /// CHECK: smull r{{\d+}}, r{{\d+}}, r{{\d+}}, r{{\d+}} 399 /// CHECK-NOT: sub r{{\d+}}, r{{\d+}}, r{{\d+}}, asr #31 400 // 401 /// CHECK-START-ARM64: int DivTest.$noinline$UnsignedIntDiv07(int) disassembly (after) 402 /// CHECK: smull x{{\d+}}, w{{\d+}}, w{{\d+}} 403 /// CHECK: lsr x{{\d+}}, x{{\d+}}, #34 404 /// CHECK-NOT: add w{{\d+}}, w{{\d+}}, w{{\d+}}, lsr #31 $noinline$UnsignedIntDiv07(int v)405 private static int $noinline$UnsignedIntDiv07(int v) { 406 while (v > 0 && (v % 10) == 0) { 407 v /= 10; 408 } 409 return v; 410 } 411 412 // A test case to check that a correcting 'add' is not generated for a non-negative 413 // dividend and a positive divisor. 414 // 415 /// CHECK-START-ARM: int DivTest.$noinline$UnsignedIntDiv08(int) disassembly (after) 416 /// CHECK: smull r{{\d+}}, r{{\d+}}, r{{\d+}}, r{{\d+}} 417 /// CHECK-NOT: sub r{{\d+}}, r{{\d+}}, r{{\d+}}, asr #31 418 // 419 /// CHECK-START-ARM64: int DivTest.$noinline$UnsignedIntDiv08(int) disassembly (after) 420 /// CHECK: smull x{{\d+}}, w{{\d+}}, w{{\d+}} 421 /// CHECK: lsr x{{\d+}}, x{{\d+}}, #34 422 /// CHECK-NOT: add w{{\d+}}, w{{\d+}}, w{{\d+}}, lsr #31 $noinline$UnsignedIntDiv08(int v)423 private static int $noinline$UnsignedIntDiv08(int v) { 424 if (v < 10) { 425 v = $noinline$Negate(v); // This is to prevent from using Select. 426 } else { 427 v = (v % 10) + (v / 10); 428 } 429 return v; 430 } 431 432 // A test case to check that a correcting 'add' is generated for a negative 433 // dividend and a positive divisor. 434 // 435 /// CHECK-START-ARM: int DivTest.$noinline$SignedIntDiv01(int) disassembly (after) 436 /// CHECK: smull r{{\d+}}, r{{\d+}}, r{{\d+}}, r{{\d+}} 437 /// CHECK-NEXT: sub r{{\d+}}, r{{\d+}}, r{{\d+}}, asr #31 438 // 439 /// CHECK-START-ARM64: int DivTest.$noinline$SignedIntDiv01(int) disassembly (after) 440 /// CHECK: asr x{{\d+}}, x{{\d+}}, #32 441 /// CHECK-NEXT: add w{{\d+}}, w{{\d+}}, w{{\d+}}, lsr #31 $noinline$SignedIntDiv01(int v)442 private static int $noinline$SignedIntDiv01(int v) { 443 int c = 0; 444 if (v < 0) { 445 c = v / 6; 446 } else { 447 c = $noinline$Decrement(v); // This is to prevent from using Select. 448 } 449 return c; 450 } 451 452 // A test case to check that a correcting 'add' is generated for a negative 453 // dividend and a positive divisor. 454 // 455 /// CHECK-START-ARM: int DivTest.$noinline$SignedIntDiv02(int) disassembly (after) 456 /// CHECK: smull r{{\d+}}, r{{\d+}}, r{{\d+}}, r{{\d+}} 457 /// CHECK-NEXT: sub r{{\d+}}, r{{\d+}}, r{{\d+}}, asr #31 458 // 459 /// CHECK-START-ARM64: int DivTest.$noinline$SignedIntDiv02(int) disassembly (after) 460 /// CHECK: asr x{{\d+}}, x{{\d+}}, #32 461 /// CHECK-NEXT: add w{{\d+}}, w{{\d+}}, w{{\d+}}, lsr #31 $noinline$SignedIntDiv02(int v)462 private static int $noinline$SignedIntDiv02(int v) { 463 int c = 0; 464 if (v <= 0) { 465 c = v / 6; 466 } else { 467 c = $noinline$Decrement(v); // This is to prevent from using Select. 468 } 469 return c; 470 } 471 472 // A test case to check that a correcting 'add' is generated for signed division. 473 // 474 /// CHECK-START-ARM: int DivTest.$noinline$SignedIntDiv03(int) disassembly (after) 475 /// CHECK: smull r{{\d+}}, r{{\d+}}, r{{\d+}}, r{{\d+}} 476 /// CHECK-NEXT: sub r{{\d+}}, r{{\d+}}, r{{\d+}}, asr #31 477 // 478 /// CHECK-START-ARM64: int DivTest.$noinline$SignedIntDiv03(int) disassembly (after) 479 /// CHECK: asr x{{\d+}}, x{{\d+}}, #32 480 /// CHECK-NEXT: add w{{\d+}}, w{{\d+}}, w{{\d+}}, lsr #31 $noinline$SignedIntDiv03(int v)481 private static int $noinline$SignedIntDiv03(int v) { 482 boolean positive = (v > 0); 483 int c = v / 6; 484 if (!positive) { 485 c = $noinline$Negate(c); // This is to prevent from using Select. 486 } 487 return c; 488 } 489 490 // A test case to check that a correcting 'add' is generated for signed division. 491 // 492 /// CHECK-START-ARM: int DivTest.$noinline$SignedIntDiv04(int, boolean) disassembly (after) 493 /// CHECK: smull r{{\d+}}, r{{\d+}}, r{{\d+}}, r{{\d+}} 494 /// CHECK-NEXT: sub r{{\d+}}, r{{\d+}}, r{{\d+}}, asr #31 495 // 496 /// CHECK-START-ARM64: int DivTest.$noinline$SignedIntDiv04(int, boolean) disassembly (after) 497 /// CHECK: asr x{{\d+}}, x{{\d+}}, #32 498 /// CHECK-NEXT: add w{{\d+}}, w{{\d+}}, w{{\d+}}, lsr #31 $noinline$SignedIntDiv04(int v, boolean apply_div)499 private static int $noinline$SignedIntDiv04(int v, boolean apply_div) { 500 int c = 0; 501 boolean positive = (v > 0); 502 if (apply_div) { 503 c = v / 6; 504 } else { 505 c = $noinline$Decrement(v); // This is to prevent from using Select. 506 } 507 if (!positive) { 508 c = $noinline$Negate(c); // This is to prevent from using Select. 509 } 510 return c; 511 } 512 513 // A test case to check that a correcting 'add' is generated for signed division. 514 // 515 /// CHECK-START-ARM: int DivTest.$noinline$SignedIntDiv05(int, int, int) disassembly (after) 516 /// CHECK: smull r{{\d+}}, r{{\d+}}, r{{\d+}}, r{{\d+}} 517 /// CHECK-NEXT: sub r{{\d+}}, r{{\d+}}, r{{\d+}}, asr #31 518 // 519 /// CHECK-START-ARM64: int DivTest.$noinline$SignedIntDiv05(int, int, int) disassembly (after) 520 /// CHECK: asr x{{\d+}}, x{{\d+}}, #32 521 /// CHECK-NEXT: add w{{\d+}}, w{{\d+}}, w{{\d+}}, lsr #31 $noinline$SignedIntDiv05(int v, int a, int b)522 private static int $noinline$SignedIntDiv05(int v, int a, int b) { 523 int c = 0; 524 525 if (v < a) 526 c = $noinline$Increment(c); // This is to prevent from using Select. 527 528 if (b < a) 529 c = $noinline$Increment(c); // This is to prevent from using Select. 530 531 if (v > b) { 532 c = v / 6; 533 } else { 534 c = $noinline$Increment(c); // This is to prevent from using Select. 535 } 536 537 return c; 538 } 539 540 // A test case to check that a correcting 'add' is generated for signed division. 541 // 542 /// CHECK-START-ARM: int DivTest.$noinline$SignedIntDiv06(int) disassembly (after) 543 /// CHECK: smull r{{\d+}}, r{{\d+}}, r{{\d+}}, r{{\d+}} 544 /// CHECK-NEXT: sub r{{\d+}}, r{{\d+}}, r{{\d+}}, asr #31 545 // 546 /// CHECK-START-ARM64: int DivTest.$noinline$SignedIntDiv06(int) disassembly (after) 547 /// CHECK: asr x{{\d+}}, x{{\d+}}, #32 548 /// CHECK-NEXT: add w{{\d+}}, w{{\d+}}, w{{\d+}}, lsr #31 $noinline$SignedIntDiv06(int v)549 private static int $noinline$SignedIntDiv06(int v) { 550 int c = v / 6; 551 552 if (v > 0) { 553 c = $noinline$Negate(c); // This is to prevent from using Select. 554 } 555 556 return c; 557 } 558 divLong()559 private static void divLong() { 560 expectEquals(0L, $noinline$LongDivBy18(0L)); 561 expectEquals(0L, $noinline$LongDivBy18(1L)); 562 expectEquals(0L, $noinline$LongDivBy18(-1L)); 563 expectEquals(1L, $noinline$LongDivBy18(18L)); 564 expectEquals(-1L, $noinline$LongDivBy18(-18L)); 565 expectEquals(3L, $noinline$LongDivBy18(65L)); 566 expectEquals(-3L, $noinline$LongDivBy18(-65L)); 567 568 expectEquals(0L, $noinline$LongDivByMinus18(0L)); 569 expectEquals(0L, $noinline$LongDivByMinus18(1L)); 570 expectEquals(0L, $noinline$LongDivByMinus18(-1L)); 571 expectEquals(-1L, $noinline$LongDivByMinus18(18L)); 572 expectEquals(1L, $noinline$LongDivByMinus18(-18L)); 573 expectEquals(-3L, $noinline$LongDivByMinus18(65L)); 574 expectEquals(3L, $noinline$LongDivByMinus18(-65L)); 575 576 expectEquals(0L, $noinline$LongDivBy7(0L)); 577 expectEquals(0L, $noinline$LongDivBy7(1L)); 578 expectEquals(0L, $noinline$LongDivBy7(-1L)); 579 expectEquals(1L, $noinline$LongDivBy7(7L)); 580 expectEquals(-1L, $noinline$LongDivBy7(-7L)); 581 expectEquals(3L, $noinline$LongDivBy7(22L)); 582 expectEquals(-3L, $noinline$LongDivBy7(-22L)); 583 584 expectEquals(0L, $noinline$LongDivByMinus7(0L)); 585 expectEquals(0L, $noinline$LongDivByMinus7(1L)); 586 expectEquals(0L, $noinline$LongDivByMinus7(-1L)); 587 expectEquals(-1L, $noinline$LongDivByMinus7(7L)); 588 expectEquals(1L, $noinline$LongDivByMinus7(-7L)); 589 expectEquals(-3L, $noinline$LongDivByMinus7(22L)); 590 expectEquals(3L, $noinline$LongDivByMinus7(-22L)); 591 592 expectEquals(0L, $noinline$LongDivBy6(0L)); 593 expectEquals(0L, $noinline$LongDivBy6(1L)); 594 expectEquals(0L, $noinline$LongDivBy6(-1L)); 595 expectEquals(1L, $noinline$LongDivBy6(6L)); 596 expectEquals(-1L, $noinline$LongDivBy6(-6L)); 597 expectEquals(3L, $noinline$LongDivBy6(19L)); 598 expectEquals(-3L, $noinline$LongDivBy6(-19L)); 599 600 expectEquals(0L, $noinline$LongDivByMinus6(0L)); 601 expectEquals(0L, $noinline$LongDivByMinus6(1L)); 602 expectEquals(0L, $noinline$LongDivByMinus6(-1L)); 603 expectEquals(-1L, $noinline$LongDivByMinus6(6L)); 604 expectEquals(1L, $noinline$LongDivByMinus6(-6L)); 605 expectEquals(-3L, $noinline$LongDivByMinus6(19L)); 606 expectEquals(3L, $noinline$LongDivByMinus6(-19L)); 607 608 expectEquals(0L, $noinline$LongDivBy100(0L)); 609 expectEquals(0L, $noinline$LongDivBy100(1L)); 610 expectEquals(0L, $noinline$LongDivBy100(-1L)); 611 expectEquals(1L, $noinline$LongDivBy100(100L)); 612 expectEquals(-1L, $noinline$LongDivBy100(-100L)); 613 expectEquals(3L, $noinline$LongDivBy100(301L)); 614 expectEquals(-3L, $noinline$LongDivBy100(-301L)); 615 616 expectEquals(0L, $noinline$LongDivByMinus100(0L)); 617 expectEquals(0L, $noinline$LongDivByMinus100(1L)); 618 expectEquals(0L, $noinline$LongDivByMinus100(-1L)); 619 expectEquals(-1L, $noinline$LongDivByMinus100(100L)); 620 expectEquals(1L, $noinline$LongDivByMinus100(-100L)); 621 expectEquals(-3L, $noinline$LongDivByMinus100(301L)); 622 expectEquals(3L, $noinline$LongDivByMinus100(-301L)); 623 624 expectEquals(2L, $noinline$UnsignedLongDiv01(12L)); 625 expectEquals(2L, $noinline$UnsignedLongDiv02(12L)); 626 expectEquals(2L, $noinline$UnsignedLongDiv03(12L)); 627 expectEquals(2L, $noinline$UnsignedLongDiv04(12L)); 628 expectEquals("01", $noinline$UnsignedLongDiv05(10L)); 629 expectEquals("321", $noinline$UnsignedLongDiv05(123L)); 630 expectEquals(1L, $noinline$UnsignedLongDiv06(101L)); 631 expectEquals(1L, $noinline$UnsignedLongDiv07(10L)); 632 expectEquals(1L, $noinline$UnsignedLongDiv07(100L)); 633 expectEquals(10L, $noinline$UnsignedLongDiv08(100L)); 634 expectEquals(11L, $noinline$UnsignedLongDiv08(101L)); 635 636 expectEquals(-2L, $noinline$SignedLongDiv01(-12L)); 637 expectEquals(-2L, $noinline$SignedLongDiv02(-12L)); 638 expectEquals(2L, $noinline$SignedLongDiv03(-12L)); 639 expectEquals(2L, $noinline$SignedLongDiv04(-12L, true)); 640 expectEquals(-2L, $noinline$SignedLongDiv05(-12L, 0L,-13L)); 641 expectEquals(-2L, $noinline$SignedLongDiv06(-12L)); 642 } 643 644 // Test cases for Int64 HDiv/HRem to check that optimizations implemented for Int32 are not 645 // used for Int64. The same divisors 18, -18, 7, -7, 6 and -6 are used. 646 647 /// CHECK-START-ARM64: long DivTest.$noinline$LongDivBy18(long) disassembly (after) 648 /// CHECK: smulh x{{\d+}}, x{{\d+}}, x{{\d+}} 649 /// CHECK-NEXT: add x{{\d+}}, x{{\d+}}, x{{\d+}}, lsr #63 $noinline$LongDivBy18(long v)650 private static long $noinline$LongDivBy18(long v) { 651 long r = v / 18L; 652 return r; 653 } 654 655 /// CHECK-START-ARM64: long DivTest.$noinline$LongDivByMinus18(long) disassembly (after) 656 /// CHECK: smulh x{{\d+}}, x{{\d+}}, x{{\d+}} 657 /// CHECK-NEXT: add x{{\d+}}, x{{\d+}}, x{{\d+}}, lsr #63 $noinline$LongDivByMinus18(long v)658 private static long $noinline$LongDivByMinus18(long v) { 659 long r = v / -18L; 660 return r; 661 } 662 663 /// CHECK-START-ARM64: long DivTest.$noinline$LongDivBy7(long) disassembly (after) 664 /// CHECK: smulh x{{\d+}}, x{{\d+}}, x{{\d+}} 665 /// CHECK-NEXT: asr x{{\d+}}, x{{\d+}}, #1 666 /// CHECK-NEXT: add x{{\d+}}, x{{\d+}}, x{{\d+}}, lsr #63 $noinline$LongDivBy7(long v)667 private static long $noinline$LongDivBy7(long v) { 668 long r = v / 7L; 669 return r; 670 } 671 672 /// CHECK-START-ARM64: long DivTest.$noinline$LongDivByMinus7(long) disassembly (after) 673 /// CHECK: smulh x{{\d+}}, x{{\d+}}, x{{\d+}} 674 /// CHECK-NEXT: asr x{{\d+}}, x{{\d+}}, #1 675 /// CHECK-NEXT: add x{{\d+}}, x{{\d+}}, x{{\d+}}, lsr #63 $noinline$LongDivByMinus7(long v)676 private static long $noinline$LongDivByMinus7(long v) { 677 long r = v / -7L; 678 return r; 679 } 680 681 /// CHECK-START-ARM64: long DivTest.$noinline$LongDivBy6(long) disassembly (after) 682 /// CHECK: smulh x{{\d+}}, x{{\d+}}, x{{\d+}} 683 /// CHECK-NEXT: add x{{\d+}}, x{{\d+}}, x{{\d+}}, lsr #63 $noinline$LongDivBy6(long v)684 private static long $noinline$LongDivBy6(long v) { 685 long r = v / 6L; 686 return r; 687 } 688 689 /// CHECK-START-ARM64: long DivTest.$noinline$LongDivByMinus6(long) disassembly (after) 690 /// CHECK: smulh x{{\d+}}, x{{\d+}}, x{{\d+}} 691 /// CHECK-NEXT: add x{{\d+}}, x{{\d+}}, x{{\d+}}, lsr #63 $noinline$LongDivByMinus6(long v)692 private static long $noinline$LongDivByMinus6(long v) { 693 long r = v / -6L; 694 return r; 695 } 696 697 // A test to check 'add' and 'add_shift' are optimized into 'adds' and 'cinc'. 698 // 699 /// CHECK-START-ARM64: long DivTest.$noinline$LongDivBy100(long) disassembly (after) 700 /// CHECK: smulh x{{\d+}}, x{{\d+}}, x{{\d+}} 701 /// CHECK-NEXT: adds x{{\d+}}, x{{\d+}}, x{{\d+}} 702 /// CHECK-NEXT: asr x{{\d+}}, x{{\d+}}, #6 703 /// CHECK-NEXT: cinc x{{\d+}}, x{{\d+}}, mi $noinline$LongDivBy100(long v)704 private static long $noinline$LongDivBy100(long v) { 705 long r = v / 100L; 706 return r; 707 } 708 709 // A test to check 'subs' and 'add_shift' are optimized into 'subs' and 'cinc'. 710 // 711 /// CHECK-START-ARM64: long DivTest.$noinline$LongDivByMinus100(long) disassembly (after) 712 /// CHECK: smulh x{{\d+}}, x{{\d+}}, x{{\d+}} 713 /// CHECK-NEXT: subs x{{\d+}}, x{{\d+}}, x{{\d+}} 714 /// CHECK-NEXT: asr x{{\d+}}, x{{\d+}}, #6 715 /// CHECK-NEXT: cinc x{{\d+}}, x{{\d+}}, mi $noinline$LongDivByMinus100(long v)716 private static long $noinline$LongDivByMinus100(long v) { 717 long r = v / -100L; 718 return r; 719 } 720 $noinline$Negate(long v)721 private static long $noinline$Negate(long v) { 722 return -v; 723 } 724 $noinline$Decrement(long v)725 private static long $noinline$Decrement(long v) { 726 return v - 1; 727 } 728 $noinline$Increment(long v)729 private static long $noinline$Increment(long v) { 730 return v + 1; 731 } 732 733 // A test case to check that a correcting 'add' is not generated for a non-negative 734 // dividend and a positive divisor. 735 // 736 /// CHECK-START-ARM64: long DivTest.$noinline$UnsignedLongDiv01(long) disassembly (after) 737 /// CHECK: smulh x{{\d+}}, x{{\d+}}, x{{\d+}} 738 /// CHECK-NOT: add x{{\d+}}, x{{\d+}}, x{{\d+}}, lsr #63 $noinline$UnsignedLongDiv01(long v)739 private static long $noinline$UnsignedLongDiv01(long v) { 740 long c = 0; 741 if (v > 0) { 742 c = v / 6; 743 } else { 744 c = $noinline$Negate(v); // This is to prevent from using Select. 745 } 746 return c; 747 } 748 749 // A test case to check that a correcting 'add' is not generated for a non-negative 750 // dividend and a positive divisor. 751 // 752 /// CHECK-START-ARM64: long DivTest.$noinline$UnsignedLongDiv02(long) disassembly (after) 753 /// CHECK: smulh x{{\d+}}, x{{\d+}}, x{{\d+}} 754 /// CHECK-NOT: add x{{\d+}}, x{{\d+}}, x{{\d+}}, lsr #63 $noinline$UnsignedLongDiv02(long v)755 private static long $noinline$UnsignedLongDiv02(long v) { 756 long c = 0; 757 if (0 < v) { 758 c = v / 6; 759 } else { 760 c = $noinline$Negate(v); // This is to prevent from using Select. 761 } 762 return c; 763 } 764 765 // A test case to check that a correcting 'add' is not generated for a non-negative 766 // dividend and a positive divisor. 767 // 768 /// CHECK-START-ARM64: long DivTest.$noinline$UnsignedLongDiv03(long) disassembly (after) 769 /// CHECK: smulh x{{\d+}}, x{{\d+}}, x{{\d+}} 770 /// CHECK-NOT: add x{{\d+}}, x{{\d+}}, x{{\d+}}, lsr #63 $noinline$UnsignedLongDiv03(long v)771 private static long $noinline$UnsignedLongDiv03(long v) { 772 long c = 0; 773 if (v >= 0) { 774 c = v / 6; 775 } else { 776 c = $noinline$Negate(v); // This is to prevent from using Select. 777 } 778 return c; 779 } 780 781 // A test case to check that a correcting 'add' is not generated for a non-negative 782 // dividend and a positive divisor. 783 // 784 /// CHECK-START-ARM64: long DivTest.$noinline$UnsignedLongDiv04(long) disassembly (after) 785 /// CHECK: smulh x{{\d+}}, x{{\d+}}, x{{\d+}} 786 /// CHECK-NOT: add x{{\d+}}, x{{\d+}}, x{{\d+}}, lsr #63 $noinline$UnsignedLongDiv04(long v)787 private static long $noinline$UnsignedLongDiv04(long v) { 788 long c = 0; 789 if (0 <= v) { 790 c = v / 6; 791 } else { 792 c = $noinline$Negate(v); // This is to prevent from using Select. 793 } 794 return c; 795 } 796 797 // A test case to check that a correcting 'add' is not generated for a non-negative 798 // dividend and a positive divisor. 799 // 800 /// CHECK-START-ARM64: java.lang.String DivTest.$noinline$UnsignedLongDiv05(long) disassembly (after) 801 /// CHECK: smulh x{{\d+}}, x{{\d+}}, x{{\d+}} 802 /// CHECK-NEXT: lsr x{{\d+}}, x{{\d+}}, #2 803 /// CHECK-NOT: add x{{\d+}}, x{{\d+}}, x{{\d+}}, lsr #63 $noinline$UnsignedLongDiv05(long v)804 private static String $noinline$UnsignedLongDiv05(long v) { 805 String r = ""; 806 while (v > 0) { 807 long d = v % 10; 808 r += (char)(d + '0'); 809 v /= 10; 810 } 811 return r; 812 } 813 // A test case to check that a correcting 'add' is not generated for a non-negative 814 // dividend and a positive divisor. 815 // 816 /// CHECK-START-ARM64: void DivTest.$noinline$UnsignedLongDiv05(java.lang.StringBuilder, long, long) disassembly (after) 817 /// CHECK: smulh x{{\d+}}, x{{\d+}}, x{{\d+}} 818 /// CHECK-NEXT: lsr x{{\d+}}, x{{\d+}}, #2 819 /// CHECK-NOT: add x{{\d+}}, x{{\d+}}, x{{\d+}}, lsr #63 $noinline$UnsignedLongDiv05(java.lang.StringBuilder sb, long w, long d)820 private static void $noinline$UnsignedLongDiv05(java.lang.StringBuilder sb, long w, long d) { 821 while (w > 0) { 822 sb.append((char)(d/w + '0')); 823 d = d % w; 824 w /= 10; 825 } 826 } 827 828 // A test case to check that a correcting 'add' is not generated for a non-negative 829 // dividend and a positive divisor. 830 // 831 /// CHECK-START-ARM64: long DivTest.$noinline$UnsignedLongDiv06(long) disassembly (after) 832 /// CHECK: smulh x{{\d+}}, x{{\d+}}, x{{\d+}} 833 /// CHECK-NOT: add x{{\d+}}, x{{\d+}}, x{{\d+}}, lsr #63 $noinline$UnsignedLongDiv06(long v)834 private static long $noinline$UnsignedLongDiv06(long v) { 835 long c = 0; 836 for(; v > 100; ++c) { 837 v /= 10; 838 } 839 return c; 840 } 841 842 // A test case to check that a correcting 'add' is not generated for a non-negative 843 // dividend and a positive divisor. 844 // 845 /// CHECK-START-ARM64: long DivTest.$noinline$UnsignedLongDiv07(long) disassembly (after) 846 /// CHECK: smulh x{{\d+}}, x{{\d+}}, x{{\d+}} 847 /// CHECK-NOT: add x{{\d+}}, x{{\d+}}, x{{\d+}}, lsr #63 $noinline$UnsignedLongDiv07(long v)848 private static long $noinline$UnsignedLongDiv07(long v) { 849 while (v > 0 && (v % 10) == 0) { 850 v /= 10; 851 } 852 return v; 853 } 854 855 // A test case to check that a correcting 'add' is not generated for a non-negative 856 // dividend and a positive divisor. 857 // 858 /// CHECK-START-ARM64: long DivTest.$noinline$UnsignedLongDiv08(long) disassembly (after) 859 /// CHECK: smulh x{{\d+}}, x{{\d+}}, x{{\d+}} 860 /// CHECK-NOT: add x{{\d+}}, x{{\d+}}, x{{\d+}}, lsr #63 $noinline$UnsignedLongDiv08(long v)861 private static long $noinline$UnsignedLongDiv08(long v) { 862 if (v < 10) { 863 v = $noinline$Negate(v); // This is to prevent from using Select. 864 } else { 865 v = (v % 10) + (v / 10); 866 } 867 return v; 868 } 869 870 // A test case to check that a correcting 'add' is generated for a negative 871 // dividend and a positive divisor. 872 // 873 /// CHECK-START-ARM64: long DivTest.$noinline$SignedLongDiv01(long) disassembly (after) 874 /// CHECK: smulh x{{\d+}}, x{{\d+}}, x{{\d+}} 875 /// CHECK-NEXT: add x{{\d+}}, x{{\d+}}, x{{\d+}}, lsr #63 $noinline$SignedLongDiv01(long v)876 private static long $noinline$SignedLongDiv01(long v) { 877 long c = 0; 878 if (v < 0) { 879 c = v / 6; 880 } else { 881 c = $noinline$Decrement(v); // This is to prevent from using Select. 882 } 883 return c; 884 } 885 886 // A test case to check that a correcting 'add' is generated for a negative 887 // dividend and a positive divisor. 888 // 889 /// CHECK-START-ARM64: long DivTest.$noinline$SignedLongDiv02(long) disassembly (after) 890 /// CHECK: smulh x{{\d+}}, x{{\d+}}, x{{\d+}} 891 /// CHECK-NEXT: add x{{\d+}}, x{{\d+}}, x{{\d+}}, lsr #63 $noinline$SignedLongDiv02(long v)892 private static long $noinline$SignedLongDiv02(long v) { 893 long c = 0; 894 if (v <= 0) { 895 c = v / 6; 896 } else { 897 c = $noinline$Decrement(v); // This is to prevent from using Select. 898 } 899 return c; 900 } 901 902 // A test case to check that a correcting 'add' is generated for signed division. 903 // 904 /// CHECK-START-ARM64: long DivTest.$noinline$SignedLongDiv03(long) disassembly (after) 905 /// CHECK: smulh x{{\d+}}, x{{\d+}}, x{{\d+}} 906 /// CHECK-NEXT: add x{{\d+}}, x{{\d+}}, x{{\d+}}, lsr #63 $noinline$SignedLongDiv03(long v)907 private static long $noinline$SignedLongDiv03(long v) { 908 boolean positive = (v > 0); 909 long c = v / 6; 910 if (!positive) { 911 c = $noinline$Negate(c); // This is to prevent from using Select. 912 } 913 return c; 914 } 915 916 // A test case to check that a correcting 'add' is generated for signed division. 917 // 918 /// CHECK-START-ARM64: long DivTest.$noinline$SignedLongDiv04(long, boolean) disassembly (after) 919 /// CHECK: smulh x{{\d+}}, x{{\d+}}, x{{\d+}} 920 /// CHECK-NEXT: add x{{\d+}}, x{{\d+}}, x{{\d+}}, lsr #63 $noinline$SignedLongDiv04(long v, boolean apply_div)921 private static long $noinline$SignedLongDiv04(long v, boolean apply_div) { 922 long c = 0; 923 boolean positive = (v > 0); 924 if (apply_div) { 925 c = v / 6; 926 } else { 927 c = $noinline$Decrement(v); // This is to prevent from using Select. 928 } 929 if (!positive) { 930 c = $noinline$Negate(c); // This is to prevent from using Select. 931 } 932 return c; 933 } 934 935 // A test case to check that a correcting 'add' is generated for signed division. 936 // 937 /// CHECK-START-ARM64: long DivTest.$noinline$SignedLongDiv05(long, long, long) disassembly (after) 938 /// CHECK: smulh x{{\d+}}, x{{\d+}}, x{{\d+}} 939 /// CHECK-NEXT: add x{{\d+}}, x{{\d+}}, x{{\d+}}, lsr #63 $noinline$SignedLongDiv05(long v, long a, long b)940 private static long $noinline$SignedLongDiv05(long v, long a, long b) { 941 long c = 0; 942 943 if (v < a) 944 c = $noinline$Increment(c); // This is to prevent from using Select. 945 946 if (b < a) 947 c = $noinline$Increment(c); // This is to prevent from using Select. 948 949 if (v > b) { 950 c = v / 6; 951 } else { 952 c = $noinline$Increment(c); // This is to prevent from using Select. 953 } 954 955 return c; 956 } 957 958 // A test case to check that a correcting 'add' is generated for signed division. 959 // 960 /// CHECK-START-ARM64: long DivTest.$noinline$SignedLongDiv06(long) disassembly (after) 961 /// CHECK: smulh x{{\d+}}, x{{\d+}}, x{{\d+}} 962 /// CHECK-NEXT: add x{{\d+}}, x{{\d+}}, x{{\d+}}, lsr #63 $noinline$SignedLongDiv06(long v)963 private static long $noinline$SignedLongDiv06(long v) { 964 long c = v / 6; 965 966 if (v > 0) { 967 c = $noinline$Negate(c); // This is to prevent from using Select. 968 } 969 970 return c; 971 } 972 } 973