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