• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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