altos: Add 64-bit add/mul/shift for SDCC
[fw/altos] / src / test / ao_int64_test.c
1 /*
2  * Copyright © 2013 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; version 2 of the License.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
16  */
17
18 #include <ao_int64.h>
19 #include <ao_int64.c>
20 #include <stdio.h>
21 #include <stdlib.h>
22
23 int     errors;
24
25 #define test(op,func,a,b,ao_a,ao_b) do {                                \
26                 r = (a) op (b);                                         \
27                 func(&ao_r, ao_a, ao_b);                                \
28                 c = ao_cast64(&ao_r);                                   \
29                 if (c != r) {                                           \
30                         printf ("trial %4d: %lld " #func " %lld = %lld (should be %lld)\n", \
31                                 trial, (int64_t) (a), (int64_t) b, c, r); \
32                         ++errors;                                       \
33                 }                                                       \
34         } while (0)
35
36
37 void
38 do_test(int trial, int64_t a, int64_t b)
39 {
40         int64_t r, c;
41         ao_int64_t      ao_a, ao_b, ao_r;
42
43         ao_int64_init64(&ao_a, a >> 32, a);
44         ao_int64_init64(&ao_b, b >> 32, b);
45
46         test(+, ao_plus64, a, b, &ao_a, &ao_b);
47         test(*, ao_mul64,(int64_t) (int32_t) a, (int32_t) b, (int32_t) a, (int32_t) b);
48         test(>>, ao_rshift64, a, (uint8_t) b & 0x3f, &ao_a, (uint8_t) b & 0x3f);
49         test(<<, ao_lshift64, a, (uint8_t) b & 0x3f, &ao_a, (uint8_t) b & 0x3f);
50         test(*, ao_mul64_16, a, (uint16_t) b, &ao_a, (uint16_t) b);
51 }
52
53 #define TESTS   10000000
54
55 static int64_t
56 random64(void)
57 {
58         return (int64_t) random() + ((int64_t) random() << 31) /* + ((int64_t) random() << 33) */;
59 }
60
61 int
62 main (int argc, char **argv)
63 {
64         int     i, start;
65
66         if (argv[1])
67                 start = atoi(argv[1]);
68         else
69                 start = 0;
70         srandom(1000);
71         for (i = 0; i < TESTS; i++) {
72                 int64_t a = random64();
73                 int64_t b = random64();
74                 if (i >= start)
75                         do_test(i, a, b);
76         }
77         return errors;
78 }