IntMath.java revision 2ad60cfc28e14ee8f0bb038720836a4696c478ad
1// Copyright 2006 The Android Open Source Project
2
3/**
4 * Test arithmetic operations.
5 */
6public 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        assert(results[0] == 69997);
141        assert(results[1] == 70003);
142        assert(results[2] == -210000);
143        assert(results[3] == 605032704);    // overflow / truncate
144        assert(results[4] == -23333);
145        assert(results[5] == 1);
146        assert(results[6] == 70000);
147        assert(results[7] == -3);
148        assert(results[8] == -70003);
149        assert(results[9] == 70000);
150    }
151
152    /*
153     * More operations, this time with 16-bit constants.  (x=77777)
154     */
155    static int[] lit16Test(int x) {
156        System.out.println("IntMath.lit16Test");
157
158        int[] results = new int[8];
159
160        /* try to generate op-int/lit16" instructions */
161        results[0] = x + 1000;
162        results[1] = 1000 - x;
163        results[2] = x * 1000;
164        results[3] = x / 1000;
165        results[4] = x % 1000;
166        results[5] = x & 1000;
167        results[6] = x | -1000;
168        results[7] = x ^ -1000;
169        return results;
170    }
171    static void lit16Check(int[] results) {
172        assert(results[0] == 78777);
173        assert(results[1] == -76777);
174        assert(results[2] == 77777000);
175        assert(results[3] == 77);
176        assert(results[4] == 777);
177        assert(results[5] == 960);
178        assert(results[6] == -39);
179        assert(results[7] == -76855);
180    }
181
182    /*
183     * More operations, this time with 8-bit constants.  (x=-55555)
184     */
185    static int[] lit8Test(int x) {
186        System.out.println("IntMath.lit8Test");
187
188        int[] results = new int[8];
189
190        /* try to generate op-int/lit8" instructions */
191        results[0] = x + 10;
192        results[1] = 10 - x;
193        results[2] = x * 10;
194        results[3] = x / 10;
195        results[4] = x % 10;
196        results[5] = x & 10;
197        results[6] = x | -10;
198        results[7] = x ^ -10;
199        return results;
200    }
201    static void lit8Check(int[] results) {
202        //for (int i = 0; i < results.length; i++)
203        //    System.out.println(" " + i + ": " + results[i]);
204        assert(results[0] == -55545);
205        assert(results[1] == 55565);
206        assert(results[2] == -555550);
207        assert(results[3] == -5555);
208        assert(results[4] == -5);
209        assert(results[5] == 8);
210        assert(results[6] == -1);
211        assert(results[7] == 55563);
212    }
213
214
215    /*
216     * Shift some data.  (value=0xff00aa01, dist=8)
217     */
218    static int[] intShiftTest(int value, int dist) {
219        System.out.println("IntMath.intShiftTest");
220
221        int results[] = new int[4];
222
223        results[0] = value << dist;
224        results[1] = value >> dist;
225        results[2] = value >>> dist;
226
227        results[3] = (((value << dist) >> dist) >>> dist) << dist;
228        return results;
229    }
230    static void intShiftCheck(int[] results) {
231        System.out.println("IntMath.intShiftCheck");
232
233        assert(results[0] == 0x00aa0100);
234        assert(results[1] == 0xffff00aa);
235        assert(results[2] == 0x00ff00aa);
236        assert(results[3] == 0xaa00);
237    }
238
239    /*
240     * We pass in the arguments and return the results so the compiler
241     * doesn't do the math for us.  (x=70000000000, y=-3)
242     */
243    static long[] longOperTest(long x, long y) {
244        System.out.println("IntMath.longOperTest");
245
246        long[] results = new long[10];
247
248        /* this seems to generate "op-long" instructions */
249        results[0] = x + y;
250        results[1] = x - y;
251        results[2] = x * y;
252        results[3] = x * x;
253        results[4] = x / y;
254        results[5] = x % -y;
255        results[6] = x & y;
256        results[7] = x | y;
257        results[8] = x ^ y;
258
259        /* this seems to generate "op-long/2addr" instructions */
260        results[9] = x + ((((((((x + y) - y) * y) / y) % y) & y) | y) ^ y);
261
262        return results;
263    }
264    static void longOperCheck(long[] results) {
265        System.out.println("IntMath.longOperCheck");
266        assert(results[0] == 69999999997L);
267        assert(results[1] == 70000000003L);
268        assert(results[2] == -210000000000L);
269        assert(results[3] == -6833923606740729856L);    // overflow
270        assert(results[4] == -23333333333L);
271        assert(results[5] == 1);
272        assert(results[6] == 70000000000L);
273        assert(results[7] == -3);
274        assert(results[8] == -70000000003L);
275        assert(results[9] == 70000000000L);
276
277        assert(results.length == 10);
278    }
279
280    /*
281     * Shift some data.  (value=0xd5aa96deff00aa01, dist=8)
282     */
283    static long[] longShiftTest(long value, int dist) {
284        System.out.println("IntMath.longShiftTest");
285
286        long results[] = new long[4];
287
288        results[0] = value << dist;
289        results[1] = value >> dist;
290        results[2] = value >>> dist;
291
292        results[3] = (((value << dist) >> dist) >>> dist) << dist;
293        return results;
294    }
295    static long longShiftCheck(long[] results) {
296        System.out.println("IntMath.longShiftCheck");
297
298        assert(results[0] == 0x96deff00aa010000L);
299        assert(results[1] == 0xffffd5aa96deff00L);
300        assert(results[2] == 0x0000d5aa96deff00L);
301        assert(results[3] == 0xffff96deff000000L);
302
303        assert(results.length == 4);
304
305        return results[0];      // test return-long
306    }
307
308
309    /*
310     * Try to cause some unary operations.
311     */
312    static int unopTest(int x) {
313        x = -x;
314        x ^= 0xffffffff;
315        return x;
316    }
317    static void unopCheck(int result) {
318        assert(result == 37);
319    }
320
321    static class Shorty {
322        public short mShort;
323        public char mChar;
324        public byte mByte;
325    };
326
327    /*
328     * Truncate an int.
329     */
330    static Shorty truncateTest(int x) {
331        System.out.println("IntMath.truncateTest");
332        Shorty shorts = new Shorty();
333
334        shorts.mShort = (short) x;
335        shorts.mChar = (char) x;
336        shorts.mByte = (byte) x;
337        return shorts;
338    }
339    static void truncateCheck(Shorty shorts) {
340        assert(shorts.mShort == -5597);     // 0xea23
341        assert(shorts.mChar == 59939);      // 0xea23
342        assert(shorts.mByte == 35);         // 0x23
343    }
344
345    /*
346     * Verify that we get a divide-by-zero exception.
347     */
348    static void divideByZero(int z) {
349        System.out.println("IntMath.divideByZero");
350
351        try {
352            int x = 100 / z;
353            assert(false);
354        } catch (ArithmeticException ae) {
355        }
356
357        try {
358            int x = 100 % z;
359            assert(false);
360        } catch (ArithmeticException ae) {
361        }
362
363        try {
364            long x = 100L / z;
365            assert(false);
366        } catch (ArithmeticException ae) {
367        }
368
369        try {
370            long x = 100L % z;
371            assert(false);
372        } catch (ArithmeticException ae) {
373        }
374    }
375
376    /*
377     * Check "const" instructions.  We use negative values to ensure that
378     * sign-extension is happening.
379     */
380    static void checkConsts(byte small, short medium, int large, long huge) {
381        System.out.println("IntMath.checkConsts");
382
383        assert(small == 1);                     // const/4
384        assert(medium == -256);                 // const/16
385        assert(medium == -256L);                // const-wide/16
386        assert(large == -88888);                // const
387        assert(large == -88888L);               // const-wide/32
388        assert(huge == 0x9922334455667788L);    // const-wide
389    }
390
391    public static void run() {
392        shiftTest1();
393        shiftTest2();
394        unsignedShiftTest();
395        convTest();
396        charSubTest();
397
398        int[] intResults;
399        long[] longResults;
400
401        intResults = intOperTest(70000, -3);
402        intOperCheck(intResults);
403        longResults = longOperTest(70000000000L, -3L);
404        longOperCheck(longResults);
405
406        intResults = lit16Test(77777);
407        lit16Check(intResults);
408        intResults = lit8Test(-55555);
409        lit8Check(intResults);
410
411        intResults = intShiftTest(0xff00aa01, 8);
412        intShiftCheck(intResults);
413        longResults = longShiftTest(0xd5aa96deff00aa01L, 16);
414        long longRet = longShiftCheck(longResults);
415        assert(longRet == 0x96deff00aa010000L);
416
417        Shorty shorts = truncateTest(-16717277);    // 0xff00ea23
418        truncateCheck(shorts);
419
420        divideByZero(0);
421
422        checkConsts((byte) 1, (short) -256, -88888, 0x9922334455667788L);
423
424        unopCheck(unopTest(38));
425    }
426}
427
428