Merge branch 'master' into bindings/python
[babeltrace.git] / tests / lib / test_bitfield.c
1 /*
2 * test-bitfield.c
3 *
4 * BabelTrace - bitfield test program
5 *
6 * Copyright 2010 - 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 #define _GNU_SOURCE
23 #include <babeltrace/bitfield.h>
24 #include <time.h>
25 #include <stdlib.h>
26 #include <stdio.h>
27
28 #include <tap/tap.h>
29
30 unsigned int glob;
31
32 /*
33 * This function is only declared to show the size of a bitfield write in
34 * objdump.
35 */
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_TEST_DESC_FMT_STR "Writing and reading back 0x%X, signed"
45 #define UNSIGNED_TEST_DESC_FMT_STR "Writing and reading back 0x%X, unsigned"
46 #define DIAG_FMT_STR "Failed reading value written \"%s\"-wise, with start=%i" \
47 " and length=%i. Read %llX"
48
49 unsigned int srcrand;
50
51 #if defined(__i386) || defined(__x86_64)
52
53 static inline int fls(int x)
54 {
55 int r;
56 asm("bsrl %1,%0\n\t"
57 "cmovzl %2,%0"
58 : "=&r" (r) : "rm" (x), "rm" (-1));
59 return r + 1;
60 }
61
62 #elif defined(__PPC__)
63
64 static __inline__ int fls(unsigned int x)
65 {
66 int lz;
67
68 asm ("cntlzw %0,%1" : "=r" (lz) : "r" (x));
69 return 32 - lz;
70 }
71
72 #else
73
74 static int fls(unsigned int x)
75 {
76 int r = 32;
77
78 if (!x)
79 return 0;
80 if (!(x & 0xFFFF0000U)) {
81 x <<= 16;
82 r -= 16;
83 }
84 if (!(x & 0xFF000000U)) {
85 x <<= 8;
86 r -= 8;
87 }
88 if (!(x & 0xF0000000U)) {
89 x <<= 4;
90 r -= 4;
91 }
92 if (!(x & 0xC0000000U)) {
93 x <<= 2;
94 r -= 2;
95 }
96 if (!(x & 0x80000000U)) {
97 x <<= 1;
98 r -= 1;
99 }
100 return r;
101 }
102
103 #endif
104
105 #define print_byte_array(c, len) \
106 do { \
107 unsigned long i; \
108 \
109 for (i = 0; i < (len); i++) { \
110 printf("0x%X", (c)[i]); \
111 if (i != (len) - 1) \
112 printf(" "); \
113 } \
114 printf("\n"); \
115 } while (0)
116
117 #define init_byte_array(c, len, val) \
118 do { \
119 unsigned long i; \
120 \
121 for (i = 0; i < (len); i++) \
122 (c)[i] = (val); \
123 } while (0)
124
125 #define check_result(ref, val, buffer, typename, start, len, \
126 desc_fmt_str) \
127 ({ \
128 if ((val) != (ref)) { \
129 fail(desc_fmt_str, ref); \
130 diag(DIAG_FMT_STR, #typename, start, len, val); \
131 printf("# "); \
132 print_byte_array(buffer, TEST_LEN); \
133 } \
134 (val) != (ref); \
135 })
136
137 void run_test_unsigned(void)
138 {
139 unsigned int src, nrbits;
140 union {
141 unsigned char c[TEST_LEN];
142 unsigned short s[TEST_LEN/sizeof(unsigned short)];
143 unsigned int i[TEST_LEN/sizeof(unsigned int)];
144 unsigned long l[TEST_LEN/sizeof(unsigned long)];
145 unsigned long long ll[TEST_LEN/sizeof(unsigned long long)];
146 } target;
147 unsigned long long readval;
148 unsigned int s, l;
149
150 src = srcrand;
151 nrbits = fls(src);
152
153 for (s = 0; s < CHAR_BIT * TEST_LEN; s++) {
154 for (l = nrbits; l < (CHAR_BIT * TEST_LEN) - s; l++) {
155 init_byte_array(target.c, TEST_LEN, 0xFF);
156 bt_bitfield_write(target.c, unsigned char, s, l, src);
157 bt_bitfield_read(target.c, unsigned char, s, l, &readval);
158 if (check_result(src, readval, target.c, unsigned char,
159 s, l, UNSIGNED_TEST_DESC_FMT_STR)) {
160 return;
161 }
162
163 init_byte_array(target.c, TEST_LEN, 0xFF);
164 bt_bitfield_write(target.s, unsigned short, s, l, src);
165 bt_bitfield_read(target.c, unsigned char, s, l, &readval);
166 if (check_result(src, readval, target.c, unsigned short,
167 s, l, UNSIGNED_TEST_DESC_FMT_STR)) {
168 return;
169 }
170
171 init_byte_array(target.c, TEST_LEN, 0xFF);
172 bt_bitfield_write(target.i, unsigned int, s, l, src);
173 bt_bitfield_read(target.c, unsigned char, s, l, &readval);
174 if (check_result(src, readval, target.c, unsigned int,
175 s, l, UNSIGNED_TEST_DESC_FMT_STR)) {
176 return;
177 }
178
179 init_byte_array(target.c, TEST_LEN, 0xFF);
180 bt_bitfield_write(target.l, unsigned long, s, l, src);
181 bt_bitfield_read(target.c, unsigned char, s, l, &readval);
182 if (check_result(src, readval, target.c, unsigned long,
183 s, l, UNSIGNED_TEST_DESC_FMT_STR)) {
184 return;
185 }
186
187 init_byte_array(target.c, TEST_LEN, 0xFF);
188 bt_bitfield_write(target.ll, unsigned long long, s, l, src);
189 bt_bitfield_read(target.c, unsigned char, s, l, &readval);
190 if (check_result(src, readval, target.c, unsigned long long,
191 s, l, UNSIGNED_TEST_DESC_FMT_STR)) {
192 return;
193 }
194 }
195 }
196
197 pass(UNSIGNED_TEST_DESC_FMT_STR, src);
198 }
199
200 void run_test_signed(void)
201 {
202 int src, nrbits;
203 union {
204 signed char c[TEST_LEN];
205 short s[TEST_LEN/sizeof(short)];
206 int i[TEST_LEN/sizeof(int)];
207 long l[TEST_LEN/sizeof(long)];
208 long long ll[TEST_LEN/sizeof(long long)];
209 } target;
210 long long readval;
211 unsigned int s, l;
212
213 src = srcrand;
214 if (src & 0x80000000U)
215 nrbits = fls(~src) + 1; /* Find least significant bit conveying sign */
216 else
217 nrbits = fls(src) + 1; /* Keep sign at 0 */
218
219 for (s = 0; s < CHAR_BIT * TEST_LEN; s++) {
220 for (l = nrbits; l < (CHAR_BIT * TEST_LEN) - s; l++) {
221 init_byte_array(target.c, TEST_LEN, 0x0);
222 bt_bitfield_write(target.c, signed char, s, l, src);
223 bt_bitfield_read(target.c, signed char, s, l, &readval);
224 if (check_result(src, readval, target.c, signed char,
225 s, l, SIGNED_TEST_DESC_FMT_STR)) {
226 return;
227 }
228
229 init_byte_array(target.c, TEST_LEN, 0x0);
230 bt_bitfield_write(target.s, short, s, l, src);
231 bt_bitfield_read(target.c, signed char, s, l, &readval);
232 if (check_result(src, readval, target.c, short,
233 s, l, SIGNED_TEST_DESC_FMT_STR)) {
234 return;
235 }
236
237 init_byte_array(target.c, TEST_LEN, 0x0);
238 bt_bitfield_write(target.i, int, s, l, src);
239 bt_bitfield_read(target.c, signed char, s, l, &readval);
240 if (check_result(src, readval, target.c, int,
241 s, l, SIGNED_TEST_DESC_FMT_STR)) {
242 return;
243 }
244
245 init_byte_array(target.c, TEST_LEN, 0x0);
246 bt_bitfield_write(target.l, long, s, l, src);
247 bt_bitfield_read(target.c, signed char, s, l, &readval);
248 if (check_result(src, readval, target.c, long,
249 s, l, SIGNED_TEST_DESC_FMT_STR)) {
250 return;
251 }
252
253 init_byte_array(target.c, TEST_LEN, 0x0);
254 bt_bitfield_write(target.ll, long long, s, l, src);
255 bt_bitfield_read(target.c, signed char, s, l, &readval);
256 if (check_result(src, readval, target.c, long long,
257 s, l, SIGNED_TEST_DESC_FMT_STR)) {
258 return;
259 }
260 }
261 }
262
263 pass(SIGNED_TEST_DESC_FMT_STR, src);
264 }
265
266 void run_test(void)
267 {
268 int i;
269 plan_tests(NR_TESTS * 2 + 6);
270
271 srand(time(NULL));
272
273 srcrand = 0;
274 run_test_unsigned();
275 srcrand = 0;
276 run_test_signed();
277
278 srcrand = 1;
279 run_test_unsigned();
280
281 srcrand = ~0U;
282 run_test_unsigned();
283
284 srcrand = -1;
285 run_test_signed();
286
287 srcrand = (int)0x80000000U;
288 run_test_signed();
289
290 for (i = 0; i < NR_TESTS; i++) {
291 srcrand = rand();
292 run_test_unsigned();
293 run_test_signed();
294 }
295 }
296
297 static
298 int print_encodings(unsigned long src, unsigned int shift, unsigned int len)
299 {
300 union {
301 unsigned char c[8];
302 unsigned short s[4];
303 unsigned int i[2];
304 unsigned long l[2];
305 unsigned long long ll[1];
306 } target;
307 unsigned long long readval;
308
309 init_byte_array(target.c, 8, 0xFF);
310 bt_bitfield_write(target.c, unsigned char, shift, len, src);
311 printf("bytewise\n");
312 print_byte_array(target.c, 8);
313
314 init_byte_array(target.c, 8, 0xFF);
315 bt_bitfield_write(target.s, unsigned short, shift, len, src);
316 printf("shortwise\n");
317 print_byte_array(target.c, 8);
318
319 init_byte_array(target.c, 8, 0xFF);
320 bt_bitfield_write(target.i, unsigned int, shift, len, src);
321 printf("intwise\n");
322 print_byte_array(target.c, 8);
323
324 init_byte_array(target.c, 8, 0xFF);
325 bt_bitfield_write(target.l, unsigned long, shift, len, src);
326 printf("longwise\n");
327 print_byte_array(target.c, 8);
328
329 init_byte_array(target.c, 8, 0xFF);
330 bt_bitfield_write(target.ll, unsigned long long, shift, len, src);
331 printf("lluwise\n");
332 print_byte_array(target.c, 8);
333
334 bt_bitfield_read(target.c, unsigned char, shift, len, &readval);
335 printf("read: %llX\n", readval);
336 print_byte_array(target.c, 8);
337
338 return 0;
339 }
340
341 int main(int argc, char **argv)
342 {
343 if (argc > 1) {
344 /* Print encodings */
345 unsigned long src;
346 unsigned int shift, len;
347
348 src = atoi(argv[1]);
349 if (argc > 2)
350 shift = atoi(argv[2]);
351 else
352 shift = 12;
353 if (argc > 3)
354 len = atoi(argv[3]);
355 else
356 len = 40;
357 return print_encodings(src, shift, len);
358 }
359
360 /* Run tap-formated tests */
361 run_test();
362 return exit_status();
363 }
This page took 0.037293 seconds and 5 git commands to generate.