1 /* 2 * Copyright (C) 2018 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 { 18 expectEquals(T expected, T result)19 public static <T extends Number> void expectEquals(T expected, T result) { 20 if (!expected.equals(result)) { 21 throw new Error("Expected: " + expected + ", found: " + result); 22 } 23 } 24 main()25 public static void main() { 26 divInt(); 27 divLong(); 28 } 29 divInt()30 private static void divInt() { 31 expectEquals(0, $noinline$IntDivBy2(0)); 32 expectEquals(0, $noinline$IntDivBy2(1)); 33 expectEquals(0, $noinline$IntDivBy2(-1)); 34 expectEquals(1, $noinline$IntDivBy2(2)); 35 expectEquals(-1, $noinline$IntDivBy2(-2)); 36 expectEquals(1, $noinline$IntDivBy2(3)); 37 expectEquals(-1, $noinline$IntDivBy2(-3)); 38 expectEquals(3, $noinline$IntDivBy2(7)); 39 expectEquals(-3, $noinline$IntDivBy2(-7)); 40 expectEquals(4, $noinline$IntDivBy2(8)); 41 expectEquals(-4, $noinline$IntDivBy2(-8)); 42 expectEquals(7, $noinline$IntDivBy2(0x0f)); 43 expectEquals(0x007f, $noinline$IntDivBy2(0x00ff)); 44 expectEquals(0x07ff, $noinline$IntDivBy2(0x0fff)); 45 expectEquals(0x007fff, $noinline$IntDivBy2(0x00ffff)); 46 expectEquals(0x3fffffff, $noinline$IntDivBy2(Integer.MAX_VALUE)); 47 expectEquals(0xc0000000, $noinline$IntDivBy2(Integer.MIN_VALUE)); 48 49 expectEquals(0, $noinline$IntDivByMinus2(0)); 50 expectEquals(0, $noinline$IntDivByMinus2(1)); 51 expectEquals(0, $noinline$IntDivByMinus2(-1)); 52 expectEquals(-1, $noinline$IntDivByMinus2(2)); 53 expectEquals(1, $noinline$IntDivByMinus2(-2)); 54 expectEquals(-1, $noinline$IntDivByMinus2(3)); 55 expectEquals(1, $noinline$IntDivByMinus2(-3)); 56 expectEquals(-3, $noinline$IntDivByMinus2(7)); 57 expectEquals(3, $noinline$IntDivByMinus2(-7)); 58 expectEquals(-4, $noinline$IntDivByMinus2(8)); 59 expectEquals(4, $noinline$IntDivByMinus2(-8)); 60 expectEquals(-7, $noinline$IntDivByMinus2(0x0f)); 61 expectEquals(0xffffff81, $noinline$IntDivByMinus2(0x00ff)); 62 expectEquals(0xfffff801, $noinline$IntDivByMinus2(0x0fff)); 63 expectEquals(0xffff8001, $noinline$IntDivByMinus2(0x00ffff)); 64 expectEquals(0xc0000001, $noinline$IntDivByMinus2(Integer.MAX_VALUE)); 65 expectEquals(0x40000000, $noinline$IntDivByMinus2(Integer.MIN_VALUE)); 66 67 expectEquals(0, $noinline$IntDivBy16(0)); 68 expectEquals(1, $noinline$IntDivBy16(16)); 69 expectEquals(-1, $noinline$IntDivBy16(-16)); 70 expectEquals(2, $noinline$IntDivBy16(33)); 71 expectEquals(0x000f, $noinline$IntDivBy16(0x00ff)); 72 expectEquals(0x00ff, $noinline$IntDivBy16(0x0fff)); 73 expectEquals(0x000fff, $noinline$IntDivBy16(0x00ffff)); 74 expectEquals(0x07ffffff, $noinline$IntDivBy16(Integer.MAX_VALUE)); 75 expectEquals(0xf8000000, $noinline$IntDivBy16(Integer.MIN_VALUE)); 76 77 expectEquals(0, $noinline$IntDivByMinus16(0)); 78 expectEquals(-1, $noinline$IntDivByMinus16(16)); 79 expectEquals(1, $noinline$IntDivByMinus16(-16)); 80 expectEquals(-2, $noinline$IntDivByMinus16(33)); 81 expectEquals(0xfffffff1, $noinline$IntDivByMinus16(0x00ff)); 82 expectEquals(0xffffff01, $noinline$IntDivByMinus16(0x0fff)); 83 expectEquals(0xfffff001, $noinline$IntDivByMinus16(0x00ffff)); 84 expectEquals(0xf8000001, $noinline$IntDivByMinus16(Integer.MAX_VALUE)); 85 expectEquals(0x08000000, $noinline$IntDivByMinus16(Integer.MIN_VALUE)); 86 87 expectEquals(0, $noinline$IntDivByIntMin(0)); 88 expectEquals(0, $noinline$IntDivByIntMin(1)); 89 expectEquals(0, $noinline$IntDivByIntMin(-1)); 90 expectEquals(1, $noinline$IntDivByIntMin(Integer.MIN_VALUE)); 91 expectEquals(0, $noinline$IntDivByIntMin(Integer.MAX_VALUE)); 92 } 93 94 /// CHECK-START-ARM64: java.lang.Integer DivTest.$noinline$IntDivBy2(int) disassembly (after) 95 /// CHECK: add w{{\d+}}, w{{\d+}}, w{{\d+}}, lsr #31 96 /// CHECK: asr w{{\d+}}, w{{\d+}}, #1 97 /// CHECK-START-X86_64: java.lang.Integer DivTest.$noinline$IntDivBy2(int) disassembly (after) 98 /// CHECK-NOT: cmovnl/geq 99 /// CHECK: add $noinline$IntDivBy2(int v)100 private static Integer $noinline$IntDivBy2(int v) { 101 int r = v / 2; 102 return r; 103 } 104 105 /// CHECK-START-ARM64: java.lang.Integer DivTest.$noinline$IntDivByMinus2(int) disassembly (after) 106 /// CHECK: add w{{\d+}}, w{{\d+}}, w{{\d+}}, lsr #31 107 /// CHECK: neg w{{\d+}}, w{{\d+}}, asr #1 108 /// CHECK-START-X86_64: java.lang.Integer DivTest.$noinline$IntDivByMinus2(int) disassembly (after) 109 /// CHECK-NOT: cmovnl/geq 110 /// CHECK: add $noinline$IntDivByMinus2(int v)111 private static Integer $noinline$IntDivByMinus2(int v) { 112 int r = v / -2; 113 return r; 114 } 115 116 /// CHECK-START-ARM64: java.lang.Integer DivTest.$noinline$IntDivBy16(int) disassembly (after) 117 /// CHECK: add w{{\d+}}, w{{\d+}}, #0xf 118 /// CHECK: cmp w{{\d+}}, #0x0 119 /// CHECK: csel w{{\d+}}, w{{\d+}}, w{{\d+}}, lt 120 /// CHECK: asr w{{\d+}}, w{{\d+}}, #4 $noinline$IntDivBy16(int v)121 private static Integer $noinline$IntDivBy16(int v) { 122 int r = v / 16; 123 return r; 124 } 125 126 /// CHECK-START-ARM64: java.lang.Integer DivTest.$noinline$IntDivByMinus16(int) disassembly (after) 127 /// CHECK: add w{{\d+}}, w{{\d+}}, #0xf 128 /// CHECK: cmp w{{\d+}}, #0x0 129 /// CHECK: csel w{{\d+}}, w{{\d+}}, w{{\d+}}, lt 130 /// CHECK: neg w{{\d+}}, w{{\d+}}, asr #4 $noinline$IntDivByMinus16(int v)131 private static Integer $noinline$IntDivByMinus16(int v) { 132 int r = v / -16; 133 return r; 134 } 135 136 /// CHECK-START-ARM64: java.lang.Integer DivTest.$noinline$IntDivByIntMin(int) disassembly (after) 137 /// CHECK: mov w{{\d+}}, #0x7fffffff 138 /// CHECK: add w{{\d+}}, w{{\d+}}, w{{\d+}} 139 /// CHECK: cmp w{{\d+}}, #0x0 140 /// CHECK: csel w{{\d+}}, w{{\d+}}, w{{\d+}}, lt 141 /// CHECK: neg w{{\d+}}, w{{\d+}}, asr #31 $noinline$IntDivByIntMin(int v)142 private static Integer $noinline$IntDivByIntMin(int v) { 143 int r = v / Integer.MIN_VALUE; 144 return r; 145 } 146 divLong()147 private static void divLong() { 148 expectEquals(0L, $noinline$LongDivBy2(0L)); 149 expectEquals(0L, $noinline$LongDivBy2(1L)); 150 expectEquals(0L, $noinline$LongDivBy2(-1L)); 151 expectEquals(1L, $noinline$LongDivBy2(2L)); 152 expectEquals(-1L, $noinline$LongDivBy2(-2L)); 153 expectEquals(1L, $noinline$LongDivBy2(3L)); 154 expectEquals(-1L, $noinline$LongDivBy2(-3L)); 155 expectEquals(3L, $noinline$LongDivBy2(7L)); 156 expectEquals(-3L, $noinline$LongDivBy2(-7L)); 157 expectEquals(4L, $noinline$LongDivBy2(8L)); 158 expectEquals(-4L, $noinline$LongDivBy2(-8L)); 159 expectEquals(7L, $noinline$LongDivBy2(0x0fL)); 160 expectEquals(0x007fL, $noinline$LongDivBy2(0x00ffL)); 161 expectEquals(0x07ffL, $noinline$LongDivBy2(0x0fffL)); 162 expectEquals(0x007fffL, $noinline$LongDivBy2(0x00ffffL)); 163 expectEquals(0x3fffffffffffffffL, $noinline$LongDivBy2(Long.MAX_VALUE)); 164 expectEquals(0xc000000000000000L, $noinline$LongDivBy2(Long.MIN_VALUE)); 165 166 expectEquals(0L, $noinline$LongDivByMinus2(0)); 167 expectEquals(0L, $noinline$LongDivByMinus2(1L)); 168 expectEquals(0L, $noinline$LongDivByMinus2(-1L)); 169 expectEquals(-1L, $noinline$LongDivByMinus2(2L)); 170 expectEquals(1L, $noinline$LongDivByMinus2(-2L)); 171 expectEquals(-1L, $noinline$LongDivByMinus2(3L)); 172 expectEquals(1L, $noinline$LongDivByMinus2(-3L)); 173 expectEquals(-3L, $noinline$LongDivByMinus2(7L)); 174 expectEquals(3L, $noinline$LongDivByMinus2(-7L)); 175 expectEquals(-4L, $noinline$LongDivByMinus2(8L)); 176 expectEquals(4L, $noinline$LongDivByMinus2(-8L)); 177 expectEquals(-7L, $noinline$LongDivByMinus2(0x0fL)); 178 expectEquals(0xffffffffffffff81L, $noinline$LongDivByMinus2(0x00ffL)); 179 expectEquals(0xfffffffffffff801L, $noinline$LongDivByMinus2(0x0fffL)); 180 expectEquals(0xffffffffffff8001L, $noinline$LongDivByMinus2(0x00ffffL)); 181 expectEquals(0xc000000000000001L, $noinline$LongDivByMinus2(Long.MAX_VALUE)); 182 expectEquals(0x4000000000000000L, $noinline$LongDivByMinus2(Long.MIN_VALUE)); 183 184 expectEquals(0L, $noinline$LongDivBy16(0)); 185 expectEquals(1L, $noinline$LongDivBy16(16L)); 186 expectEquals(-1L, $noinline$LongDivBy16(-16L)); 187 expectEquals(2L, $noinline$LongDivBy16(33L)); 188 expectEquals(0x000fL, $noinline$LongDivBy16(0x00ffL)); 189 expectEquals(0x00ffL, $noinline$LongDivBy16(0x0fffL)); 190 expectEquals(0x000fffL, $noinline$LongDivBy16(0x00ffffL)); 191 expectEquals(0x07ffffffffffffffL, $noinline$LongDivBy16(Long.MAX_VALUE)); 192 expectEquals(0xf800000000000000L, $noinline$LongDivBy16(Long.MIN_VALUE)); 193 194 expectEquals(0L, $noinline$LongDivByMinus16(0)); 195 expectEquals(-1L, $noinline$LongDivByMinus16(16L)); 196 expectEquals(1L, $noinline$LongDivByMinus16(-16L)); 197 expectEquals(-2L, $noinline$LongDivByMinus16(33L)); 198 expectEquals(0xfffffffffffffff1L, $noinline$LongDivByMinus16(0x00ffL)); 199 expectEquals(0xffffffffffffff01L, $noinline$LongDivByMinus16(0x0fffL)); 200 expectEquals(0xfffffffffffff001L, $noinline$LongDivByMinus16(0x00ffffL)); 201 expectEquals(0xf800000000000001L, $noinline$LongDivByMinus16(Long.MAX_VALUE)); 202 expectEquals(0x0800000000000000L, $noinline$LongDivByMinus16(Long.MIN_VALUE)); 203 204 expectEquals(0L, $noinline$LongDivByLongMin(0)); 205 expectEquals(0L, $noinline$LongDivByLongMin(1)); 206 expectEquals(0L, $noinline$LongDivByLongMin(-1)); 207 expectEquals(1L, $noinline$LongDivByLongMin(Long.MIN_VALUE)); 208 expectEquals(0L, $noinline$LongDivByLongMin(Long.MAX_VALUE)); 209 } 210 211 /// CHECK-START-ARM64: java.lang.Long DivTest.$noinline$LongDivBy2(long) disassembly (after) 212 /// CHECK: add x{{\d+}}, x{{\d+}}, x{{\d+}}, lsr #63 213 /// CHECK: asr x{{\d+}}, x{{\d+}}, #1 214 /// CHECK-START-X86_64: java.lang.Long DivTest.$noinline$LongDivBy2(long) disassembly (after) 215 /// CHECK-NOT: cmovnl/geq 216 /// CHECK: addq $noinline$LongDivBy2(long v)217 private static Long $noinline$LongDivBy2(long v) { 218 long r = v / 2; 219 return r; 220 } 221 222 /// CHECK-START-ARM64: java.lang.Long DivTest.$noinline$LongDivByMinus2(long) disassembly (after) 223 /// CHECK: add x{{\d+}}, x{{\d+}}, x{{\d+}}, lsr #63 224 /// CHECK: neg x{{\d+}}, x{{\d+}}, asr #1 225 /// CHECK-START-X86_64: java.lang.Long DivTest.$noinline$LongDivByMinus2(long) disassembly (after) 226 /// CHECK-NOT: cmovnl/geq 227 /// CHECK: addq $noinline$LongDivByMinus2(long v)228 private static Long $noinline$LongDivByMinus2(long v) { 229 long r = v / -2; 230 return r; 231 } 232 233 /// CHECK-START-ARM64: java.lang.Long DivTest.$noinline$LongDivBy16(long) disassembly (after) 234 /// CHECK: add x{{\d+}}, x{{\d+}}, #0xf 235 /// CHECK: cmp x{{\d+}}, #0x0 236 /// CHECK: csel x{{\d+}}, x{{\d+}}, x{{\d+}}, lt 237 /// CHECK: asr x{{\d+}}, x{{\d+}}, #4 $noinline$LongDivBy16(long v)238 private static Long $noinline$LongDivBy16(long v) { 239 long r = v / 16; 240 return r; 241 } 242 243 /// CHECK-START-ARM64: java.lang.Long DivTest.$noinline$LongDivByMinus16(long) disassembly (after) 244 /// CHECK: add x{{\d+}}, x{{\d+}}, #0xf 245 /// CHECK: cmp x{{\d+}}, #0x0 246 /// CHECK: csel x{{\d+}}, x{{\d+}}, x{{\d+}}, lt 247 /// CHECK: neg x{{\d+}}, x{{\d+}}, asr #4 $noinline$LongDivByMinus16(long v)248 private static Long $noinline$LongDivByMinus16(long v) { 249 long r = v / -16; 250 return r; 251 } 252 253 /// CHECK-START-ARM64: java.lang.Long DivTest.$noinline$LongDivByLongMin(long) disassembly (after) 254 /// CHECK: mov x{{\d+}}, #0x7fffffffffffffff 255 /// CHECK: add x{{\d+}}, x{{\d+}}, x{{\d+}} 256 /// CHECK: cmp x{{\d+}}, #0x0 257 /// CHECK: csel x{{\d+}}, x{{\d+}}, x{{\d+}}, lt 258 /// CHECK: neg x{{\d+}}, x{{\d+}}, asr #63 $noinline$LongDivByLongMin(long v)259 private static Long $noinline$LongDivByLongMin(long v) { 260 long r = v / Long.MIN_VALUE; 261 return r; 262 } 263 } 264