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 RemTest { 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 remInt(); 27 remLong(); 28 } 29 remInt()30 private static void remInt() { 31 expectEquals(0, $noinline$IntMod2(0)); 32 expectEquals(1, $noinline$IntMod2(1)); 33 expectEquals(-1, $noinline$IntMod2(-1)); 34 expectEquals(0, $noinline$IntMod2(2)); 35 expectEquals(0, $noinline$IntMod2(-2)); 36 expectEquals(1, $noinline$IntMod2(3)); 37 expectEquals(-1, $noinline$IntMod2(-3)); 38 expectEquals(1, $noinline$IntMod2(0x0f)); 39 expectEquals(1, $noinline$IntMod2(0x00ff)); 40 expectEquals(1, $noinline$IntMod2(0x00ffff)); 41 expectEquals(1, $noinline$IntMod2(Integer.MAX_VALUE)); 42 expectEquals(0, $noinline$IntMod2(Integer.MIN_VALUE)); 43 44 expectEquals(0, $noinline$IntModMinus2(0)); 45 expectEquals(1, $noinline$IntModMinus2(1)); 46 expectEquals(-1, $noinline$IntModMinus2(-1)); 47 expectEquals(0, $noinline$IntModMinus2(2)); 48 expectEquals(0, $noinline$IntModMinus2(-2)); 49 expectEquals(1, $noinline$IntModMinus2(3)); 50 expectEquals(-1, $noinline$IntModMinus2(-3)); 51 expectEquals(1, $noinline$IntModMinus2(0x0f)); 52 expectEquals(1, $noinline$IntModMinus2(0x00ff)); 53 expectEquals(1, $noinline$IntModMinus2(0x00ffff)); 54 expectEquals(1, $noinline$IntModMinus2(Integer.MAX_VALUE)); 55 expectEquals(0, $noinline$IntModMinus2(Integer.MIN_VALUE)); 56 57 expectEquals(0, $noinline$IntMod16(0)); 58 expectEquals(1, $noinline$IntMod16(1)); 59 expectEquals(1, $noinline$IntMod16(17)); 60 expectEquals(-1, $noinline$IntMod16(-1)); 61 expectEquals(0, $noinline$IntMod16(32)); 62 expectEquals(0, $noinline$IntMod16(-32)); 63 expectEquals(0x0f, $noinline$IntMod16(0x0f)); 64 expectEquals(0x0f, $noinline$IntMod16(0x00ff)); 65 expectEquals(0x0f, $noinline$IntMod16(0x00ffff)); 66 expectEquals(15, $noinline$IntMod16(Integer.MAX_VALUE)); 67 expectEquals(0, $noinline$IntMod16(Integer.MIN_VALUE)); 68 69 expectEquals(0, $noinline$IntModMinus16(0)); 70 expectEquals(1, $noinline$IntModMinus16(1)); 71 expectEquals(1, $noinline$IntModMinus16(17)); 72 expectEquals(-1, $noinline$IntModMinus16(-1)); 73 expectEquals(0, $noinline$IntModMinus16(32)); 74 expectEquals(0, $noinline$IntModMinus16(-32)); 75 expectEquals(0x0f, $noinline$IntModMinus16(0x0f)); 76 expectEquals(0x0f, $noinline$IntModMinus16(0x00ff)); 77 expectEquals(0x0f, $noinline$IntModMinus16(0x00ffff)); 78 expectEquals(15, $noinline$IntModMinus16(Integer.MAX_VALUE)); 79 expectEquals(0, $noinline$IntModMinus16(Integer.MIN_VALUE)); 80 81 expectEquals(0, $noinline$IntModIntMin(0)); 82 expectEquals(1, $noinline$IntModIntMin(1)); 83 expectEquals(0, $noinline$IntModIntMin(Integer.MIN_VALUE)); 84 expectEquals(-1, $noinline$IntModIntMin(-1)); 85 expectEquals(0x0f, $noinline$IntModIntMin(0x0f)); 86 expectEquals(0x00ff, $noinline$IntModIntMin(0x00ff)); 87 expectEquals(0x00ffff, $noinline$IntModIntMin(0x00ffff)); 88 expectEquals(Integer.MAX_VALUE, $noinline$IntModIntMin(Integer.MAX_VALUE)); 89 } 90 91 /// CHECK-START-ARM64: java.lang.Integer RemTest.$noinline$IntMod2(int) disassembly (after) 92 /// CHECK: cmp w{{\d+}}, #0x0 93 /// CHECK: and w{{\d+}}, w{{\d+}}, #0x1 94 /// CHECK: cneg w{{\d+}}, w{{\d+}}, lt 95 /// CHECK-START-X86_64: java.lang.Integer RemTest.$noinline$IntMod2(int) disassembly (after) 96 /// CHECK: Rem [{{i\d+}},{{i\d+}}] 97 /// CHECK-NOT: imul 98 /// CHECK-NOT: shr 99 /// CHECK-NOT: imul 100 /// CHECK: mov 101 /// CHECK: and 102 /// CHECK: jz/eq 103 /// CHECK: lea 104 /// CHECK: test 105 /// CHECK: cmovl/nge $noinline$IntMod2(int v)106 private static Integer $noinline$IntMod2(int v) { 107 int r = v % 2; 108 return r; 109 } 110 111 /// CHECK-START-ARM64: java.lang.Integer RemTest.$noinline$IntModMinus2(int) disassembly (after) 112 /// CHECK: cmp w{{\d+}}, #0x0 113 /// CHECK: and w{{\d+}}, w{{\d+}}, #0x1 114 /// CHECK: cneg w{{\d+}}, w{{\d+}}, lt 115 /// CHECK-START-X86_64: java.lang.Integer RemTest.$noinline$IntModMinus2(int) disassembly (after) 116 /// CHECK: Rem [{{i\d+}},{{i\d+}}] 117 /// CHECK-NOT: imul 118 /// CHECK-NOT: shr 119 /// CHECK-NOT: imul 120 /// CHECK: mov 121 /// CHECK: and 122 /// CHECK: jz/eq 123 /// CHECK: lea 124 /// CHECK: test 125 /// CHECK: cmovl/nge $noinline$IntModMinus2(int v)126 private static Integer $noinline$IntModMinus2(int v) { 127 int r = v % -2; 128 return r; 129 } 130 131 /// CHECK-START-ARM64: java.lang.Integer RemTest.$noinline$IntMod16(int) disassembly (after) 132 /// CHECK: negs w{{\d+}}, w{{\d+}} 133 /// CHECK: and w{{\d+}}, w{{\d+}}, #0xf 134 /// CHECK: and w{{\d+}}, w{{\d+}}, #0xf 135 /// CHECK: csneg w{{\d+}}, w{{\d+}}, mi 136 /// CHECK-START-X86_64: java.lang.Integer RemTest.$noinline$IntMod16(int) disassembly (after) 137 /// CHECK: Rem [{{i\d+}},{{i\d+}}] 138 /// CHECK-NOT: imul 139 /// CHECK-NOT: shr 140 /// CHECK-NOT: imul 141 /// CHECK: mov 142 /// CHECK: and 143 /// CHECK: jz/eq 144 /// CHECK: lea 145 /// CHECK: test 146 /// CHECK: cmovl/nge $noinline$IntMod16(int v)147 private static Integer $noinline$IntMod16(int v) { 148 int r = v % 16; 149 return r; 150 } 151 152 /// CHECK-START-ARM64: java.lang.Integer RemTest.$noinline$IntModMinus16(int) disassembly (after) 153 /// CHECK: negs w{{\d+}}, w{{\d+}} 154 /// CHECK: and w{{\d+}}, w{{\d+}}, #0xf 155 /// CHECK: and w{{\d+}}, w{{\d+}}, #0xf 156 /// CHECK: csneg w{{\d+}}, w{{\d+}}, mi 157 /// CHECK-START-X86_64: java.lang.Integer RemTest.$noinline$IntModMinus16(int) disassembly (after) 158 /// CHECK: Rem [{{i\d+}},{{i\d+}}] 159 /// CHECK-NOT: imul 160 /// CHECK-NOT: shr 161 /// CHECK-NOT: imul 162 /// CHECK: mov 163 /// CHECK: and 164 /// CHECK: jz/eq 165 /// CHECK: lea 166 /// CHECK: test 167 /// CHECK: cmovl/nge $noinline$IntModMinus16(int v)168 private static Integer $noinline$IntModMinus16(int v) { 169 int r = v % -16; 170 return r; 171 } 172 173 /// CHECK-START-ARM64: java.lang.Integer RemTest.$noinline$IntModIntMin(int) disassembly (after) 174 /// CHECK: negs w{{\d+}}, w{{\d+}} 175 /// CHECK: and w{{\d+}}, w{{\d+}}, #0x7fffffff 176 /// CHECK: and w{{\d+}}, w{{\d+}}, #0x7fffffff 177 /// CHECK: csneg w{{\d+}}, w{{\d+}}, mi 178 /// CHECK-START-X86_64: java.lang.Integer RemTest.$noinline$IntModIntMin(int) disassembly (after) 179 /// CHECK: Rem [{{i\d+}},{{i\d+}}] 180 /// CHECK-NOT: imul 181 /// CHECK-NOT: shr 182 /// CHECK-NOT: imul 183 /// CHECK: mov 184 /// CHECK: and 185 /// CHECK: jz/eq 186 /// CHECK: lea 187 /// CHECK: test 188 /// CHECK: cmovl/nge $noinline$IntModIntMin(int v)189 private static Integer $noinline$IntModIntMin(int v) { 190 int r = v % Integer.MIN_VALUE; 191 return r; 192 } 193 remLong()194 private static void remLong() { 195 expectEquals(0L, $noinline$LongMod2(0)); 196 expectEquals(1L, $noinline$LongMod2(1)); 197 expectEquals(-1L, $noinline$LongMod2(-1)); 198 expectEquals(0L, $noinline$LongMod2(2)); 199 expectEquals(0L, $noinline$LongMod2(-2)); 200 expectEquals(1L, $noinline$LongMod2(3)); 201 expectEquals(-1L, $noinline$LongMod2(-3)); 202 expectEquals(1L, $noinline$LongMod2(0x0f)); 203 expectEquals(1L, $noinline$LongMod2(0x00ff)); 204 expectEquals(1L, $noinline$LongMod2(0x00ffff)); 205 expectEquals(1L, $noinline$LongMod2(0x00ffffff)); 206 expectEquals(1L, $noinline$LongMod2(0x00ffffffffL)); 207 expectEquals(1L, $noinline$LongMod2(Long.MAX_VALUE)); 208 expectEquals(0L, $noinline$LongMod2(Long.MIN_VALUE)); 209 210 expectEquals(0L, $noinline$LongModMinus2(0)); 211 expectEquals(1L, $noinline$LongModMinus2(1)); 212 expectEquals(-1L, $noinline$LongModMinus2(-1)); 213 expectEquals(0L, $noinline$LongModMinus2(2)); 214 expectEquals(0L, $noinline$LongModMinus2(-2)); 215 expectEquals(1L, $noinline$LongModMinus2(3)); 216 expectEquals(-1L, $noinline$LongModMinus2(-3)); 217 expectEquals(1L, $noinline$LongModMinus2(0x0f)); 218 expectEquals(1L, $noinline$LongModMinus2(0x00ff)); 219 expectEquals(1L, $noinline$LongModMinus2(0x00ffff)); 220 expectEquals(1L, $noinline$LongModMinus2(0x00ffffff)); 221 expectEquals(1L, $noinline$LongModMinus2(0x00ffffffffL)); 222 expectEquals(1L, $noinline$LongModMinus2(Long.MAX_VALUE)); 223 expectEquals(0L, $noinline$LongModMinus2(Long.MIN_VALUE)); 224 225 expectEquals(0L, $noinline$LongMod16(0)); 226 expectEquals(1L, $noinline$LongMod16(1)); 227 expectEquals(1L, $noinline$LongMod16(17)); 228 expectEquals(-1L, $noinline$LongMod16(-1)); 229 expectEquals(0L, $noinline$LongMod16(32)); 230 expectEquals(0L, $noinline$LongMod16(-32)); 231 expectEquals(0x0fL, $noinline$LongMod16(0x0f)); 232 expectEquals(0x0fL, $noinline$LongMod16(0x00ff)); 233 expectEquals(0x0fL, $noinline$LongMod16(0x00ffff)); 234 expectEquals(0x0fL, $noinline$LongMod16(0x00ffffff)); 235 expectEquals(0x0fL, $noinline$LongMod16(0x00ffffffffL)); 236 expectEquals(15L, $noinline$LongMod16(Long.MAX_VALUE)); 237 expectEquals(0L, $noinline$LongMod16(Long.MIN_VALUE)); 238 239 expectEquals(0L, $noinline$LongModMinus16(0)); 240 expectEquals(1L, $noinline$LongModMinus16(1)); 241 expectEquals(1L, $noinline$LongModMinus16(17)); 242 expectEquals(-1L, $noinline$LongModMinus16(-1)); 243 expectEquals(0L, $noinline$LongModMinus16(32)); 244 expectEquals(0L, $noinline$LongModMinus16(-32)); 245 expectEquals(0x0fL, $noinline$LongModMinus16(0x0f)); 246 expectEquals(0x0fL, $noinline$LongModMinus16(0x00ff)); 247 expectEquals(0x0fL, $noinline$LongModMinus16(0x00ffff)); 248 expectEquals(0x0fL, $noinline$LongModMinus16(0x00ffffff)); 249 expectEquals(0x0fL, $noinline$LongModMinus16(0x00ffffffffL)); 250 expectEquals(15L, $noinline$LongModMinus16(Long.MAX_VALUE)); 251 expectEquals(0L, $noinline$LongModMinus16(Long.MIN_VALUE)); 252 253 expectEquals(0L, $noinline$LongModLongMin(0)); 254 expectEquals(1L, $noinline$LongModLongMin(1)); 255 expectEquals(0L, $noinline$LongModLongMin(Long.MIN_VALUE)); 256 expectEquals(-1L, $noinline$LongModLongMin(-1)); 257 expectEquals(0x0fL, $noinline$LongModLongMin(0x0f)); 258 expectEquals(0x00ffL, $noinline$LongModLongMin(0x00ff)); 259 expectEquals(0x00ffffL, $noinline$LongModLongMin(0x00ffff)); 260 expectEquals(0x00ffffffL, $noinline$LongModLongMin(0x00ffffff)); 261 expectEquals(0x00ffffffffL, $noinline$LongModLongMin(0x00ffffffffL)); 262 expectEquals(Long.MAX_VALUE, $noinline$LongModLongMin(Long.MAX_VALUE)); 263 } 264 265 /// CHECK-START-ARM64: java.lang.Long RemTest.$noinline$LongMod2(long) disassembly (after) 266 /// CHECK: cmp x{{\d+}}, #0x0 267 /// CHECK: and x{{\d+}}, x{{\d+}}, #0x1 268 /// CHECK: cneg x{{\d+}}, x{{\d+}}, lt 269 /// CHECK-START-X86_64: java.lang.Long RemTest.$noinline$LongMod2(long) disassembly (after) 270 /// CHECK: Rem [{{j\d+}},{{j\d+}}] 271 /// CHECK-NOT: imul 272 /// CHECK-NOT: shrq 273 /// CHECK-NOT: imulq 274 /// CHECK: movq 275 /// CHECK: andq 276 /// CHECK: jz/eq 277 /// CHECK: movq 278 /// CHECK: sarq 279 /// CHECK: shlq 280 /// CHECK: orq $noinline$LongMod2(long v)281 private static Long $noinline$LongMod2(long v) { 282 long r = v % 2; 283 return r; 284 } 285 286 /// CHECK-START-ARM64: java.lang.Long RemTest.$noinline$LongModMinus2(long) disassembly (after) 287 /// CHECK: cmp x{{\d+}}, #0x0 288 /// CHECK: and x{{\d+}}, x{{\d+}}, #0x1 289 /// CHECK: cneg x{{\d+}}, x{{\d+}}, lt 290 /// CHECK-START-X86_64: java.lang.Long RemTest.$noinline$LongModMinus2(long) disassembly (after) 291 /// CHECK: Rem [{{j\d+}},{{j\d+}}] 292 /// CHECK-NOT: imul 293 /// CHECK-NOT: shrq 294 /// CHECK-NOT: imulq 295 /// CHECK: movq 296 /// CHECK: andq 297 /// CHECK: jz/eq 298 /// CHECK: movq 299 /// CHECK: sarq 300 /// CHECK: shlq 301 /// CHECK: orq $noinline$LongModMinus2(long v)302 private static Long $noinline$LongModMinus2(long v) { 303 long r = v % -2; 304 return r; 305 } 306 307 /// CHECK-START-ARM64: java.lang.Long RemTest.$noinline$LongMod16(long) disassembly (after) 308 /// CHECK: negs x{{\d+}}, x{{\d+}} 309 /// CHECK: and x{{\d+}}, x{{\d+}}, #0xf 310 /// CHECK: and x{{\d+}}, x{{\d+}}, #0xf 311 /// CHECK: csneg x{{\d+}}, x{{\d+}}, mi 312 313 /// CHECK-START-X86_64: java.lang.Long RemTest.$noinline$LongMod16(long) disassembly (after) 314 /// CHECK: Rem [{{j\d+}},{{j\d+}}] 315 /// CHECK-NOT: imul 316 /// CHECK-NOT: shrq 317 /// CHECK-NOT: imulq 318 /// CHECK: movq 319 /// CHECK: andq 320 /// CHECK: jz/eq 321 /// CHECK: movq 322 /// CHECK: sarq 323 /// CHECK: shlq 324 /// CHECK: orq $noinline$LongMod16(long v)325 private static Long $noinline$LongMod16(long v) { 326 long r = v % 16; 327 return r; 328 } 329 330 /// CHECK-START-ARM64: java.lang.Long RemTest.$noinline$LongModMinus16(long) disassembly (after) 331 /// CHECK: negs x{{\d+}}, x{{\d+}} 332 /// CHECK: and x{{\d+}}, x{{\d+}}, #0xf 333 /// CHECK: and x{{\d+}}, x{{\d+}}, #0xf 334 /// CHECK: csneg x{{\d+}}, x{{\d+}}, mi 335 /// CHECK-START-X86_64: java.lang.Long RemTest.$noinline$LongModMinus16(long) disassembly (after) 336 /// CHECK: Rem [{{j\d+}},{{j\d+}}] 337 /// CHECK-NOT: imul 338 /// CHECK-NOT: shrq 339 /// CHECK-NOT: imulq 340 /// CHECK: movq 341 /// CHECK: andq 342 /// CHECK: jz/eq 343 /// CHECK: movq 344 /// CHECK: sarq 345 /// CHECK: shlq 346 /// CHECK: orq $noinline$LongModMinus16(long v)347 private static Long $noinline$LongModMinus16(long v) { 348 long r = v % -16; 349 return r; 350 } 351 352 /// CHECK-START-ARM64: java.lang.Long RemTest.$noinline$LongModLongMin(long) disassembly (after) 353 /// CHECK: negs x{{\d+}}, x{{\d+}} 354 /// CHECK: and x{{\d+}}, x{{\d+}}, #0x7fffffffffffffff 355 /// CHECK: and x{{\d+}}, x{{\d+}}, #0x7fffffffffffffff 356 /// CHECK: csneg x{{\d+}}, x{{\d+}}, mi 357 /// CHECK-START-X86_64: java.lang.Long RemTest.$noinline$LongModLongMin(long) disassembly (after) 358 /// CHECK: Rem [{{j\d+}},{{j\d+}}] 359 /// CHECK-NOT: imul 360 /// CHECK-NOT: shrq 361 /// CHECK-NOT: imulq 362 /// CHECK: movq 363 /// CHECK: andq 364 /// CHECK: jz/eq 365 /// CHECK: movq 366 /// CHECK: sarq 367 /// CHECK: shlq 368 /// CHECK: orq $noinline$LongModLongMin(long v)369 private static Long $noinline$LongModLongMin(long v) { 370 long r = v % Long.MIN_VALUE; 371 return r; 372 } 373 } 374