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