Move to kernel style SPDX license identifiers
[babeltrace.git] / tests / bitfield / test_bitfield.c
CommitLineData
6dc2ca62 1/*
0235b0db 2 * SPDX-License-Identifier: GPL-2.0-only
6dc2ca62 3 *
0235b0db 4 * Copyright (C) 2010-2019 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
6dc2ca62 5 *
0235b0db 6 * BabelTrace - bitfield test program
6dc2ca62
MD
7 */
8
578e048b 9#include "compat/bitfield.h"
47e0f2e2
MD
10#include <time.h>
11#include <stdlib.h>
6dc2ca62
MD
12#include <stdio.h>
13
1833a3d1 14#include <tap/tap.h>
9e8e57d0 15
6dc2ca62
MD
16unsigned int glob;
17
18/*
19 * This function is only declared to show the size of a bitfield write in
7c7301d5 20 * objdump. The declaration is there to avoid a -Wmissing-prototypes warning.
6dc2ca62 21 */
7c7301d5 22void fct(void);
6dc2ca62
MD
23void fct(void)
24{
47e0f2e2 25 bt_bitfield_write(&glob, unsigned int, 12, 15, 0x12345678);
6dc2ca62
MD
26}
27
28/* Test array size, in bytes */
29#define TEST_LEN 128
30#define NR_TESTS 10
0675eb8c
MD
31#define SIGNED_INT_READ_TEST_DESC_FMT_STR "Writing and reading back 0x%X, signed int dest, varying read unit size"
32#define SIGNED_INT_WRITE_TEST_DESC_FMT_STR "Writing and reading back 0x%X, signed int source, varying write unit size"
33#define SIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR "Writing and reading back 0x%llX, signed long long dest, varying read unit size"
34#define SIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR "Writing and reading back 0x%llX, signed long long source, varying write unit size"
35#define UNSIGNED_INT_READ_TEST_DESC_FMT_STR "Writing and reading back 0x%X, unsigned int dest, varying read unit size"
36#define UNSIGNED_INT_WRITE_TEST_DESC_FMT_STR "Writing and reading back 0x%X, unsigned int source, varying write unit size"
37#define UNSIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR "Writing and reading back 0x%llX, unsigned long long dest, varying read unit size"
38#define UNSIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR "Writing and reading back 0x%llX, unsigned long long source, varying write unit size"
092f9aea
SM
39#define DIAG_FMT_STR(val_type_fmt) "Failed reading value written \"%s\"-wise, with start=%i" \
40 " and length=%i. Read 0x" val_type_fmt
6dc2ca62 41
0675eb8c
MD
42static
43unsigned int fls_u64(uint64_t x)
6dc2ca62 44{
0675eb8c 45 unsigned int r = 64;
6dc2ca62 46
0675eb8c
MD
47 if (!x)
48 return 0;
6dc2ca62 49
0675eb8c
MD
50 if (!(x & 0xFFFFFFFF00000000ULL)) {
51 x <<= 32;
52 r -= 32;
53 }
54 if (!(x & 0xFFFF000000000000ULL)) {
55 x <<= 16;
56 r -= 16;
57 }
58 if (!(x & 0xFF00000000000000ULL)) {
59 x <<= 8;
60 r -= 8;
61 }
62 if (!(x & 0xF000000000000000ULL)) {
63 x <<= 4;
64 r -= 4;
65 }
66 if (!(x & 0xC000000000000000ULL)) {
67 x <<= 2;
68 r -= 2;
69 }
70 if (!(x & 0x8000000000000000ULL)) {
71 x <<= 1;
72 r -= 1;
73 }
74 return r;
6dc2ca62
MD
75}
76
0675eb8c
MD
77static
78unsigned int fls_u32(uint32_t x)
6dc2ca62 79{
0675eb8c 80 unsigned int r = 32;
6dc2ca62
MD
81
82 if (!x)
83 return 0;
84 if (!(x & 0xFFFF0000U)) {
85 x <<= 16;
86 r -= 16;
87 }
88 if (!(x & 0xFF000000U)) {
89 x <<= 8;
90 r -= 8;
91 }
92 if (!(x & 0xF0000000U)) {
93 x <<= 4;
94 r -= 4;
95 }
96 if (!(x & 0xC0000000U)) {
97 x <<= 2;
98 r -= 2;
99 }
100 if (!(x & 0x80000000U)) {
101 x <<= 1;
102 r -= 1;
103 }
104 return r;
105}
106
47e0f2e2
MD
107#define print_byte_array(c, len) \
108do { \
109 unsigned long i; \
110 \
111 for (i = 0; i < (len); i++) { \
112 printf("0x%X", (c)[i]); \
113 if (i != (len) - 1) \
114 printf(" "); \
115 } \
116 printf("\n"); \
117} while (0)
118
119#define init_byte_array(c, len, val) \
120do { \
121 unsigned long i; \
122 \
123 for (i = 0; i < (len); i++) \
124 (c)[i] = (val); \
125} while (0)
6dc2ca62 126
092f9aea
SM
127#define check_result(ref, val, buffer, typename, start, len, \
128 desc_fmt_str, val_type_fmt) \
129({ \
130 if ((val) != (ref)) { \
131 fail(desc_fmt_str, ref); \
132 diag(DIAG_FMT_STR(val_type_fmt), #typename, start, len, val); \
133 printf("# "); \
134 print_byte_array(buffer, TEST_LEN); \
135 } \
136 (val) != (ref); \
9e8e57d0
JG
137})
138
7c7301d5 139static
0675eb8c 140void run_test_unsigned_write(unsigned int src_ui, unsigned long long src_ull)
6dc2ca62 141{
0675eb8c 142 unsigned int nrbits_ui, nrbits_ull;
6dc2ca62
MD
143 union {
144 unsigned char c[TEST_LEN];
145 unsigned short s[TEST_LEN/sizeof(unsigned short)];
146 unsigned int i[TEST_LEN/sizeof(unsigned int)];
147 unsigned long l[TEST_LEN/sizeof(unsigned long)];
148 unsigned long long ll[TEST_LEN/sizeof(unsigned long long)];
149 } target;
380d60b1 150 unsigned long long readval;
6dc2ca62 151 unsigned int s, l;
6dc2ca62 152
09650ea1 153 /* The number of bits needed to represent 0 is 0. */
0675eb8c 154 nrbits_ui = fls_u32(src_ui);
6dc2ca62 155
0675eb8c 156 /* Write from unsigned integer src input. */
6dc2ca62 157 for (s = 0; s < CHAR_BIT * TEST_LEN; s++) {
09650ea1 158 for (l = nrbits_ui; l <= (CHAR_BIT * TEST_LEN) - s; l++) {
6dc2ca62 159 init_byte_array(target.c, TEST_LEN, 0xFF);
0675eb8c 160 bt_bitfield_write(target.c, unsigned char, s, l, src_ui);
47e0f2e2 161 bt_bitfield_read(target.c, unsigned char, s, l, &readval);
0675eb8c 162 if (check_result(src_ui, readval, target.c, unsigned char,
092f9aea
SM
163 s, l, UNSIGNED_INT_WRITE_TEST_DESC_FMT_STR,
164 "%llX")) {
9e8e57d0 165 return;
6dc2ca62
MD
166 }
167
168 init_byte_array(target.c, TEST_LEN, 0xFF);
0675eb8c 169 bt_bitfield_write(target.s, unsigned short, s, l, src_ui);
47e0f2e2 170 bt_bitfield_read(target.c, unsigned char, s, l, &readval);
0675eb8c 171 if (check_result(src_ui, readval, target.c, unsigned short,
092f9aea
SM
172 s, l, UNSIGNED_INT_WRITE_TEST_DESC_FMT_STR,
173 "%llX")) {
9e8e57d0 174 return;
6dc2ca62
MD
175 }
176
177 init_byte_array(target.c, TEST_LEN, 0xFF);
0675eb8c 178 bt_bitfield_write(target.i, unsigned int, s, l, src_ui);
47e0f2e2 179 bt_bitfield_read(target.c, unsigned char, s, l, &readval);
0675eb8c 180 if (check_result(src_ui, readval, target.c, unsigned int,
092f9aea
SM
181 s, l, UNSIGNED_INT_WRITE_TEST_DESC_FMT_STR,
182 "%llX")) {
9e8e57d0 183 return;
6dc2ca62
MD
184 }
185
186 init_byte_array(target.c, TEST_LEN, 0xFF);
0675eb8c 187 bt_bitfield_write(target.l, unsigned long, s, l, src_ui);
47e0f2e2 188 bt_bitfield_read(target.c, unsigned char, s, l, &readval);
0675eb8c 189 if (check_result(src_ui, readval, target.c, unsigned long,
092f9aea
SM
190 s, l, UNSIGNED_INT_WRITE_TEST_DESC_FMT_STR,
191 "%llX")) {
9e8e57d0 192 return;
6dc2ca62
MD
193 }
194
195 init_byte_array(target.c, TEST_LEN, 0xFF);
0675eb8c 196 bt_bitfield_write(target.ll, unsigned long long, s, l, src_ui);
47e0f2e2 197 bt_bitfield_read(target.c, unsigned char, s, l, &readval);
0675eb8c 198 if (check_result(src_ui, readval, target.c, unsigned long long,
092f9aea
SM
199 s, l, UNSIGNED_INT_WRITE_TEST_DESC_FMT_STR,
200 "%llX")) {
9e8e57d0 201 return;
6dc2ca62
MD
202 }
203 }
204 }
0675eb8c
MD
205 pass(UNSIGNED_INT_WRITE_TEST_DESC_FMT_STR, src_ui);
206
09650ea1 207 /* The number of bits needed to represent 0 is 0. */
0675eb8c
MD
208 nrbits_ull = fls_u64(src_ull);
209
210 /* Write from unsigned long long src input. */
211 for (s = 0; s < CHAR_BIT * TEST_LEN; s++) {
09650ea1 212 for (l = nrbits_ull; l <= (CHAR_BIT * TEST_LEN) - s; l++) {
0675eb8c
MD
213 init_byte_array(target.c, TEST_LEN, 0xFF);
214 bt_bitfield_write(target.c, unsigned char, s, l, src_ull);
215 bt_bitfield_read(target.c, unsigned char, s, l, &readval);
216 if (check_result(src_ull, readval, target.c, unsigned char,
092f9aea
SM
217 s, l, UNSIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR,
218 "%llX")) {
0675eb8c
MD
219 return;
220 }
9e8e57d0 221
0675eb8c
MD
222 init_byte_array(target.c, TEST_LEN, 0xFF);
223 bt_bitfield_write(target.s, unsigned short, s, l, src_ull);
224 bt_bitfield_read(target.c, unsigned char, s, l, &readval);
225 if (check_result(src_ull, readval, target.c, unsigned short,
092f9aea
SM
226 s, l, UNSIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR,
227 "%llX")) {
0675eb8c
MD
228 return;
229 }
230
231 init_byte_array(target.c, TEST_LEN, 0xFF);
232 bt_bitfield_write(target.i, unsigned int, s, l, src_ull);
233 bt_bitfield_read(target.c, unsigned char, s, l, &readval);
234 if (check_result(src_ull, readval, target.c, unsigned int,
092f9aea
SM
235 s, l, UNSIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR,
236 "%llX")) {
0675eb8c
MD
237 return;
238 }
239
240 init_byte_array(target.c, TEST_LEN, 0xFF);
241 bt_bitfield_write(target.l, unsigned long, s, l, src_ull);
242 bt_bitfield_read(target.c, unsigned char, s, l, &readval);
243 if (check_result(src_ull, readval, target.c, unsigned long,
092f9aea
SM
244 s, l, UNSIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR,
245 "%llX")) {
0675eb8c
MD
246 return;
247 }
248
249 init_byte_array(target.c, TEST_LEN, 0xFF);
250 bt_bitfield_write(target.ll, unsigned long long, s, l, src_ull);
251 bt_bitfield_read(target.c, unsigned char, s, l, &readval);
252 if (check_result(src_ull, readval, target.c, unsigned long long,
092f9aea
SM
253 s, l, UNSIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR,
254 "%llX")) {
0675eb8c
MD
255 return;
256 }
257 }
258 }
259 pass(UNSIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR, src_ull);
6dc2ca62
MD
260}
261
7c7301d5 262static
0675eb8c 263void run_test_unsigned_read(unsigned int src_ui, unsigned long long src_ull)
6dc2ca62 264{
0675eb8c
MD
265 unsigned int nrbits_ui, nrbits_ull, readval_ui;
266 union {
267 unsigned char c[TEST_LEN];
268 unsigned short s[TEST_LEN/sizeof(unsigned short)];
269 unsigned int i[TEST_LEN/sizeof(unsigned int)];
270 unsigned long l[TEST_LEN/sizeof(unsigned long)];
271 unsigned long long ll[TEST_LEN/sizeof(unsigned long long)];
272 } target;
273 unsigned long long readval_ull;
274 unsigned int s, l;
275
09650ea1 276 /* The number of bits needed to represent 0 is 0. */
0675eb8c
MD
277 nrbits_ui = fls_u32(src_ui);
278
279 /* Read to unsigned integer readval output. */
280 for (s = 0; s < CHAR_BIT * TEST_LEN; s++) {
09650ea1 281 for (l = nrbits_ui; l <= (CHAR_BIT * TEST_LEN) - s; l++) {
0675eb8c
MD
282 init_byte_array(target.c, TEST_LEN, 0xFF);
283 bt_bitfield_write(target.c, unsigned char, s, l, src_ui);
284 bt_bitfield_read(target.c, unsigned char, s, l, &readval_ui);
285 if (check_result(src_ui, readval_ui, target.c, unsigned char,
092f9aea
SM
286 s, l, UNSIGNED_INT_READ_TEST_DESC_FMT_STR,
287 "%X")) {
0675eb8c
MD
288 return;
289 }
290
291 init_byte_array(target.c, TEST_LEN, 0xFF);
056d0f40
MD
292 bt_bitfield_write(target.c, unsigned char, s, l, src_ui);
293 bt_bitfield_read(target.s, unsigned short, s, l, &readval_ui);
0675eb8c 294 if (check_result(src_ui, readval_ui, target.c, unsigned short,
092f9aea
SM
295 s, l, UNSIGNED_INT_READ_TEST_DESC_FMT_STR,
296 "%X")) {
0675eb8c
MD
297 return;
298 }
299
300 init_byte_array(target.c, TEST_LEN, 0xFF);
056d0f40
MD
301 bt_bitfield_write(target.c, unsigned char, s, l, src_ui);
302 bt_bitfield_read(target.i, unsigned int, s, l, &readval_ui);
0675eb8c 303 if (check_result(src_ui, readval_ui, target.c, unsigned int,
092f9aea
SM
304 s, l, UNSIGNED_INT_READ_TEST_DESC_FMT_STR,
305 "%X")) {
0675eb8c
MD
306 return;
307 }
308
309 init_byte_array(target.c, TEST_LEN, 0xFF);
056d0f40
MD
310 bt_bitfield_write(target.c, unsigned char, s, l, src_ui);
311 bt_bitfield_read(target.l, unsigned long, s, l, &readval_ui);
0675eb8c 312 if (check_result(src_ui, readval_ui, target.c, unsigned long,
092f9aea
SM
313 s, l, UNSIGNED_INT_READ_TEST_DESC_FMT_STR,
314 "%X")) {
0675eb8c
MD
315 return;
316 }
317
318 init_byte_array(target.c, TEST_LEN, 0xFF);
056d0f40
MD
319 bt_bitfield_write(target.c, unsigned char, s, l, src_ui);
320 bt_bitfield_read(target.ll, unsigned long long, s, l, &readval_ui);
0675eb8c 321 if (check_result(src_ui, readval_ui, target.c, unsigned long long,
092f9aea
SM
322 s, l, UNSIGNED_INT_READ_TEST_DESC_FMT_STR,
323 "%X")) {
0675eb8c
MD
324 return;
325 }
326 }
327 }
328 pass(UNSIGNED_INT_READ_TEST_DESC_FMT_STR, src_ui);
329
09650ea1 330 /* The number of bits needed to represent 0 is 0. */
0675eb8c
MD
331 nrbits_ull = fls_u64(src_ull);
332
333 /* Read to unsigned long long readval output. */
334 for (s = 0; s < CHAR_BIT * TEST_LEN; s++) {
09650ea1 335 for (l = nrbits_ull; l <= (CHAR_BIT * TEST_LEN) - s; l++) {
0675eb8c
MD
336 init_byte_array(target.c, TEST_LEN, 0xFF);
337 bt_bitfield_write(target.c, unsigned char, s, l, src_ull);
338 bt_bitfield_read(target.c, unsigned char, s, l, &readval_ull);
339 if (check_result(src_ull, readval_ull, target.c, unsigned char,
092f9aea
SM
340 s, l, UNSIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR,
341 "%llX")) {
0675eb8c
MD
342 return;
343 }
344
345 init_byte_array(target.c, TEST_LEN, 0xFF);
056d0f40
MD
346 bt_bitfield_write(target.c, unsigned char, s, l, src_ull);
347 bt_bitfield_read(target.s, unsigned short, s, l, &readval_ull);
0675eb8c 348 if (check_result(src_ull, readval_ull, target.c, unsigned short,
092f9aea
SM
349 s, l, UNSIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR,
350 "%llX")) {
0675eb8c
MD
351 return;
352 }
353
354 init_byte_array(target.c, TEST_LEN, 0xFF);
056d0f40
MD
355 bt_bitfield_write(target.c, unsigned char, s, l, src_ull);
356 bt_bitfield_read(target.i, unsigned int, s, l, &readval_ull);
0675eb8c 357 if (check_result(src_ull, readval_ull, target.c, unsigned int,
092f9aea
SM
358 s, l, UNSIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR,
359 "%llX")) {
0675eb8c
MD
360 return;
361 }
362
363 init_byte_array(target.c, TEST_LEN, 0xFF);
056d0f40
MD
364 bt_bitfield_write(target.c, unsigned char, s, l, src_ull);
365 bt_bitfield_read(target.l, unsigned long, s, l, &readval_ull);
0675eb8c 366 if (check_result(src_ull, readval_ull, target.c, unsigned long,
092f9aea
SM
367 s, l, UNSIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR,
368 "%llX")) {
0675eb8c
MD
369 return;
370 }
371
372 init_byte_array(target.c, TEST_LEN, 0xFF);
056d0f40
MD
373 bt_bitfield_write(target.c, unsigned char, s, l, src_ull);
374 bt_bitfield_read(target.ll, unsigned long long, s, l, &readval_ull);
0675eb8c 375 if (check_result(src_ull, readval_ull, target.c, unsigned long long,
092f9aea
SM
376 s, l, UNSIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR,
377 "%llX")) {
0675eb8c
MD
378 return;
379 }
380 }
381 }
382 pass(UNSIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR, src_ull);
383}
384
7c7301d5 385static
0675eb8c
MD
386void run_test_unsigned(unsigned int src_ui, unsigned long long src_ull)
387{
388 run_test_unsigned_write(src_ui, src_ull);
389 run_test_unsigned_read(src_ui, src_ull);
390}
391
7c7301d5 392static
0675eb8c
MD
393void run_test_signed_write(int src_i, long long src_ll)
394{
3622ef51 395 unsigned int nrbits_i, nrbits_ll;
6dc2ca62 396 union {
47e0f2e2 397 signed char c[TEST_LEN];
6dc2ca62
MD
398 short s[TEST_LEN/sizeof(short)];
399 int i[TEST_LEN/sizeof(int)];
400 long l[TEST_LEN/sizeof(long)];
401 long long ll[TEST_LEN/sizeof(long long)];
402 } target;
380d60b1 403 long long readval;
6dc2ca62 404 unsigned int s, l;
6dc2ca62 405
9d9b332b
MD
406 if (!src_i)
407 nrbits_i = 0; /* The number of bits needed to represent 0 is 0. */
408 else if (src_i & 0x80000000U)
0675eb8c 409 nrbits_i = fls_u32(~src_i) + 1; /* Find least significant bit conveying sign */
6dc2ca62 410 else
0675eb8c 411 nrbits_i = fls_u32(src_i) + 1; /* Keep sign at 0 */
6dc2ca62 412
0675eb8c 413 /* Write from signed integer src input. */
9e8e57d0 414 for (s = 0; s < CHAR_BIT * TEST_LEN; s++) {
09650ea1 415 for (l = nrbits_i; l <= (CHAR_BIT * TEST_LEN) - s; l++) {
6dc2ca62 416 init_byte_array(target.c, TEST_LEN, 0x0);
0675eb8c 417 bt_bitfield_write(target.c, signed char, s, l, src_i);
47e0f2e2 418 bt_bitfield_read(target.c, signed char, s, l, &readval);
0675eb8c 419 if (check_result(src_i, readval, target.c, signed char,
092f9aea
SM
420 s, l, SIGNED_INT_WRITE_TEST_DESC_FMT_STR,
421 "%llX")) {
9e8e57d0 422 return;
6dc2ca62
MD
423 }
424
425 init_byte_array(target.c, TEST_LEN, 0x0);
0675eb8c 426 bt_bitfield_write(target.s, short, s, l, src_i);
47e0f2e2 427 bt_bitfield_read(target.c, signed char, s, l, &readval);
0675eb8c 428 if (check_result(src_i, readval, target.c, short,
092f9aea
SM
429 s, l, SIGNED_INT_WRITE_TEST_DESC_FMT_STR,
430 "%llX")) {
9e8e57d0 431 return;
6dc2ca62
MD
432 }
433
434 init_byte_array(target.c, TEST_LEN, 0x0);
0675eb8c 435 bt_bitfield_write(target.i, int, s, l, src_i);
47e0f2e2 436 bt_bitfield_read(target.c, signed char, s, l, &readval);
0675eb8c 437 if (check_result(src_i, readval, target.c, int,
092f9aea
SM
438 s, l, SIGNED_INT_WRITE_TEST_DESC_FMT_STR,
439 "%llX")) {
9e8e57d0 440 return;
6dc2ca62
MD
441 }
442
443 init_byte_array(target.c, TEST_LEN, 0x0);
0675eb8c 444 bt_bitfield_write(target.l, long, s, l, src_i);
47e0f2e2 445 bt_bitfield_read(target.c, signed char, s, l, &readval);
0675eb8c 446 if (check_result(src_i, readval, target.c, long,
092f9aea
SM
447 s, l, SIGNED_INT_WRITE_TEST_DESC_FMT_STR,
448 "%llX")) {
9e8e57d0 449 return;
6dc2ca62
MD
450 }
451
452 init_byte_array(target.c, TEST_LEN, 0x0);
0675eb8c 453 bt_bitfield_write(target.ll, long long, s, l, src_i);
47e0f2e2 454 bt_bitfield_read(target.c, signed char, s, l, &readval);
0675eb8c 455 if (check_result(src_i, readval, target.c, long long,
092f9aea
SM
456 s, l, SIGNED_INT_WRITE_TEST_DESC_FMT_STR,
457 "%llX")) {
9e8e57d0 458 return;
6dc2ca62
MD
459 }
460 }
461 }
0675eb8c
MD
462 pass(SIGNED_INT_WRITE_TEST_DESC_FMT_STR, src_i);
463
9d9b332b
MD
464 if (!src_ll)
465 nrbits_ll = 0; /* The number of bits needed to represent 0 is 0. */
466 else if (src_ll & 0x8000000000000000ULL)
0675eb8c
MD
467 nrbits_ll = fls_u64(~src_ll) + 1; /* Find least significant bit conveying sign */
468 else
469 nrbits_ll = fls_u64(src_ll) + 1; /* Keep sign at 0 */
470
471 /* Write from signed long long src input. */
472 for (s = 0; s < CHAR_BIT * TEST_LEN; s++) {
09650ea1 473 for (l = nrbits_ll; l <= (CHAR_BIT * TEST_LEN) - s; l++) {
0675eb8c
MD
474 init_byte_array(target.c, TEST_LEN, 0x0);
475 bt_bitfield_write(target.c, signed char, s, l, src_ll);
476 bt_bitfield_read(target.c, signed char, s, l, &readval);
477 if (check_result(src_ll, readval, target.c, signed char,
092f9aea
SM
478 s, l, SIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR,
479 "%llX")) {
0675eb8c
MD
480 return;
481 }
482
483 init_byte_array(target.c, TEST_LEN, 0x0);
484 bt_bitfield_write(target.s, short, s, l, src_ll);
485 bt_bitfield_read(target.c, signed char, s, l, &readval);
486 if (check_result(src_ll, readval, target.c, short,
092f9aea
SM
487 s, l, SIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR,
488 "%llX")) {
0675eb8c
MD
489 return;
490 }
491
492 init_byte_array(target.c, TEST_LEN, 0x0);
493 bt_bitfield_write(target.i, int, s, l, src_ll);
494 bt_bitfield_read(target.c, signed char, s, l, &readval);
495 if (check_result(src_ll, readval, target.c, int,
092f9aea
SM
496 s, l, SIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR,
497 "%llX")) {
0675eb8c
MD
498 return;
499 }
9e8e57d0 500
0675eb8c
MD
501 init_byte_array(target.c, TEST_LEN, 0x0);
502 bt_bitfield_write(target.l, long, s, l, src_ll);
503 bt_bitfield_read(target.c, signed char, s, l, &readval);
504 if (check_result(src_ll, readval, target.c, long,
092f9aea
SM
505 s, l, SIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR,
506 "%llX")) {
0675eb8c
MD
507 return;
508 }
509
510 init_byte_array(target.c, TEST_LEN, 0x0);
511 bt_bitfield_write(target.ll, long long, s, l, src_ll);
512 bt_bitfield_read(target.c, signed char, s, l, &readval);
513 if (check_result(src_ll, readval, target.c, long long,
092f9aea
SM
514 s, l, SIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR,
515 "%llX")) {
0675eb8c
MD
516 return;
517 }
518 }
519 }
520 pass(SIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR, src_ll);
6dc2ca62
MD
521}
522
7c7301d5 523static
0675eb8c 524void run_test_signed_read(int src_i, long long src_ll)
6dc2ca62 525{
3622ef51
MD
526 unsigned int nrbits_i, nrbits_ll;
527 int readval_i;
0675eb8c
MD
528 union {
529 unsigned char c[TEST_LEN];
530 unsigned short s[TEST_LEN/sizeof(unsigned short)];
531 unsigned int i[TEST_LEN/sizeof(unsigned int)];
532 unsigned long l[TEST_LEN/sizeof(unsigned long)];
533 unsigned long long ll[TEST_LEN/sizeof(unsigned long long)];
534 } target;
535 long long readval_ll;
536 unsigned int s, l;
6dc2ca62 537
9d9b332b
MD
538 if (!src_i)
539 nrbits_i = 0; /* The number of bits needed to represent 0 is 0. */
540 else if (src_i & 0x80000000U)
0675eb8c
MD
541 nrbits_i = fls_u32(~src_i) + 1; /* Find least significant bit conveying sign */
542 else
543 nrbits_i = fls_u32(src_i) + 1; /* Keep sign at 0 */
6dc2ca62 544
0675eb8c
MD
545 /* Read to signed integer readval output. */
546 for (s = 0; s < CHAR_BIT * TEST_LEN; s++) {
09650ea1 547 for (l = nrbits_i; l <= (CHAR_BIT * TEST_LEN) - s; l++) {
0675eb8c
MD
548 init_byte_array(target.c, TEST_LEN, 0xFF);
549 bt_bitfield_write(target.c, signed char, s, l, src_i);
550 bt_bitfield_read(target.c, signed char, s, l, &readval_i);
551 if (check_result(src_i, readval_i, target.c, signed char,
092f9aea
SM
552 s, l, SIGNED_INT_READ_TEST_DESC_FMT_STR,
553 "%X")) {
0675eb8c
MD
554 return;
555 }
9e8e57d0 556
0675eb8c 557 init_byte_array(target.c, TEST_LEN, 0xFF);
056d0f40
MD
558 bt_bitfield_write(target.c, signed char, s, l, src_i);
559 bt_bitfield_read(target.s, short, s, l, &readval_i);
0675eb8c 560 if (check_result(src_i, readval_i, target.c, short,
092f9aea
SM
561 s, l, SIGNED_INT_READ_TEST_DESC_FMT_STR,
562 "%X")) {
0675eb8c
MD
563 return;
564 }
9e8e57d0 565
0675eb8c 566 init_byte_array(target.c, TEST_LEN, 0xFF);
056d0f40
MD
567 bt_bitfield_write(target.c, signed char, s, l, src_i);
568 bt_bitfield_read(target.i, int, s, l, &readval_i);
0675eb8c 569 if (check_result(src_i, readval_i, target.c, int,
092f9aea
SM
570 s, l, SIGNED_INT_READ_TEST_DESC_FMT_STR,
571 "%X")) {
0675eb8c
MD
572 return;
573 }
9e8e57d0 574
0675eb8c 575 init_byte_array(target.c, TEST_LEN, 0xFF);
056d0f40
MD
576 bt_bitfield_write(target.c, signed char, s, l, src_i);
577 bt_bitfield_read(target.l, long, s, l, &readval_i);
0675eb8c 578 if (check_result(src_i, readval_i, target.c, long,
092f9aea
SM
579 s, l, SIGNED_INT_READ_TEST_DESC_FMT_STR,
580 "%X")) {
0675eb8c
MD
581 return;
582 }
9e8e57d0 583
0675eb8c 584 init_byte_array(target.c, TEST_LEN, 0xFF);
056d0f40
MD
585 bt_bitfield_write(target.c, signed char, s, l, src_i);
586 bt_bitfield_read(target.ll, long long, s, l, &readval_i);
0675eb8c 587 if (check_result(src_i, readval_i, target.c, long long,
092f9aea
SM
588 s, l, SIGNED_INT_READ_TEST_DESC_FMT_STR,
589 "%X")) {
0675eb8c
MD
590 return;
591 }
592 }
593 }
594 pass(SIGNED_INT_READ_TEST_DESC_FMT_STR, src_i);
595
9d9b332b
MD
596 if (!src_ll)
597 nrbits_ll = 0; /* The number of bits needed to represent 0 is 0. */
0675eb8c
MD
598 if (src_ll & 0x8000000000000000ULL)
599 nrbits_ll = fls_u64(~src_ll) + 1; /* Find least significant bit conveying sign */
600 else
601 nrbits_ll = fls_u64(src_ll) + 1; /* Keep sign at 0 */
602
603 /* Read to signed long long readval output. */
604 for (s = 0; s < CHAR_BIT * TEST_LEN; s++) {
09650ea1 605 for (l = nrbits_ll; l <= (CHAR_BIT * TEST_LEN) - s; l++) {
0675eb8c
MD
606 init_byte_array(target.c, TEST_LEN, 0xFF);
607 bt_bitfield_write(target.c, signed char, s, l, src_ll);
608 bt_bitfield_read(target.c, signed char, s, l, &readval_ll);
609 if (check_result(src_ll, readval_ll, target.c, signed char,
092f9aea
SM
610 s, l, SIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR,
611 "%llX")) {
0675eb8c
MD
612 return;
613 }
614
615 init_byte_array(target.c, TEST_LEN, 0xFF);
056d0f40
MD
616 bt_bitfield_write(target.c, signed char, s, l, src_ll);
617 bt_bitfield_read(target.s, short, s, l, &readval_ll);
0675eb8c 618 if (check_result(src_ll, readval_ll, target.c, short,
092f9aea
SM
619 s, l, SIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR,
620 "%llX")) {
0675eb8c
MD
621 return;
622 }
623
624 init_byte_array(target.c, TEST_LEN, 0xFF);
056d0f40
MD
625 bt_bitfield_write(target.c, signed char, s, l, src_ll);
626 bt_bitfield_read(target.i, int, s, l, &readval_ll);
0675eb8c 627 if (check_result(src_ll, readval_ll, target.c, int,
092f9aea
SM
628 s, l, SIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR,
629 "%llX")) {
0675eb8c
MD
630 return;
631 }
632
633 init_byte_array(target.c, TEST_LEN, 0xFF);
056d0f40
MD
634 bt_bitfield_write(target.c, signed char, s, l, src_ll);
635 bt_bitfield_read(target.l, long, s, l, &readval_ll);
0675eb8c 636 if (check_result(src_ll, readval_ll, target.c, long,
092f9aea
SM
637 s, l, SIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR,
638 "%llX")) {
0675eb8c
MD
639 return;
640 }
641
642 init_byte_array(target.c, TEST_LEN, 0xFF);
056d0f40
MD
643 bt_bitfield_write(target.c, signed char, s, l, src_ll);
644 bt_bitfield_read(target.ll, long long, s, l, &readval_ll);
0675eb8c 645 if (check_result(src_ll, readval_ll, target.c, long long,
092f9aea
SM
646 s, l, SIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR,
647 "%llX")) {
0675eb8c
MD
648 return;
649 }
650 }
651 }
652 pass(SIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR, src_ll);
653}
654
7c7301d5 655static
0675eb8c
MD
656void run_test_signed(int src_i, long long src_ll)
657{
658 run_test_signed_write(src_i, src_ll);
659 run_test_signed_read(src_i, src_ll);
660}
661
7c7301d5 662static
0675eb8c
MD
663void run_test(void)
664{
665 int i;
666
667 plan_tests(NR_TESTS * 8 + 24);
668
669 srand(time(NULL));
670
671 run_test_unsigned(0, 0);
672 run_test_signed(0, 0);
673 run_test_unsigned(1, 1);
674 run_test_unsigned(~0U, ~0ULL);
675 run_test_signed(-1U, -1ULL);
676 run_test_signed(0x80000000U, 0x8000000000000000ULL);
6dc2ca62
MD
677
678 for (i = 0; i < NR_TESTS; i++) {
0675eb8c
MD
679 unsigned int src_ui = rand();
680 unsigned long long src_ull = ((unsigned long long) (unsigned int) rand() << 32) |
681 (unsigned long long) (unsigned int) rand();
682
683 run_test_unsigned(src_ui, src_ull);
684 run_test_signed((int) src_ui, (long long) src_ull);
6dc2ca62 685 }
6dc2ca62
MD
686}
687
9e8e57d0
JG
688static
689int print_encodings(unsigned long src, unsigned int shift, unsigned int len)
6dc2ca62 690{
6dc2ca62
MD
691 union {
692 unsigned char c[8];
693 unsigned short s[4];
694 unsigned int i[2];
695 unsigned long l[2];
696 unsigned long long ll[1];
697 } target;
380d60b1 698 unsigned long long readval;
6dc2ca62 699
9e8e57d0 700 init_byte_array(target.c, 8, 0xFF);
47e0f2e2 701 bt_bitfield_write(target.c, unsigned char, shift, len, src);
6dc2ca62
MD
702 printf("bytewise\n");
703 print_byte_array(target.c, 8);
704
9e8e57d0 705 init_byte_array(target.c, 8, 0xFF);
47e0f2e2 706 bt_bitfield_write(target.s, unsigned short, shift, len, src);
6dc2ca62
MD
707 printf("shortwise\n");
708 print_byte_array(target.c, 8);
709
9e8e57d0 710 init_byte_array(target.c, 8, 0xFF);
47e0f2e2 711 bt_bitfield_write(target.i, unsigned int, shift, len, src);
6dc2ca62
MD
712 printf("intwise\n");
713 print_byte_array(target.c, 8);
714
9e8e57d0 715 init_byte_array(target.c, 8, 0xFF);
47e0f2e2 716 bt_bitfield_write(target.l, unsigned long, shift, len, src);
6dc2ca62
MD
717 printf("longwise\n");
718 print_byte_array(target.c, 8);
719
9e8e57d0 720 init_byte_array(target.c, 8, 0xFF);
47e0f2e2 721 bt_bitfield_write(target.ll, unsigned long long, shift, len, src);
6dc2ca62
MD
722 printf("lluwise\n");
723 print_byte_array(target.c, 8);
724
47e0f2e2 725 bt_bitfield_read(target.c, unsigned char, shift, len, &readval);
6dc2ca62 726 printf("read: %llX\n", readval);
9e8e57d0 727 print_byte_array(target.c, 8);
6dc2ca62 728
9e8e57d0
JG
729 return 0;
730}
731
732int main(int argc, char **argv)
733{
734 if (argc > 1) {
735 /* Print encodings */
736 unsigned long src;
737 unsigned int shift, len;
738
739 src = atoi(argv[1]);
740 if (argc > 2)
741 shift = atoi(argv[2]);
742 else
743 shift = 12;
744 if (argc > 3)
745 len = atoi(argv[3]);
746 else
747 len = 40;
748 return print_encodings(src, shift, len);
749 }
6dc2ca62 750
9e8e57d0
JG
751 /* Run tap-formated tests */
752 run_test();
753 return exit_status();
6dc2ca62 754}
This page took 0.108191 seconds and 4 git commands to generate.