blob: be883b9e7d209c3317c206a5c16db82506c1538a [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
88 static void convTest() {
89 System.out.println("IntMath.convTest");
90
91 float f;
92 double d;
93 int i;
94 long l;
95
96 /* int --> long */
97 i = 7654;
98 l = (long) i;
jeffhao795d78f2011-09-30 18:34:35 -070099 Main.assertTrue(l == 7654L);
jeffhao5d1ac922011-09-29 17:41:15 -0700100
101 i = -7654;
102 l = (long) i;
jeffhao795d78f2011-09-30 18:34:35 -0700103 Main.assertTrue(l == -7654L);
jeffhao5d1ac922011-09-29 17:41:15 -0700104
105 /* long --> int (with truncation) */
106 l = 5678956789L;
107 i = (int) l;
jeffhao795d78f2011-09-30 18:34:35 -0700108 Main.assertTrue(i == 1383989493);
jeffhao5d1ac922011-09-29 17:41:15 -0700109
110 l = -5678956789L;
111 i = (int) l;
jeffhao795d78f2011-09-30 18:34:35 -0700112 Main.assertTrue(i == -1383989493);
jeffhao5d1ac922011-09-29 17:41:15 -0700113 }
114
115 static void charSubTest() {
116 System.out.println("IntMath.charSubTest");
117
118 char char1 = 0x00e9;
119 char char2 = 0xffff;
120 int i;
121
122 /* chars are unsigned-expanded to ints before subtraction */
123 i = char1 - char2;
jeffhao795d78f2011-09-30 18:34:35 -0700124 Main.assertTrue(i == 0xffff00ea);
jeffhao5d1ac922011-09-29 17:41:15 -0700125 }
126
127 /*
128 * We pass in the arguments and return the results so the compiler
129 * doesn't do the math for us. (x=70000, y=-3)
130 */
131 static int[] intOperTest(int x, int y) {
132 System.out.println("IntMath.intOperTest");
133
134 int[] results = new int[10];
135
136 /* this seems to generate "op-int" instructions */
137 results[0] = x + y;
138 results[1] = x - y;
139 results[2] = x * y;
140 results[3] = x * x;
141 results[4] = x / y;
142 results[5] = x % -y;
143 results[6] = x & y;
144 results[7] = x | y;
145 results[8] = x ^ y;
146
147 /* this seems to generate "op-int/2addr" instructions */
148 results[9] = x + ((((((((x + y) - y) * y) / y) % y) & y) | y) ^ y);
149
150 return results;
151 }
152 static void intOperCheck(int[] results) {
153 System.out.println("IntMath.intOperCheck");
154
155 /* check this edge case while we're here (div-int/2addr) */
156 int minInt = -2147483648;
157 int negOne = -results[5];
158 int plusOne = 1;
159 int result = (((minInt + plusOne) - plusOne) / negOne) / negOne;
jeffhao795d78f2011-09-30 18:34:35 -0700160 Main.assertTrue(result == minInt);
jeffhao5d1ac922011-09-29 17:41:15 -0700161
jeffhao795d78f2011-09-30 18:34:35 -0700162 Main.assertTrue(results[0] == 69997);
163 Main.assertTrue(results[1] == 70003);
164 Main.assertTrue(results[2] == -210000);
165 Main.assertTrue(results[3] == 605032704); // overflow / truncate
166 Main.assertTrue(results[4] == -23333);
167 Main.assertTrue(results[5] == 1);
168 Main.assertTrue(results[6] == 70000);
169 Main.assertTrue(results[7] == -3);
170 Main.assertTrue(results[8] == -70003);
171 Main.assertTrue(results[9] == 70000);
jeffhao5d1ac922011-09-29 17:41:15 -0700172 }
173
174 /*
175 * More operations, this time with 16-bit constants. (x=77777)
176 */
177 static int[] lit16Test(int x) {
178 System.out.println("IntMath.lit16Test");
179
180 int[] results = new int[8];
181
182 /* try to generate op-int/lit16" instructions */
183 results[0] = x + 1000;
184 results[1] = 1000 - x;
185 results[2] = x * 1000;
186 results[3] = x / 1000;
187 results[4] = x % 1000;
188 results[5] = x & 1000;
189 results[6] = x | -1000;
190 results[7] = x ^ -1000;
191 return results;
192 }
193 static void lit16Check(int[] results) {
jeffhao795d78f2011-09-30 18:34:35 -0700194 Main.assertTrue(results[0] == 78777);
195 Main.assertTrue(results[1] == -76777);
196 Main.assertTrue(results[2] == 77777000);
197 Main.assertTrue(results[3] == 77);
198 Main.assertTrue(results[4] == 777);
199 Main.assertTrue(results[5] == 960);
200 Main.assertTrue(results[6] == -39);
201 Main.assertTrue(results[7] == -76855);
jeffhao5d1ac922011-09-29 17:41:15 -0700202 }
203
204 /*
205 * More operations, this time with 8-bit constants. (x=-55555)
206 */
207 static int[] lit8Test(int x) {
208 System.out.println("IntMath.lit8Test");
209
210 int[] results = new int[8];
211
212 /* try to generate op-int/lit8" instructions */
213 results[0] = x + 10;
214 results[1] = 10 - x;
215 results[2] = x * 10;
216 results[3] = x / 10;
217 results[4] = x % 10;
218 results[5] = x & 10;
219 results[6] = x | -10;
220 results[7] = x ^ -10;
221 return results;
222 }
223 static void lit8Check(int[] results) {
224 //for (int i = 0; i < results.length; i++)
225 // System.out.println(" " + i + ": " + results[i]);
226
227 /* check this edge case while we're here (div-int/lit8) */
228 int minInt = -2147483648;
229 int result = minInt / -1;
jeffhao795d78f2011-09-30 18:34:35 -0700230 Main.assertTrue(result == minInt);
jeffhao5d1ac922011-09-29 17:41:15 -0700231
jeffhao795d78f2011-09-30 18:34:35 -0700232 Main.assertTrue(results[0] == -55545);
233 Main.assertTrue(results[1] == 55565);
234 Main.assertTrue(results[2] == -555550);
235 Main.assertTrue(results[3] == -5555);
236 Main.assertTrue(results[4] == -5);
237 Main.assertTrue(results[5] == 8);
238 Main.assertTrue(results[6] == -1);
239 Main.assertTrue(results[7] == 55563);
jeffhao5d1ac922011-09-29 17:41:15 -0700240 }
241
242
243 /*
244 * Shift some data. (value=0xff00aa01, dist=8)
245 */
246 static int[] intShiftTest(int value, int dist) {
247 System.out.println("IntMath.intShiftTest");
248
249 int results[] = new int[4];
250
251 results[0] = value << dist;
252 results[1] = value >> dist;
253 results[2] = value >>> dist;
254
255 results[3] = (((value << dist) >> dist) >>> dist) << dist;
256 return results;
257 }
258 static void intShiftCheck(int[] results) {
259 System.out.println("IntMath.intShiftCheck");
260
jeffhao795d78f2011-09-30 18:34:35 -0700261 Main.assertTrue(results[0] == 0x00aa0100);
262 Main.assertTrue(results[1] == 0xffff00aa);
263 Main.assertTrue(results[2] == 0x00ff00aa);
264 Main.assertTrue(results[3] == 0xaa00);
jeffhao5d1ac922011-09-29 17:41:15 -0700265 }
266
267 /*
268 * We pass in the arguments and return the results so the compiler
269 * doesn't do the math for us. (x=70000000000, y=-3)
270 */
271 static long[] longOperTest(long x, long y) {
272 System.out.println("IntMath.longOperTest");
273
274 long[] results = new long[10];
275
276 /* this seems to generate "op-long" instructions */
277 results[0] = x + y;
278 results[1] = x - y;
279 results[2] = x * y;
280 results[3] = x * x;
281 results[4] = x / y;
282 results[5] = x % -y;
283 results[6] = x & y;
284 results[7] = x | y;
285 results[8] = x ^ y;
286
287 /* this seems to generate "op-long/2addr" instructions */
288 results[9] = x + ((((((((x + y) - y) * y) / y) % y) & y) | y) ^ y);
289
290 return results;
291 }
292 static void longOperCheck(long[] results) {
293 System.out.println("IntMath.longOperCheck");
294
295 /* check this edge case while we're here (div-long/2addr) */
296 long minLong = -9223372036854775808L;
297 long negOne = -results[5];
298 long plusOne = 1;
299 long result = (((minLong + plusOne) - plusOne) / negOne) / negOne;
jeffhao795d78f2011-09-30 18:34:35 -0700300 Main.assertTrue(result == minLong);
jeffhao5d1ac922011-09-29 17:41:15 -0700301
jeffhao795d78f2011-09-30 18:34:35 -0700302 Main.assertTrue(results[0] == 69999999997L);
303 Main.assertTrue(results[1] == 70000000003L);
304 Main.assertTrue(results[2] == -210000000000L);
305 Main.assertTrue(results[3] == -6833923606740729856L); // overflow
306 Main.assertTrue(results[4] == -23333333333L);
307 Main.assertTrue(results[5] == 1);
308 Main.assertTrue(results[6] == 70000000000L);
309 Main.assertTrue(results[7] == -3);
310 Main.assertTrue(results[8] == -70000000003L);
311 Main.assertTrue(results[9] == 70000000000L);
jeffhao5d1ac922011-09-29 17:41:15 -0700312
jeffhao795d78f2011-09-30 18:34:35 -0700313 Main.assertTrue(results.length == 10);
jeffhao5d1ac922011-09-29 17:41:15 -0700314 }
315
316 /*
317 * Shift some data. (value=0xd5aa96deff00aa01, dist=8)
318 */
319 static long[] longShiftTest(long value, int dist) {
320 System.out.println("IntMath.longShiftTest");
321
322 long results[] = new long[4];
323
324 results[0] = value << dist;
325 results[1] = value >> dist;
326 results[2] = value >>> dist;
327
328 results[3] = (((value << dist) >> dist) >>> dist) << dist;
329 return results;
330 }
331 static long longShiftCheck(long[] results) {
332 System.out.println("IntMath.longShiftCheck");
333
jeffhao795d78f2011-09-30 18:34:35 -0700334 Main.assertTrue(results[0] == 0x96deff00aa010000L);
335 Main.assertTrue(results[1] == 0xffffd5aa96deff00L);
336 Main.assertTrue(results[2] == 0x0000d5aa96deff00L);
337 Main.assertTrue(results[3] == 0xffff96deff000000L);
jeffhao5d1ac922011-09-29 17:41:15 -0700338
jeffhao795d78f2011-09-30 18:34:35 -0700339 Main.assertTrue(results.length == 4);
jeffhao5d1ac922011-09-29 17:41:15 -0700340
341 return results[0]; // test return-long
342 }
343
344
345 /*
346 * Try to cause some unary operations.
347 */
348 static int unopTest(int x) {
349 x = -x;
350 x ^= 0xffffffff;
351 return x;
352 }
353 static void unopCheck(int result) {
jeffhao795d78f2011-09-30 18:34:35 -0700354 Main.assertTrue(result == 37);
jeffhao5d1ac922011-09-29 17:41:15 -0700355 }
356
357 static class Shorty {
358 public short mShort;
359 public char mChar;
360 public byte mByte;
361 };
362
363 /*
364 * Truncate an int.
365 */
366 static Shorty truncateTest(int x) {
367 System.out.println("IntMath.truncateTest");
368 Shorty shorts = new Shorty();
369
370 shorts.mShort = (short) x;
371 shorts.mChar = (char) x;
372 shorts.mByte = (byte) x;
373 return shorts;
374 }
375 static void truncateCheck(Shorty shorts) {
jeffhao795d78f2011-09-30 18:34:35 -0700376 Main.assertTrue(shorts.mShort == -5597); // 0xea23
377 Main.assertTrue(shorts.mChar == 59939); // 0xea23
378 Main.assertTrue(shorts.mByte == 35); // 0x23
jeffhao5d1ac922011-09-29 17:41:15 -0700379 }
380
381 /*
382 * Verify that we get a divide-by-zero exception.
383 */
384 static void divideByZero(int z) {
385 System.out.println("IntMath.divideByZero");
386
387 try {
388 int x = 100 / z;
jeffhao795d78f2011-09-30 18:34:35 -0700389 Main.assertTrue(false);
jeffhao5d1ac922011-09-29 17:41:15 -0700390 } catch (ArithmeticException ae) {
391 }
392
393 try {
394 int x = 100 % z;
jeffhao795d78f2011-09-30 18:34:35 -0700395 Main.assertTrue(false);
jeffhao5d1ac922011-09-29 17:41:15 -0700396 } catch (ArithmeticException ae) {
397 }
398
399 try {
400 long x = 100L / z;
jeffhao795d78f2011-09-30 18:34:35 -0700401 Main.assertTrue(false);
jeffhao5d1ac922011-09-29 17:41:15 -0700402 } catch (ArithmeticException ae) {
403 }
404
405 try {
406 long x = 100L % z;
jeffhao795d78f2011-09-30 18:34:35 -0700407 Main.assertTrue(false);
jeffhao5d1ac922011-09-29 17:41:15 -0700408 } catch (ArithmeticException ae) {
409 }
410 }
411
412 /*
413 * Check an edge condition: dividing the most-negative integer by -1
414 * returns the most-negative integer, and doesn't cause an exception.
415 *
416 * Pass in -1, -1L.
417 */
418 static void bigDivideOverflow(int idiv, long ldiv) {
419 System.out.println("IntMath.bigDivideOverflow");
420 int mostNegInt = (int) 0x80000000;
421 long mostNegLong = (long) 0x8000000000000000L;
422
423 int intDivResult = mostNegInt / idiv;
424 int intModResult = mostNegInt % idiv;
425 long longDivResult = mostNegLong / ldiv;
426 long longModResult = mostNegLong % ldiv;
427
jeffhao795d78f2011-09-30 18:34:35 -0700428 Main.assertTrue(intDivResult == mostNegInt);
429 Main.assertTrue(intModResult == 0);
430 Main.assertTrue(longDivResult == mostNegLong);
431 Main.assertTrue(longModResult == 0);
jeffhao5d1ac922011-09-29 17:41:15 -0700432 }
433
434 /*
435 * Check "const" instructions. We use negative values to ensure that
436 * sign-extension is happening.
437 */
438 static void checkConsts(byte small, short medium, int large, long huge) {
439 System.out.println("IntMath.checkConsts");
440
jeffhao795d78f2011-09-30 18:34:35 -0700441 Main.assertTrue(small == 1); // const/4
442 Main.assertTrue(medium == -256); // const/16
443 Main.assertTrue(medium == -256L); // const-wide/16
444 Main.assertTrue(large == -88888); // const
445 Main.assertTrue(large == -88888L); // const-wide/32
446 Main.assertTrue(huge == 0x9922334455667788L); // const-wide
jeffhao5d1ac922011-09-29 17:41:15 -0700447 }
448
449 /*
450 * Test some java.lang.Math functions.
451 *
452 * The method arguments are positive values.
453 */
454 static void jlmTests(int ii, long ll) {
455 System.out.println("IntMath.jlmTests");
456
jeffhao795d78f2011-09-30 18:34:35 -0700457 Main.assertTrue(Math.abs(ii) == ii);
458 Main.assertTrue(Math.abs(-ii) == ii);
459 Main.assertTrue(Math.min(ii, -5) == -5);
460 Main.assertTrue(Math.max(ii, -5) == ii);
jeffhao5d1ac922011-09-29 17:41:15 -0700461
jeffhao795d78f2011-09-30 18:34:35 -0700462 Main.assertTrue(Math.abs(ll) == ll);
463 Main.assertTrue(Math.abs(-ll) == ll);
464 Main.assertTrue(Math.min(ll, -5L) == -5L);
465 Main.assertTrue(Math.max(ll, -5L) == ll);
jeffhao5d1ac922011-09-29 17:41:15 -0700466 }
467
468 public static void run() {
469 shiftTest1();
470 shiftTest2();
471 unsignedShiftTest();
472 convTest();
473 charSubTest();
474
475 int[] intResults;
476 long[] longResults;
477
478 intResults = intOperTest(70000, -3);
479 intOperCheck(intResults);
480 longResults = longOperTest(70000000000L, -3L);
481 longOperCheck(longResults);
482
483 intResults = lit16Test(77777);
484 lit16Check(intResults);
485 intResults = lit8Test(-55555);
486 lit8Check(intResults);
487
488 intResults = intShiftTest(0xff00aa01, 8);
489 intShiftCheck(intResults);
490 longResults = longShiftTest(0xd5aa96deff00aa01L, 16);
491 long longRet = longShiftCheck(longResults);
jeffhao795d78f2011-09-30 18:34:35 -0700492 Main.assertTrue(longRet == 0x96deff00aa010000L);
jeffhao5d1ac922011-09-29 17:41:15 -0700493
494 Shorty shorts = truncateTest(-16717277); // 0xff00ea23
495 truncateCheck(shorts);
496
497 divideByZero(0);
498 bigDivideOverflow(-1, -1L);
499
500 checkConsts((byte) 1, (short) -256, -88888, 0x9922334455667788L);
501
502 unopCheck(unopTest(38));
503
504 jlmTests(12345, 0x1122334455667788L);
505 }
506}