1 // Copyright 2006 The Android Open Source Project 2 3 /** 4 * Test arithmetic operations. 5 */ 6 public class IntMath { 7 8 static void shiftTest1() { 9 System.out.println("IntMath.shiftTest1"); 10 11 final int[] mBytes = { 12 0x11, 0x22, 0x33, 0x44, 0x88, 0x99, 0xaa, 0xbb 13 }; 14 long l; 15 int i1, i2; 16 17 i1 = mBytes[0] | mBytes[1] << 8 | mBytes[2] << 16 | mBytes[3] << 24; 18 i2 = mBytes[4] | mBytes[5] << 8 | mBytes[6] << 16 | mBytes[7] << 24; 19 l = i1 | ((long)i2 << 32); 20 21 assert(i1 == 0x44332211); 22 assert(i2 == 0xbbaa9988); 23 assert(l == 0xbbaa998844332211L); 24 25 l = (long)mBytes[0] 26 | (long)mBytes[1] << 8 27 | (long)mBytes[2] << 16 28 | (long)mBytes[3] << 24 29 | (long)mBytes[4] << 32 30 | (long)mBytes[5] << 40 31 | (long)mBytes[6] << 48 32 | (long)mBytes[7] << 56; 33 34 assert(l == 0xbbaa998844332211L); 35 } 36 37 static void shiftTest2() { 38 System.out.println("IntMath.shiftTest2"); 39 40 long a = 0x11; 41 long b = 0x22; 42 long c = 0x33; 43 long d = 0x44; 44 long e = 0x55; 45 long f = 0x66; 46 long g = 0x77; 47 long h = 0x88; 48 49 long result = ((a << 56) | (b << 48) | (c << 40) | (d << 32) | 50 (e << 24) | (f << 16) | (g << 8) | h); 51 52 assert(result == 0x1122334455667788L); 53 } 54 55 static void unsignedShiftTest() { 56 System.out.println("IntMath.unsignedShiftTest"); 57 58 byte b = -4; 59 short s = -4; 60 char c = 0xfffc; 61 int i = -4; 62 63 b >>>= 4; 64 s >>>= 4; 65 c >>>= 4; 66 i >>>= 4; 67 68 assert((int) b == -1); 69 assert((int) s == -1); 70 assert((int) c == 0x0fff); 71 assert(i == 268435455); 72 } 73 74 static void convTest() { 75 System.out.println("IntMath.convTest"); 76 77 float f; 78 double d; 79 int i; 80 long l; 81 82 /* int --> long */ 83 i = 7654; 84 l = (long) i; 85 assert(l == 7654L); 86 87 i = -7654; 88 l = (long) i; 89 assert(l == -7654L); 90 91 /* long --> int (with truncation) */ 92 l = 5678956789L; 93 i = (int) l; 94 assert(i == 1383989493); 95 96 l = -5678956789L; 97 i = (int) l; 98 assert(i == -1383989493); 99 } 100 101 static void charSubTest() { 102 System.out.println("IntMath.charSubTest"); 103 104 char char1 = 0x00e9; 105 char char2 = 0xffff; 106 int i; 107 108 /* chars are unsigned-expanded to ints before subtraction */ 109 i = char1 - char2; 110 assert(i == 0xffff00ea); 111 } 112 113 /* 114 * We pass in the arguments and return the results so the compiler 115 * doesn't do the math for us. (x=70000, y=-3) 116 */ 117 static int[] intOperTest(int x, int y) { 118 System.out.println("IntMath.intOperTest"); 119 120 int[] results = new int[10]; 121 122 /* this seems to generate "op-int" instructions */ 123 results[0] = x + y; 124 results[1] = x - y; 125 results[2] = x * y; 126 results[3] = x * x; 127 results[4] = x / y; 128 results[5] = x % -y; 129 results[6] = x & y; 130 results[7] = x | y; 131 results[8] = x ^ y; 132 133 /* this seems to generate "op-int/2addr" instructions */ 134 results[9] = x + ((((((((x + y) - y) * y) / y) % y) & y) | y) ^ y); 135 136 return results; 137 } 138 static void intOperCheck(int[] results) { 139 System.out.println("IntMath.intOperCheck"); 140 141 /* check this edge case while we're here (div-int/2addr) */ 142 int minInt = -2147483648; 143 int negOne = -results[5]; 144 int plusOne = 1; 145 int result = (((minInt + plusOne) - plusOne) / negOne) / negOne; 146 assert(result == minInt); 147 148 assert(results[0] == 69997); 149 assert(results[1] == 70003); 150 assert(results[2] == -210000); 151 assert(results[3] == 605032704); // overflow / truncate 152 assert(results[4] == -23333); 153 assert(results[5] == 1); 154 assert(results[6] == 70000); 155 assert(results[7] == -3); 156 assert(results[8] == -70003); 157 assert(results[9] == 70000); 158 } 159 160 /* 161 * More operations, this time with 16-bit constants. (x=77777) 162 */ 163 static int[] lit16Test(int x) { 164 System.out.println("IntMath.lit16Test"); 165 166 int[] results = new int[8]; 167 168 /* try to generate op-int/lit16" instructions */ 169 results[0] = x + 1000; 170 results[1] = 1000 - x; 171 results[2] = x * 1000; 172 results[3] = x / 1000; 173 results[4] = x % 1000; 174 results[5] = x & 1000; 175 results[6] = x | -1000; 176 results[7] = x ^ -1000; 177 return results; 178 } 179 static void lit16Check(int[] results) { 180 assert(results[0] == 78777); 181 assert(results[1] == -76777); 182 assert(results[2] == 77777000); 183 assert(results[3] == 77); 184 assert(results[4] == 777); 185 assert(results[5] == 960); 186 assert(results[6] == -39); 187 assert(results[7] == -76855); 188 } 189 190 /* 191 * More operations, this time with 8-bit constants. (x=-55555) 192 */ 193 static int[] lit8Test(int x) { 194 System.out.println("IntMath.lit8Test"); 195 196 int[] results = new int[8]; 197 198 /* try to generate op-int/lit8" instructions */ 199 results[0] = x + 10; 200 results[1] = 10 - x; 201 results[2] = x * 10; 202 results[3] = x / 10; 203 results[4] = x % 10; 204 results[5] = x & 10; 205 results[6] = x | -10; 206 results[7] = x ^ -10; 207 return results; 208 } 209 static void lit8Check(int[] results) { 210 //for (int i = 0; i < results.length; i++) 211 // System.out.println(" " + i + ": " + results[i]); 212 213 /* check this edge case while we're here (div-int/lit8) */ 214 int minInt = -2147483648; 215 int result = minInt / -1; 216 assert(result == minInt); 217 218 assert(results[0] == -55545); 219 assert(results[1] == 55565); 220 assert(results[2] == -555550); 221 assert(results[3] == -5555); 222 assert(results[4] == -5); 223 assert(results[5] == 8); 224 assert(results[6] == -1); 225 assert(results[7] == 55563); 226 } 227 228 229 /* 230 * Shift some data. (value=0xff00aa01, dist=8) 231 */ 232 static int[] intShiftTest(int value, int dist) { 233 System.out.println("IntMath.intShiftTest"); 234 235 int results[] = new int[4]; 236 237 results[0] = value << dist; 238 results[1] = value >> dist; 239 results[2] = value >>> dist; 240 241 results[3] = (((value << dist) >> dist) >>> dist) << dist; 242 return results; 243 } 244 static void intShiftCheck(int[] results) { 245 System.out.println("IntMath.intShiftCheck"); 246 247 assert(results[0] == 0x00aa0100); 248 assert(results[1] == 0xffff00aa); 249 assert(results[2] == 0x00ff00aa); 250 assert(results[3] == 0xaa00); 251 } 252 253 /* 254 * We pass in the arguments and return the results so the compiler 255 * doesn't do the math for us. (x=70000000000, y=-3) 256 */ 257 static long[] longOperTest(long x, long y) { 258 System.out.println("IntMath.longOperTest"); 259 260 long[] results = new long[10]; 261 262 /* this seems to generate "op-long" instructions */ 263 results[0] = x + y; 264 results[1] = x - y; 265 results[2] = x * y; 266 results[3] = x * x; 267 results[4] = x / y; 268 results[5] = x % -y; 269 results[6] = x & y; 270 results[7] = x | y; 271 results[8] = x ^ y; 272 273 /* this seems to generate "op-long/2addr" instructions */ 274 results[9] = x + ((((((((x + y) - y) * y) / y) % y) & y) | y) ^ y); 275 276 return results; 277 } 278 static void longOperCheck(long[] results) { 279 System.out.println("IntMath.longOperCheck"); 280 281 /* check this edge case while we're here (div-long/2addr) */ 282 long minLong = -9223372036854775808L; 283 long negOne = -results[5]; 284 long plusOne = 1; 285 long result = (((minLong + plusOne) - plusOne) / negOne) / negOne; 286 assert(result == minLong); 287 288 assert(results[0] == 69999999997L); 289 assert(results[1] == 70000000003L); 290 assert(results[2] == -210000000000L); 291 assert(results[3] == -6833923606740729856L); // overflow 292 assert(results[4] == -23333333333L); 293 assert(results[5] == 1); 294 assert(results[6] == 70000000000L); 295 assert(results[7] == -3); 296 assert(results[8] == -70000000003L); 297 assert(results[9] == 70000000000L); 298 299 assert(results.length == 10); 300 } 301 302 /* 303 * Shift some data. (value=0xd5aa96deff00aa01, dist=8) 304 */ 305 static long[] longShiftTest(long value, int dist) { 306 System.out.println("IntMath.longShiftTest"); 307 308 long results[] = new long[4]; 309 310 results[0] = value << dist; 311 results[1] = value >> dist; 312 results[2] = value >>> dist; 313 314 results[3] = (((value << dist) >> dist) >>> dist) << dist; 315 return results; 316 } 317 static long longShiftCheck(long[] results) { 318 System.out.println("IntMath.longShiftCheck"); 319 320 assert(results[0] == 0x96deff00aa010000L); 321 assert(results[1] == 0xffffd5aa96deff00L); 322 assert(results[2] == 0x0000d5aa96deff00L); 323 assert(results[3] == 0xffff96deff000000L); 324 325 assert(results.length == 4); 326 327 return results[0]; // test return-long 328 } 329 330 331 /* 332 * Try to cause some unary operations. 333 */ 334 static int unopTest(int x) { 335 x = -x; 336 x ^= 0xffffffff; 337 return x; 338 } 339 static void unopCheck(int result) { 340 assert(result == 37); 341 } 342 343 static class Shorty { 344 public short mShort; 345 public char mChar; 346 public byte mByte; 347 }; 348 349 /* 350 * Truncate an int. 351 */ 352 static Shorty truncateTest(int x) { 353 System.out.println("IntMath.truncateTest"); 354 Shorty shorts = new Shorty(); 355 356 shorts.mShort = (short) x; 357 shorts.mChar = (char) x; 358 shorts.mByte = (byte) x; 359 return shorts; 360 } 361 static void truncateCheck(Shorty shorts) { 362 assert(shorts.mShort == -5597); // 0xea23 363 assert(shorts.mChar == 59939); // 0xea23 364 assert(shorts.mByte == 35); // 0x23 365 } 366 367 /* 368 * Verify that we get a divide-by-zero exception. 369 */ 370 static void divideByZero(int z) { 371 System.out.println("IntMath.divideByZero"); 372 373 try { 374 int x = 100 / z; 375 assert(false); 376 } catch (ArithmeticException ae) { 377 } 378 379 try { 380 int x = 100 % z; 381 assert(false); 382 } catch (ArithmeticException ae) { 383 } 384 385 try { 386 long x = 100L / z; 387 assert(false); 388 } catch (ArithmeticException ae) { 389 } 390 391 try { 392 long x = 100L % z; 393 assert(false); 394 } catch (ArithmeticException ae) { 395 } 396 } 397 398 /* 399 * Check an edge condition: dividing the most-negative integer by -1 400 * returns the most-negative integer, and doesn't cause an exception. 401 * 402 * Pass in -1, -1L. 403 */ 404 static void bigDivideOverflow(int idiv, long ldiv) { 405 System.out.println("IntMath.bigDivideOverflow"); 406 int mostNegInt = (int) 0x80000000; 407 long mostNegLong = (long) 0x8000000000000000L; 408 409 int intDivResult = mostNegInt / idiv; 410 int intModResult = mostNegInt % idiv; 411 long longDivResult = mostNegLong / ldiv; 412 long longModResult = mostNegLong % ldiv; 413 414 assert(intDivResult == mostNegInt); 415 assert(intModResult == 0); 416 assert(longDivResult == mostNegLong); 417 assert(longModResult == 0); 418 } 419 420 /* 421 * Check "const" instructions. We use negative values to ensure that 422 * sign-extension is happening. 423 */ 424 static void checkConsts(byte small, short medium, int large, long huge) { 425 System.out.println("IntMath.checkConsts"); 426 427 assert(small == 1); // const/4 428 assert(medium == -256); // const/16 429 assert(medium == -256L); // const-wide/16 430 assert(large == -88888); // const 431 assert(large == -88888L); // const-wide/32 432 assert(huge == 0x9922334455667788L); // const-wide 433 } 434 435 /* 436 * Test some java.lang.Math functions. 437 * 438 * The method arguments are positive values. 439 */ 440 static void jlmTests(int ii, long ll) { 441 System.out.println("IntMath.jlmTests"); 442 443 assert(Math.abs(ii) == ii); 444 assert(Math.abs(-ii) == ii); 445 assert(Math.min(ii, -5) == -5); 446 assert(Math.max(ii, -5) == ii); 447 448 assert(Math.abs(ll) == ll); 449 assert(Math.abs(-ll) == ll); 450 assert(Math.min(ll, -5L) == -5L); 451 assert(Math.max(ll, -5L) == ll); 452 } 453 454 public static void run() { 455 shiftTest1(); 456 shiftTest2(); 457 unsignedShiftTest(); 458 convTest(); 459 charSubTest(); 460 461 int[] intResults; 462 long[] longResults; 463 464 intResults = intOperTest(70000, -3); 465 intOperCheck(intResults); 466 longResults = longOperTest(70000000000L, -3L); 467 longOperCheck(longResults); 468 469 intResults = lit16Test(77777); 470 lit16Check(intResults); 471 intResults = lit8Test(-55555); 472 lit8Check(intResults); 473 474 intResults = intShiftTest(0xff00aa01, 8); 475 intShiftCheck(intResults); 476 longResults = longShiftTest(0xd5aa96deff00aa01L, 16); 477 long longRet = longShiftCheck(longResults); 478 assert(longRet == 0x96deff00aa010000L); 479 480 Shorty shorts = truncateTest(-16717277); // 0xff00ea23 481 truncateCheck(shorts); 482 483 divideByZero(0); 484 bigDivideOverflow(-1, -1L); 485 486 checkConsts((byte) 1, (short) -256, -88888, 0x9922334455667788L); 487 488 unopCheck(unopTest(38)); 489 490 jlmTests(12345, 0x1122334455667788L); 491 } 492 } 493