4c88b1a13047b69e309c443ac0e24511d0cc4275
[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_o(op,func,mod,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 mod " %lld = %lld (should be %lld)\n", \
31                                 trial, (int64_t) (a), (int64_t) b, c, r); \
32                         ++errors;                                       \
33                 }                                                       \
34         } while (0)
35
36 #define test(op,func,a,b,ao_a,ao_b) test_o(op,func,"",a,b,ao_a,ao_b)
37
38 #define test_a(op,func,a,b,ao_a,ao_b) do {      \
39                 ao_r = *ao_a;                   \
40                 test_o(op,func,"_a",a,b,&ao_r,ao_b);    \
41         } while (0)
42
43 #define test_b(op,func,a,b,ao_a,ao_b) do {      \
44                 ao_r = *ao_b;                   \
45                 test_o(op,func,"_b",a,b,ao_a,&ao_r);    \
46         } while (0)
47
48 #define test_x(op,func,a,b,ao_a,ao_b) do {      \
49                 ao_r = *ao_a;                   \
50                 test_o(op,func,"_xa",a,a,&ao_r,&ao_r);  \
51                 ao_r = *ao_b;                   \
52                 test_o(op,func,"_xb",b,b,&ao_r,&ao_r);  \
53         } while (0)
54
55 void
56 do_test(int trial, int64_t a, int64_t b)
57 {
58         int64_t r, c;
59         ao_int64_t      ao_a, ao_b, ao_r;
60
61         ao_int64_init64(&ao_a, a >> 32, a);
62         ao_int64_init64(&ao_b, b >> 32, b);
63
64         test(+, ao_plus64, a, b, &ao_a, &ao_b);
65         test_a(+, ao_plus64, a, b, &ao_a, &ao_b);
66         test_b(+, ao_plus64, a, b, &ao_a, &ao_b);
67         test_x(+, ao_plus64, a, b, &ao_a, &ao_b);
68         test(*, ao_mul64_32_32,(int64_t) (int32_t) a, (int32_t) b, (int32_t) a, (int32_t) b);
69         test(*, ao_mul64, a, b, &ao_a, &ao_b);
70         test_a(*, ao_mul64, a, b, &ao_a, &ao_b);
71         test_b(*, ao_mul64, a, b, &ao_a, &ao_b);
72         test_x(*, ao_mul64, a, b, &ao_a, &ao_b);
73         test(*, ao_mul64_64_16, a, (uint16_t) b, &ao_a, (uint16_t) b);
74         test_a(*, ao_mul64_64_16, a, (uint16_t) b, &ao_a, (uint16_t) b);
75         test(>>, ao_rshift64, a, (uint8_t) b & 0x3f, &ao_a, (uint8_t) b & 0x3f);
76         test_a(>>, ao_rshift64, a, (uint8_t) b & 0x3f, &ao_a, (uint8_t) b & 0x3f);
77         test(<<, ao_lshift64, a, (uint8_t) b & 0x3f, &ao_a, (uint8_t) b & 0x3f);
78         test_a(<<, ao_lshift64, a, (uint8_t) b & 0x3f, &ao_a, (uint8_t) b & 0x3f);
79 }
80
81 #define TESTS   10000000
82
83 static int64_t
84 random64(void)
85 {
86         return (int64_t) random() + ((int64_t) random() << 31) /* + ((int64_t) random() << 33) */;
87 }
88
89 int
90 main (int argc, char **argv)
91 {
92         int     i, start;
93
94         if (argv[1])
95                 start = atoi(argv[1]);
96         else
97                 start = 0;
98         srandom(1000);
99         for (i = 0; i < TESTS; i++) {
100                 int64_t a = random64();
101                 int64_t b = random64();
102                 if (i >= start)
103                         do_test(i, a, b);
104         }
105         return errors;
106 }