2
* Test Int128 arithmetic
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.
11
#include "qemu/int128.h"
12
#include "qemu/osdep.h"
14
static uint32_t tests[8] = {
15
0x00000000, 0x00000001, 0x7FFFFFFE, 0x7FFFFFFF,
16
0x80000000, 0x80000001, 0xFFFFFFFE, 0xFFFFFFFF,
20
#define HIGH (1ULL << 63)
21
#define MIDDLE (-1ULL & ~LOW & ~HIGH)
23
static uint64_t expand16(unsigned x)
25
return (x & LOW) | ((x & 4) ? MIDDLE : 0) | (x & 0x8000 ? HIGH : 0);
28
static Int128 expand(uint32_t x)
31
l = expand16(x & 65535);
32
h = expand16(x >> 16);
33
return (Int128) {l, h};
36
static void test_and(void)
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);
52
static void test_add(void)
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);
68
static void test_sub(void)
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);
84
static void test_neg(void)
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);
97
static void test_nz(void)
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);
109
static void test_le(void)
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);
123
static void test_lt(void)
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);
137
static void test_ge(void)
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);
151
static void test_gt(void)
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);
165
/* Make sure to test undefined behavior at runtime! */
167
static void __attribute__((__noinline__, __noclone__))
168
test_rshift_one(uint32_t x, int n, uint64_t h, uint64_t l)
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);
176
static void test_rshift(void)
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);
198
int main(int argc, char **argv)
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);