blob: 292fdd3877e94fa28bcb2a562bc5f0394d783aa8 [file] [log] [blame]
Elliott Hughes2faa5f12012-01-30 14:42:07 -08001/*
2 * Copyright (C) 2006 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 */
jeffhao5d1ac922011-09-29 17:41:15 -070016
17/**
18 * Test arithmetic operations.
19 */
20public class IntMath {
21
22 static void shiftTest1() {
23 System.out.println("IntMath.shiftTest1");
24
25 final int[] mBytes = {
26 0x11, 0x22, 0x33, 0x44, 0x88, 0x99, 0xaa, 0xbb
27 };
28 long l;
29 int i1, i2;
30
31 i1 = mBytes[0] | mBytes[1] << 8 | mBytes[2] << 16 | mBytes[3] << 24;
32 i2 = mBytes[4] | mBytes[5] << 8 | mBytes[6] << 16 | mBytes[7] << 24;
33 l = i1 | ((long)i2 << 32);
34
jeffhao795d78f2011-09-30 18:34:35 -070035 Main.assertTrue(i1 == 0x44332211);
36 Main.assertTrue(i2 == 0xbbaa9988);
37 Main.assertTrue(l == 0xbbaa998844332211L);
jeffhao5d1ac922011-09-29 17:41:15 -070038
39 l = (long)mBytes[0]
40 | (long)mBytes[1] << 8
41 | (long)mBytes[2] << 16
42 | (long)mBytes[3] << 24
43 | (long)mBytes[4] << 32
44 | (long)mBytes[5] << 40
45 | (long)mBytes[6] << 48
46 | (long)mBytes[7] << 56;
47
jeffhao795d78f2011-09-30 18:34:35 -070048 Main.assertTrue(l == 0xbbaa998844332211L);
jeffhao5d1ac922011-09-29 17:41:15 -070049 }
50
51 static void shiftTest2() {
52 System.out.println("IntMath.shiftTest2");
53
54 long a = 0x11;
55 long b = 0x22;
56 long c = 0x33;
57 long d = 0x44;
58 long e = 0x55;
59 long f = 0x66;
60 long g = 0x77;
61 long h = 0x88;
62
63 long result = ((a << 56) | (b << 48) | (c << 40) | (d << 32) |
64 (e << 24) | (f << 16) | (g << 8) | h);
65
jeffhao795d78f2011-09-30 18:34:35 -070066 Main.assertTrue(result == 0x1122334455667788L);
jeffhao5d1ac922011-09-29 17:41:15 -070067 }
68
69 static void unsignedShiftTest() {
70 System.out.println("IntMath.unsignedShiftTest");
71
72 byte b = -4;
73 short s = -4;
74 char c = 0xfffc;
75 int i = -4;
76
77 b >>>= 4;
78 s >>>= 4;
79 c >>>= 4;
80 i >>>= 4;
81
jeffhao795d78f2011-09-30 18:34:35 -070082 Main.assertTrue((int) b == -1);
83 Main.assertTrue((int) s == -1);
84 Main.assertTrue((int) c == 0x0fff);
85 Main.assertTrue(i == 268435455);
jeffhao5d1ac922011-09-29 17:41:15 -070086 }
87
Ian Rogers55b16ce2012-02-17 14:47:17 -080088 static void shiftTest3(int thirtyTwo) {
89 System.out.println("IntMath.shiftTest3");
90
91 int one = thirtyTwo / 32;
92 int sixteen = thirtyTwo / 2;
93 int thirtyThree = thirtyTwo + 1;
94 int sixtyFour = thirtyTwo * 2;
95
96 Main.assertTrue(1 << thirtyTwo == 1);
97 Main.assertTrue((1 << sixteen) << sixteen == 0);
98 Main.assertTrue(1 << thirtyThree == 2);
99 Main.assertTrue(1 << -one == -2147483648);
100 Main.assertTrue(1 << -thirtyTwo == 1);
101 Main.assertTrue(1 << -thirtyThree == -2147483648);
102 Main.assertTrue(1 << thirtyThree == 2);
103
104 Main.assertTrue(1 >> thirtyTwo == 1);
105 Main.assertTrue((1 >> sixteen) >> sixteen == 0);
106 Main.assertTrue(1 >> thirtyThree == 0);
107 Main.assertTrue(1 >> -one == 0);
108 Main.assertTrue(1 >> -thirtyTwo == 1);
109 Main.assertTrue(1 >> -thirtyThree == 0);
110 Main.assertTrue(-4 >> thirtyThree == -2);
111
112 Main.assertTrue(1 >>> thirtyTwo == 1);
113 Main.assertTrue((1 >>> sixteen) >>> sixteen == 0);
114 Main.assertTrue(1 >>> thirtyThree == 0);
115 Main.assertTrue(1 >>> -one == 0);
116 Main.assertTrue(1 >>> -thirtyTwo == 1);
117 Main.assertTrue(1 >>> -thirtyThree == 0);
118 Main.assertTrue(-4 >>> thirtyThree == 2147483646);
119 }
120
jeffhao5d1ac922011-09-29 17:41:15 -0700121 static void convTest() {
122 System.out.println("IntMath.convTest");
123
124 float f;
125 double d;
126 int i;
127 long l;
128
129 /* int --> long */
130 i = 7654;
131 l = (long) i;
jeffhao795d78f2011-09-30 18:34:35 -0700132 Main.assertTrue(l == 7654L);
jeffhao5d1ac922011-09-29 17:41:15 -0700133
134 i = -7654;
135 l = (long) i;
jeffhao795d78f2011-09-30 18:34:35 -0700136 Main.assertTrue(l == -7654L);
jeffhao5d1ac922011-09-29 17:41:15 -0700137
138 /* long --> int (with truncation) */
139 l = 5678956789L;
140 i = (int) l;
jeffhao795d78f2011-09-30 18:34:35 -0700141 Main.assertTrue(i == 1383989493);
jeffhao5d1ac922011-09-29 17:41:15 -0700142
143 l = -5678956789L;
144 i = (int) l;
jeffhao795d78f2011-09-30 18:34:35 -0700145 Main.assertTrue(i == -1383989493);
jeffhao5d1ac922011-09-29 17:41:15 -0700146 }
147
148 static void charSubTest() {
149 System.out.println("IntMath.charSubTest");
150
151 char char1 = 0x00e9;
152 char char2 = 0xffff;
153 int i;
154
155 /* chars are unsigned-expanded to ints before subtraction */
156 i = char1 - char2;
jeffhao795d78f2011-09-30 18:34:35 -0700157 Main.assertTrue(i == 0xffff00ea);
jeffhao5d1ac922011-09-29 17:41:15 -0700158 }
159
160 /*
161 * We pass in the arguments and return the results so the compiler
162 * doesn't do the math for us. (x=70000, y=-3)
163 */
164 static int[] intOperTest(int x, int y) {
165 System.out.println("IntMath.intOperTest");
166
167 int[] results = new int[10];
168
169 /* this seems to generate "op-int" instructions */
170 results[0] = x + y;
171 results[1] = x - y;
172 results[2] = x * y;
173 results[3] = x * x;
174 results[4] = x / y;
175 results[5] = x % -y;
176 results[6] = x & y;
177 results[7] = x | y;
178 results[8] = x ^ y;
179
180 /* this seems to generate "op-int/2addr" instructions */
181 results[9] = x + ((((((((x + y) - y) * y) / y) % y) & y) | y) ^ y);
182
183 return results;
184 }
185 static void intOperCheck(int[] results) {
186 System.out.println("IntMath.intOperCheck");
187
188 /* check this edge case while we're here (div-int/2addr) */
189 int minInt = -2147483648;
190 int negOne = -results[5];
191 int plusOne = 1;
192 int result = (((minInt + plusOne) - plusOne) / negOne) / negOne;
jeffhao795d78f2011-09-30 18:34:35 -0700193 Main.assertTrue(result == minInt);
jeffhao5d1ac922011-09-29 17:41:15 -0700194
jeffhao795d78f2011-09-30 18:34:35 -0700195 Main.assertTrue(results[0] == 69997);
196 Main.assertTrue(results[1] == 70003);
197 Main.assertTrue(results[2] == -210000);
198 Main.assertTrue(results[3] == 605032704); // overflow / truncate
199 Main.assertTrue(results[4] == -23333);
200 Main.assertTrue(results[5] == 1);
201 Main.assertTrue(results[6] == 70000);
202 Main.assertTrue(results[7] == -3);
203 Main.assertTrue(results[8] == -70003);
204 Main.assertTrue(results[9] == 70000);
jeffhao5d1ac922011-09-29 17:41:15 -0700205 }
206
207 /*
208 * More operations, this time with 16-bit constants. (x=77777)
209 */
210 static int[] lit16Test(int x) {
211 System.out.println("IntMath.lit16Test");
212
213 int[] results = new int[8];
214
215 /* try to generate op-int/lit16" instructions */
216 results[0] = x + 1000;
217 results[1] = 1000 - x;
218 results[2] = x * 1000;
219 results[3] = x / 1000;
220 results[4] = x % 1000;
221 results[5] = x & 1000;
222 results[6] = x | -1000;
223 results[7] = x ^ -1000;
224 return results;
225 }
226 static void lit16Check(int[] results) {
jeffhao795d78f2011-09-30 18:34:35 -0700227 Main.assertTrue(results[0] == 78777);
228 Main.assertTrue(results[1] == -76777);
229 Main.assertTrue(results[2] == 77777000);
230 Main.assertTrue(results[3] == 77);
231 Main.assertTrue(results[4] == 777);
232 Main.assertTrue(results[5] == 960);
233 Main.assertTrue(results[6] == -39);
234 Main.assertTrue(results[7] == -76855);
jeffhao5d1ac922011-09-29 17:41:15 -0700235 }
236
237 /*
238 * More operations, this time with 8-bit constants. (x=-55555)
239 */
240 static int[] lit8Test(int x) {
241 System.out.println("IntMath.lit8Test");
242
243 int[] results = new int[8];
244
245 /* try to generate op-int/lit8" instructions */
246 results[0] = x + 10;
247 results[1] = 10 - x;
248 results[2] = x * 10;
249 results[3] = x / 10;
250 results[4] = x % 10;
251 results[5] = x & 10;
252 results[6] = x | -10;
253 results[7] = x ^ -10;
254 return results;
255 }
256 static void lit8Check(int[] results) {
257 //for (int i = 0; i < results.length; i++)
258 // System.out.println(" " + i + ": " + results[i]);
259
260 /* check this edge case while we're here (div-int/lit8) */
261 int minInt = -2147483648;
262 int result = minInt / -1;
jeffhao795d78f2011-09-30 18:34:35 -0700263 Main.assertTrue(result == minInt);
jeffhao5d1ac922011-09-29 17:41:15 -0700264
jeffhao795d78f2011-09-30 18:34:35 -0700265 Main.assertTrue(results[0] == -55545);
266 Main.assertTrue(results[1] == 55565);
267 Main.assertTrue(results[2] == -555550);
268 Main.assertTrue(results[3] == -5555);
269 Main.assertTrue(results[4] == -5);
270 Main.assertTrue(results[5] == 8);
271 Main.assertTrue(results[6] == -1);
272 Main.assertTrue(results[7] == 55563);
jeffhao5d1ac922011-09-29 17:41:15 -0700273 }
274
275
276 /*
277 * Shift some data. (value=0xff00aa01, dist=8)
278 */
279 static int[] intShiftTest(int value, int dist) {
280 System.out.println("IntMath.intShiftTest");
281
282 int results[] = new int[4];
283
284 results[0] = value << dist;
285 results[1] = value >> dist;
286 results[2] = value >>> dist;
287
288 results[3] = (((value << dist) >> dist) >>> dist) << dist;
289 return results;
290 }
291 static void intShiftCheck(int[] results) {
292 System.out.println("IntMath.intShiftCheck");
293
jeffhao795d78f2011-09-30 18:34:35 -0700294 Main.assertTrue(results[0] == 0x00aa0100);
295 Main.assertTrue(results[1] == 0xffff00aa);
296 Main.assertTrue(results[2] == 0x00ff00aa);
297 Main.assertTrue(results[3] == 0xaa00);
jeffhao5d1ac922011-09-29 17:41:15 -0700298 }
299
300 /*
301 * We pass in the arguments and return the results so the compiler
302 * doesn't do the math for us. (x=70000000000, y=-3)
303 */
304 static long[] longOperTest(long x, long y) {
305 System.out.println("IntMath.longOperTest");
306
307 long[] results = new long[10];
308
309 /* this seems to generate "op-long" instructions */
310 results[0] = x + y;
311 results[1] = x - y;
312 results[2] = x * y;
313 results[3] = x * x;
314 results[4] = x / y;
315 results[5] = x % -y;
316 results[6] = x & y;
317 results[7] = x | y;
318 results[8] = x ^ y;
319
320 /* this seems to generate "op-long/2addr" instructions */
321 results[9] = x + ((((((((x + y) - y) * y) / y) % y) & y) | y) ^ y);
322
323 return results;
324 }
325 static void longOperCheck(long[] results) {
326 System.out.println("IntMath.longOperCheck");
327
328 /* check this edge case while we're here (div-long/2addr) */
329 long minLong = -9223372036854775808L;
330 long negOne = -results[5];
331 long plusOne = 1;
332 long result = (((minLong + plusOne) - plusOne) / negOne) / negOne;
jeffhao795d78f2011-09-30 18:34:35 -0700333 Main.assertTrue(result == minLong);
jeffhao5d1ac922011-09-29 17:41:15 -0700334
jeffhao795d78f2011-09-30 18:34:35 -0700335 Main.assertTrue(results[0] == 69999999997L);
336 Main.assertTrue(results[1] == 70000000003L);
337 Main.assertTrue(results[2] == -210000000000L);
338 Main.assertTrue(results[3] == -6833923606740729856L); // overflow
339 Main.assertTrue(results[4] == -23333333333L);
340 Main.assertTrue(results[5] == 1);
341 Main.assertTrue(results[6] == 70000000000L);
342 Main.assertTrue(results[7] == -3);
343 Main.assertTrue(results[8] == -70000000003L);
344 Main.assertTrue(results[9] == 70000000000L);
jeffhao5d1ac922011-09-29 17:41:15 -0700345
jeffhao795d78f2011-09-30 18:34:35 -0700346 Main.assertTrue(results.length == 10);
jeffhao5d1ac922011-09-29 17:41:15 -0700347 }
348
349 /*
350 * Shift some data. (value=0xd5aa96deff00aa01, dist=8)
351 */
352 static long[] longShiftTest(long value, int dist) {
353 System.out.println("IntMath.longShiftTest");
354
355 long results[] = new long[4];
356
357 results[0] = value << dist;
358 results[1] = value >> dist;
359 results[2] = value >>> dist;
360
361 results[3] = (((value << dist) >> dist) >>> dist) << dist;
362 return results;
363 }
364 static long longShiftCheck(long[] results) {
365 System.out.println("IntMath.longShiftCheck");
366
jeffhao795d78f2011-09-30 18:34:35 -0700367 Main.assertTrue(results[0] == 0x96deff00aa010000L);
368 Main.assertTrue(results[1] == 0xffffd5aa96deff00L);
369 Main.assertTrue(results[2] == 0x0000d5aa96deff00L);
370 Main.assertTrue(results[3] == 0xffff96deff000000L);
jeffhao5d1ac922011-09-29 17:41:15 -0700371
jeffhao795d78f2011-09-30 18:34:35 -0700372 Main.assertTrue(results.length == 4);
jeffhao5d1ac922011-09-29 17:41:15 -0700373
374 return results[0]; // test return-long
375 }
376
377
378 /*
379 * Try to cause some unary operations.
380 */
381 static int unopTest(int x) {
382 x = -x;
383 x ^= 0xffffffff;
384 return x;
385 }
386 static void unopCheck(int result) {
jeffhao795d78f2011-09-30 18:34:35 -0700387 Main.assertTrue(result == 37);
jeffhao5d1ac922011-09-29 17:41:15 -0700388 }
389
390 static class Shorty {
391 public short mShort;
392 public char mChar;
393 public byte mByte;
394 };
395
396 /*
397 * Truncate an int.
398 */
399 static Shorty truncateTest(int x) {
400 System.out.println("IntMath.truncateTest");
401 Shorty shorts = new Shorty();
402
403 shorts.mShort = (short) x;
404 shorts.mChar = (char) x;
405 shorts.mByte = (byte) x;
406 return shorts;
407 }
408 static void truncateCheck(Shorty shorts) {
jeffhao795d78f2011-09-30 18:34:35 -0700409 Main.assertTrue(shorts.mShort == -5597); // 0xea23
410 Main.assertTrue(shorts.mChar == 59939); // 0xea23
411 Main.assertTrue(shorts.mByte == 35); // 0x23
jeffhao5d1ac922011-09-29 17:41:15 -0700412 }
413
414 /*
415 * Verify that we get a divide-by-zero exception.
416 */
417 static void divideByZero(int z) {
418 System.out.println("IntMath.divideByZero");
419
420 try {
421 int x = 100 / z;
jeffhao795d78f2011-09-30 18:34:35 -0700422 Main.assertTrue(false);
jeffhao5d1ac922011-09-29 17:41:15 -0700423 } catch (ArithmeticException ae) {
424 }
425
426 try {
427 int x = 100 % z;
jeffhao795d78f2011-09-30 18:34:35 -0700428 Main.assertTrue(false);
jeffhao5d1ac922011-09-29 17:41:15 -0700429 } catch (ArithmeticException ae) {
430 }
431
432 try {
433 long x = 100L / z;
jeffhao795d78f2011-09-30 18:34:35 -0700434 Main.assertTrue(false);
jeffhao5d1ac922011-09-29 17:41:15 -0700435 } catch (ArithmeticException ae) {
436 }
437
438 try {
439 long x = 100L % z;
jeffhao795d78f2011-09-30 18:34:35 -0700440 Main.assertTrue(false);
jeffhao5d1ac922011-09-29 17:41:15 -0700441 } catch (ArithmeticException ae) {
442 }
443 }
444
445 /*
446 * Check an edge condition: dividing the most-negative integer by -1
447 * returns the most-negative integer, and doesn't cause an exception.
448 *
449 * Pass in -1, -1L.
450 */
451 static void bigDivideOverflow(int idiv, long ldiv) {
452 System.out.println("IntMath.bigDivideOverflow");
453 int mostNegInt = (int) 0x80000000;
454 long mostNegLong = (long) 0x8000000000000000L;
455
456 int intDivResult = mostNegInt / idiv;
457 int intModResult = mostNegInt % idiv;
458 long longDivResult = mostNegLong / ldiv;
459 long longModResult = mostNegLong % ldiv;
460
jeffhao795d78f2011-09-30 18:34:35 -0700461 Main.assertTrue(intDivResult == mostNegInt);
462 Main.assertTrue(intModResult == 0);
463 Main.assertTrue(longDivResult == mostNegLong);
464 Main.assertTrue(longModResult == 0);
jeffhao5d1ac922011-09-29 17:41:15 -0700465 }
466
467 /*
468 * Check "const" instructions. We use negative values to ensure that
469 * sign-extension is happening.
470 */
471 static void checkConsts(byte small, short medium, int large, long huge) {
472 System.out.println("IntMath.checkConsts");
473
jeffhao795d78f2011-09-30 18:34:35 -0700474 Main.assertTrue(small == 1); // const/4
475 Main.assertTrue(medium == -256); // const/16
476 Main.assertTrue(medium == -256L); // const-wide/16
477 Main.assertTrue(large == -88888); // const
478 Main.assertTrue(large == -88888L); // const-wide/32
479 Main.assertTrue(huge == 0x9922334455667788L); // const-wide
jeffhao5d1ac922011-09-29 17:41:15 -0700480 }
481
482 /*
483 * Test some java.lang.Math functions.
484 *
485 * The method arguments are positive values.
486 */
487 static void jlmTests(int ii, long ll) {
488 System.out.println("IntMath.jlmTests");
489
jeffhao795d78f2011-09-30 18:34:35 -0700490 Main.assertTrue(Math.abs(ii) == ii);
491 Main.assertTrue(Math.abs(-ii) == ii);
492 Main.assertTrue(Math.min(ii, -5) == -5);
493 Main.assertTrue(Math.max(ii, -5) == ii);
jeffhao5d1ac922011-09-29 17:41:15 -0700494
jeffhao795d78f2011-09-30 18:34:35 -0700495 Main.assertTrue(Math.abs(ll) == ll);
496 Main.assertTrue(Math.abs(-ll) == ll);
497 Main.assertTrue(Math.min(ll, -5L) == -5L);
498 Main.assertTrue(Math.max(ll, -5L) == ll);
jeffhao5d1ac922011-09-29 17:41:15 -0700499 }
500
501 public static void run() {
502 shiftTest1();
503 shiftTest2();
504 unsignedShiftTest();
Ian Rogers55b16ce2012-02-17 14:47:17 -0800505 shiftTest3(32);
jeffhao5d1ac922011-09-29 17:41:15 -0700506 convTest();
507 charSubTest();
508
509 int[] intResults;
510 long[] longResults;
511
512 intResults = intOperTest(70000, -3);
513 intOperCheck(intResults);
514 longResults = longOperTest(70000000000L, -3L);
515 longOperCheck(longResults);
516
517 intResults = lit16Test(77777);
518 lit16Check(intResults);
519 intResults = lit8Test(-55555);
520 lit8Check(intResults);
521
522 intResults = intShiftTest(0xff00aa01, 8);
523 intShiftCheck(intResults);
524 longResults = longShiftTest(0xd5aa96deff00aa01L, 16);
525 long longRet = longShiftCheck(longResults);
jeffhao795d78f2011-09-30 18:34:35 -0700526 Main.assertTrue(longRet == 0x96deff00aa010000L);
jeffhao5d1ac922011-09-29 17:41:15 -0700527
528 Shorty shorts = truncateTest(-16717277); // 0xff00ea23
529 truncateCheck(shorts);
530
531 divideByZero(0);
532 bigDivideOverflow(-1, -1L);
533
534 checkConsts((byte) 1, (short) -256, -88888, 0x9922334455667788L);
535
536 unopCheck(unopTest(38));
537
538 jlmTests(12345, 0x1122334455667788L);
539 }
540}