]> Git Repo - qemu.git/blob - tests/test-int128.c
tests/qapi-schema: Cover union types with base
[qemu.git] / tests / test-int128.c
1 /*
2  * Test Int128 arithmetic
3  *
4  * This work is licensed under the terms of the GNU LGPL, version 2 or later.
5  * See the COPYING.LIB file in the top-level directory.
6  *
7  */
8
9 #include <glib.h>
10 #include <stdio.h>
11 #include "qemu/int128.h"
12 #include "qemu/osdep.h"
13
14 static uint32_t tests[8] = {
15     0x00000000, 0x00000001, 0x7FFFFFFE, 0x7FFFFFFF,
16     0x80000000, 0x80000001, 0xFFFFFFFE, 0xFFFFFFFF,
17 };
18
19 #define LOW    3ULL
20 #define HIGH   (1ULL << 63)
21 #define MIDDLE (-1ULL & ~LOW & ~HIGH)
22
23 static uint64_t expand16(unsigned x)
24 {
25     return (x & LOW) | ((x & 4) ? MIDDLE : 0) | (x & 0x8000 ? HIGH : 0);
26 }
27
28 static Int128 expand(uint32_t x)
29 {
30     uint64_t l, h;
31     l = expand16(x & 65535);
32     h = expand16(x >> 16);
33     return (Int128) {l, h};
34 };
35
36 static void test_and(void)
37 {
38     int i, j;
39
40     for (i = 0; i < ARRAY_SIZE(tests); ++i) {
41         for (j = 0; j < ARRAY_SIZE(tests); ++j) {
42             Int128 a = expand(tests[i]);
43             Int128 b = expand(tests[j]);
44             Int128 r = expand(tests[i] & tests[j]);
45             Int128 s = int128_and(a, b);
46             g_assert_cmpuint(r.lo, ==, s.lo);
47             g_assert_cmpuint(r.hi, ==, s.hi);
48         }
49     }
50 }
51
52 static void test_add(void)
53 {
54     int i, j;
55
56     for (i = 0; i < ARRAY_SIZE(tests); ++i) {
57         for (j = 0; j < ARRAY_SIZE(tests); ++j) {
58             Int128 a = expand(tests[i]);
59             Int128 b = expand(tests[j]);
60             Int128 r = expand(tests[i] + tests[j]);
61             Int128 s = int128_add(a, b);
62             g_assert_cmpuint(r.lo, ==, s.lo);
63             g_assert_cmpuint(r.hi, ==, s.hi);
64         }
65     }
66 }
67
68 static void test_sub(void)
69 {
70     int i, j;
71
72     for (i = 0; i < ARRAY_SIZE(tests); ++i) {
73         for (j = 0; j < ARRAY_SIZE(tests); ++j) {
74             Int128 a = expand(tests[i]);
75             Int128 b = expand(tests[j]);
76             Int128 r = expand(tests[i] - tests[j]);
77             Int128 s = int128_sub(a, b);
78             g_assert_cmpuint(r.lo, ==, s.lo);
79             g_assert_cmpuint(r.hi, ==, s.hi);
80         }
81     }
82 }
83
84 static void test_neg(void)
85 {
86     int i;
87
88     for (i = 0; i < ARRAY_SIZE(tests); ++i) {
89         Int128 a = expand(tests[i]);
90         Int128 r = expand(-tests[i]);
91         Int128 s = int128_neg(a);
92         g_assert_cmpuint(r.lo, ==, s.lo);
93         g_assert_cmpuint(r.hi, ==, s.hi);
94     }
95 }
96
97 static void test_nz(void)
98 {
99     int i, j;
100
101     for (i = 0; i < ARRAY_SIZE(tests); ++i) {
102         for (j = 0; j < ARRAY_SIZE(tests); ++j) {
103             Int128 a = expand(tests[i]);
104             g_assert_cmpuint(int128_nz(a), ==, tests[i] != 0);
105         }
106     }
107 }
108
109 static void test_le(void)
110 {
111     int i, j;
112
113     for (i = 0; i < ARRAY_SIZE(tests); ++i) {
114         for (j = 0; j < ARRAY_SIZE(tests); ++j) {
115             /* Signed comparison */
116             int32_t a = (int32_t) tests[i];
117             int32_t b = (int32_t) tests[j];
118             g_assert_cmpuint(int128_le(expand(a), expand(b)), ==, a <= b);
119         }
120     }
121 }
122
123 static void test_lt(void)
124 {
125     int i, j;
126
127     for (i = 0; i < ARRAY_SIZE(tests); ++i) {
128         for (j = 0; j < ARRAY_SIZE(tests); ++j) {
129             /* Signed comparison */
130             int32_t a = (int32_t) tests[i];
131             int32_t b = (int32_t) tests[j];
132             g_assert_cmpuint(int128_lt(expand(a), expand(b)), ==, a < b);
133         }
134     }
135 }
136
137 static void test_ge(void)
138 {
139     int i, j;
140
141     for (i = 0; i < ARRAY_SIZE(tests); ++i) {
142         for (j = 0; j < ARRAY_SIZE(tests); ++j) {
143             /* Signed comparison */
144             int32_t a = (int32_t) tests[i];
145             int32_t b = (int32_t) tests[j];
146             g_assert_cmpuint(int128_ge(expand(a), expand(b)), ==, a >= b);
147         }
148     }
149 }
150
151 static void test_gt(void)
152 {
153     int i, j;
154
155     for (i = 0; i < ARRAY_SIZE(tests); ++i) {
156         for (j = 0; j < ARRAY_SIZE(tests); ++j) {
157             /* Signed comparison */
158             int32_t a = (int32_t) tests[i];
159             int32_t b = (int32_t) tests[j];
160             g_assert_cmpuint(int128_gt(expand(a), expand(b)), ==, a > b);
161         }
162     }
163 }
164
165 /* Make sure to test undefined behavior at runtime! */
166
167 static void __attribute__((__noinline__, __noclone__))
168 test_rshift_one(uint32_t x, int n, uint64_t h, uint64_t l)
169 {
170     Int128 a = expand(x);
171     Int128 r = int128_rshift(a, n);
172     g_assert_cmpuint(r.lo, ==, l);
173     g_assert_cmpuint(r.hi, ==, h);
174 }
175
176 static void test_rshift(void)
177 {
178     test_rshift_one(0x00010000U, 64, 0x0000000000000000ULL, 0x0000000000000001ULL);
179     test_rshift_one(0x80010000U, 64, 0xFFFFFFFFFFFFFFFFULL, 0x8000000000000001ULL);
180     test_rshift_one(0x7FFE0000U, 64, 0x0000000000000000ULL, 0x7FFFFFFFFFFFFFFEULL);
181     test_rshift_one(0xFFFE0000U, 64, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFEULL);
182     test_rshift_one(0x00010000U, 60, 0x0000000000000000ULL, 0x0000000000000010ULL);
183     test_rshift_one(0x80010000U, 60, 0xFFFFFFFFFFFFFFF8ULL, 0x0000000000000010ULL);
184     test_rshift_one(0x00018000U, 60, 0x0000000000000000ULL, 0x0000000000000018ULL);
185     test_rshift_one(0x80018000U, 60, 0xFFFFFFFFFFFFFFF8ULL, 0x0000000000000018ULL);
186     test_rshift_one(0x7FFE0000U, 60, 0x0000000000000007ULL, 0xFFFFFFFFFFFFFFE0ULL);
187     test_rshift_one(0xFFFE0000U, 60, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFE0ULL);
188     test_rshift_one(0x7FFE8000U, 60, 0x0000000000000007ULL, 0xFFFFFFFFFFFFFFE8ULL);
189     test_rshift_one(0xFFFE8000U, 60, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFE8ULL);
190     test_rshift_one(0x00018000U,  0, 0x0000000000000001ULL, 0x8000000000000000ULL);
191     test_rshift_one(0x80018000U,  0, 0x8000000000000001ULL, 0x8000000000000000ULL);
192     test_rshift_one(0x7FFE0000U,  0, 0x7FFFFFFFFFFFFFFEULL, 0x0000000000000000ULL);
193     test_rshift_one(0xFFFE0000U,  0, 0xFFFFFFFFFFFFFFFEULL, 0x0000000000000000ULL);
194     test_rshift_one(0x7FFE8000U,  0, 0x7FFFFFFFFFFFFFFEULL, 0x8000000000000000ULL);
195     test_rshift_one(0xFFFE8000U,  0, 0xFFFFFFFFFFFFFFFEULL, 0x8000000000000000ULL);
196 }
197
198 int main(int argc, char **argv)
199 {
200     g_test_init(&argc, &argv, NULL);
201     g_test_add_func("/int128/int128_and", test_and);
202     g_test_add_func("/int128/int128_add", test_add);
203     g_test_add_func("/int128/int128_sub", test_sub);
204     g_test_add_func("/int128/int128_neg", test_neg);
205     g_test_add_func("/int128/int128_nz", test_nz);
206     g_test_add_func("/int128/int128_le", test_le);
207     g_test_add_func("/int128/int128_lt", test_lt);
208     g_test_add_func("/int128/int128_ge", test_ge);
209     g_test_add_func("/int128/int128_gt", test_gt);
210     g_test_add_func("/int128/int128_rshift", test_rshift);
211     return g_test_run();
212 }
This page took 0.035711 seconds and 4 git commands to generate.