Portable bitfields: protect against variable name clashes in macros
[babeltrace.git] / tests / test-bitfield.c
CommitLineData
6dc2ca62
MD
1/*
2 * test-bitfield.c
3 *
d79865b9 4 * BabelTrace - bitfield test program
6dc2ca62 5 *
de0ba614 6 * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
6dc2ca62
MD
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; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22
23#define _GNU_SOURCE
d79865b9 24#include <babeltrace/bitfield.h>
47e0f2e2
MD
25#include <time.h>
26#include <stdlib.h>
6dc2ca62
MD
27#include <stdio.h>
28
29unsigned int glob;
30
31/*
32 * This function is only declared to show the size of a bitfield write in
33 * objdump.
34 */
35void fct(void)
36{
47e0f2e2 37 bt_bitfield_write(&glob, unsigned int, 12, 15, 0x12345678);
6dc2ca62
MD
38}
39
40/* Test array size, in bytes */
41#define TEST_LEN 128
42#define NR_TESTS 10
43
44unsigned int srcrand;
45
46#if defined(__i386) || defined(__x86_64)
47
48static inline int fls(int x)
49{
50 int r;
51 asm("bsrl %1,%0\n\t"
52 "cmovzl %2,%0"
53 : "=&r" (r) : "rm" (x), "rm" (-1));
54 return r + 1;
55}
56
57#elif defined(__PPC__)
58
59static __inline__ int fls(unsigned int x)
60{
61 int lz;
62
63 asm ("cntlzw %0,%1" : "=r" (lz) : "r" (x));
64 return 32 - lz;
65}
66
67#else
68
69static int fls(unsigned int x)
70{
71 int r = 32;
72
73 if (!x)
74 return 0;
75 if (!(x & 0xFFFF0000U)) {
76 x <<= 16;
77 r -= 16;
78 }
79 if (!(x & 0xFF000000U)) {
80 x <<= 8;
81 r -= 8;
82 }
83 if (!(x & 0xF0000000U)) {
84 x <<= 4;
85 r -= 4;
86 }
87 if (!(x & 0xC0000000U)) {
88 x <<= 2;
89 r -= 2;
90 }
91 if (!(x & 0x80000000U)) {
92 x <<= 1;
93 r -= 1;
94 }
95 return r;
96}
97
98#endif
99
47e0f2e2
MD
100#define print_byte_array(c, len) \
101do { \
102 unsigned long i; \
103 \
104 for (i = 0; i < (len); i++) { \
105 printf("0x%X", (c)[i]); \
106 if (i != (len) - 1) \
107 printf(" "); \
108 } \
109 printf("\n"); \
110} while (0)
111
112#define init_byte_array(c, len, val) \
113do { \
114 unsigned long i; \
115 \
116 for (i = 0; i < (len); i++) \
117 (c)[i] = (val); \
118} while (0)
6dc2ca62
MD
119
120int run_test_unsigned(void)
121{
47e0f2e2 122 unsigned long src, nrbits;
6dc2ca62
MD
123 union {
124 unsigned char c[TEST_LEN];
125 unsigned short s[TEST_LEN/sizeof(unsigned short)];
126 unsigned int i[TEST_LEN/sizeof(unsigned int)];
127 unsigned long l[TEST_LEN/sizeof(unsigned long)];
128 unsigned long long ll[TEST_LEN/sizeof(unsigned long long)];
129 } target;
380d60b1 130 unsigned long long readval;
6dc2ca62
MD
131 unsigned int s, l;
132 int err = 0;
133
134 printf("Running unsigned test with 0x%X\n", srcrand);
135
136 src = srcrand;
137 nrbits = fls(src);
138
139 for (s = 0; s < CHAR_BIT * TEST_LEN; s++) {
140 for (l = nrbits; l < (CHAR_BIT * TEST_LEN) - s; l++) {
141 init_byte_array(target.c, TEST_LEN, 0xFF);
47e0f2e2
MD
142 bt_bitfield_write(target.c, unsigned char, s, l, src);
143 bt_bitfield_read(target.c, unsigned char, s, l, &readval);
6dc2ca62
MD
144 if (readval != src) {
145 printf("Error (bytewise) src %lX read %llX shift %d len %d\n",
146 src, readval, s, l);
147 print_byte_array(target.c, TEST_LEN);
148 err = 1;
149 }
150
151 init_byte_array(target.c, TEST_LEN, 0xFF);
47e0f2e2
MD
152 bt_bitfield_write(target.s, unsigned short, s, l, src);
153 bt_bitfield_read(target.c, unsigned char, s, l, &readval);
6dc2ca62
MD
154 if (readval != src) {
155 printf("Error (shortwise) src %lX read %llX shift %d len %d\n",
156 src, readval, s, l);
157 print_byte_array(target.c, TEST_LEN);
158 err = 1;
159 }
160
161 init_byte_array(target.c, TEST_LEN, 0xFF);
47e0f2e2
MD
162 bt_bitfield_write(target.i, unsigned int, s, l, src);
163 bt_bitfield_read(target.c, unsigned char, s, l, &readval);
6dc2ca62
MD
164 if (readval != src) {
165 printf("Error (intwise) src %lX read %llX shift %d len %d\n",
166 src, readval, s, l);
167 print_byte_array(target.c, TEST_LEN);
168 err = 1;
169 }
170
171 init_byte_array(target.c, TEST_LEN, 0xFF);
47e0f2e2
MD
172 bt_bitfield_write(target.l, unsigned long, s, l, src);
173 bt_bitfield_read(target.c, unsigned char, s, l, &readval);
6dc2ca62
MD
174 if (readval != src) {
175 printf("Error (longwise) src %lX read %llX shift %d len %d\n",
176 src, readval, s, l);
177 print_byte_array(target.c, TEST_LEN);
178 err = 1;
179 }
180
181 init_byte_array(target.c, TEST_LEN, 0xFF);
47e0f2e2
MD
182 bt_bitfield_write(target.ll, unsigned long long, s, l, src);
183 bt_bitfield_read(target.c, unsigned char, s, l, &readval);
6dc2ca62
MD
184 if (readval != src) {
185 printf("Error (longlongwise) src %lX read %llX shift %d len %d\n",
186 src, readval, s, l);
187 print_byte_array(target.c, TEST_LEN);
188 err = 1;
189 }
190 }
191 }
192 if (!err)
193 printf("Success!\n");
194 else
195 printf("Failed!\n");
196 return err;
197}
198
199int run_test_signed(void)
200{
47e0f2e2 201 long src, nrbits;
6dc2ca62 202 union {
47e0f2e2 203 signed char c[TEST_LEN];
6dc2ca62
MD
204 short s[TEST_LEN/sizeof(short)];
205 int i[TEST_LEN/sizeof(int)];
206 long l[TEST_LEN/sizeof(long)];
207 long long ll[TEST_LEN/sizeof(long long)];
208 } target;
380d60b1 209 long long readval;
6dc2ca62
MD
210 unsigned int s, l;
211 int err = 0;
212
213 printf("Running signed test with 0x%X\n", srcrand);
214
215 src = srcrand;
216 if (src & 0x80000000U)
217 nrbits = fls(~src) + 1; /* Find least significant bit conveying sign */
218 else
219 nrbits = fls(src) + 1; /* Keep sign at 0 */
220
221 for (s = 0; s < 8 * TEST_LEN; s++) {
222 for (l = nrbits; l < (8 * TEST_LEN) - s; l++) {
223 init_byte_array(target.c, TEST_LEN, 0x0);
47e0f2e2
MD
224 bt_bitfield_write(target.c, signed char, s, l, src);
225 bt_bitfield_read(target.c, signed char, s, l, &readval);
6dc2ca62
MD
226 if (readval != src) {
227 printf("Error (bytewise) src %lX read %llX shift %d len %d\n",
228 src, readval, s, l);
229 print_byte_array(target.c, TEST_LEN);
230 err = 1;
231 }
232
233 init_byte_array(target.c, TEST_LEN, 0x0);
47e0f2e2
MD
234 bt_bitfield_write(target.s, short, s, l, src);
235 bt_bitfield_read(target.c, signed char, s, l, &readval);
6dc2ca62
MD
236 if (readval != src) {
237 printf("Error (shortwise) src %lX read %llX shift %d len %d\n",
238 src, readval, s, l);
239 print_byte_array(target.c, TEST_LEN);
240 err = 1;
241 }
242
243 init_byte_array(target.c, TEST_LEN, 0x0);
47e0f2e2
MD
244 bt_bitfield_write(target.i, int, s, l, src);
245 bt_bitfield_read(target.c, signed char, s, l, &readval);
6dc2ca62
MD
246 if (readval != src) {
247 printf("Error (intwise) src %lX read %llX shift %d len %d\n",
248 src, readval, s, l);
249 print_byte_array(target.c, TEST_LEN);
250 err = 1;
251 }
252
253 init_byte_array(target.c, TEST_LEN, 0x0);
47e0f2e2
MD
254 bt_bitfield_write(target.l, long, s, l, src);
255 bt_bitfield_read(target.c, signed char, s, l, &readval);
6dc2ca62
MD
256 if (readval != src) {
257 printf("Error (longwise) src %lX read %llX shift %d len %d\n",
258 src, readval, s, l);
259 print_byte_array(target.c, TEST_LEN);
260 err = 1;
261 }
262
263 init_byte_array(target.c, TEST_LEN, 0x0);
47e0f2e2
MD
264 bt_bitfield_write(target.ll, long long, s, l, src);
265 bt_bitfield_read(target.c, signed char, s, l, &readval);
6dc2ca62
MD
266 if (readval != src) {
267 printf("Error (longlongwise) src %lX read %llX shift %d len %d\n",
268 src, readval, s, l);
269 print_byte_array(target.c, TEST_LEN);
270 err = 1;
271 }
272 }
273 }
274 if (!err)
275 printf("Success!\n");
276 else
277 printf("Failed!\n");
278 return err;
279}
280
281int run_test(void)
282{
283 int err = 0;
284 int i;
285
286 srand(time(NULL));
287
288 srcrand = 0;
289 err |= run_test_unsigned();
290 srcrand = 0;
291 err |= run_test_signed();
292 srcrand = 1;
293 err |= run_test_unsigned();
294 srcrand = ~0U;
295 err |= run_test_unsigned();
296 srcrand = -1;
297 err |= run_test_signed();
298 srcrand = (int)0x80000000U;
299 err |= run_test_signed();
300
301 for (i = 0; i < NR_TESTS; i++) {
302 srcrand = rand();
303 err |= run_test_unsigned();
304 err |= run_test_signed();
305 }
306 return err;
307}
308
309int main(int argc, char **argv)
310{
311 unsigned long src;
312 unsigned int shift, len;
313 int ret;
314 union {
315 unsigned char c[8];
316 unsigned short s[4];
317 unsigned int i[2];
318 unsigned long l[2];
319 unsigned long long ll[1];
320 } target;
380d60b1 321 unsigned long long readval;
6dc2ca62
MD
322
323 if (argc > 1)
324 src = atoi(argv[1]);
325 else
326 src = 0x12345678;
327 if (argc > 2)
328 shift = atoi(argv[2]);
329 else
330 shift = 12;
331 if (argc > 3)
332 len = atoi(argv[3]);
333 else
334 len = 40;
335
336 target.i[0] = 0xFFFFFFFF;
337 target.i[1] = 0xFFFFFFFF;
47e0f2e2 338 bt_bitfield_write(target.c, unsigned char, shift, len, src);
6dc2ca62
MD
339 printf("bytewise\n");
340 print_byte_array(target.c, 8);
341
342 target.i[0] = 0xFFFFFFFF;
343 target.i[1] = 0xFFFFFFFF;
47e0f2e2 344 bt_bitfield_write(target.s, unsigned short, shift, len, src);
6dc2ca62
MD
345 printf("shortwise\n");
346 print_byte_array(target.c, 8);
347
348 target.i[0] = 0xFFFFFFFF;
349 target.i[1] = 0xFFFFFFFF;
47e0f2e2 350 bt_bitfield_write(target.i, unsigned int, shift, len, src);
6dc2ca62
MD
351 printf("intwise\n");
352 print_byte_array(target.c, 8);
353
354 target.i[0] = 0xFFFFFFFF;
355 target.i[1] = 0xFFFFFFFF;
47e0f2e2 356 bt_bitfield_write(target.l, unsigned long, shift, len, src);
6dc2ca62
MD
357 printf("longwise\n");
358 print_byte_array(target.c, 8);
359
360 target.i[0] = 0xFFFFFFFF;
361 target.i[1] = 0xFFFFFFFF;
47e0f2e2 362 bt_bitfield_write(target.ll, unsigned long long, shift, len, src);
6dc2ca62
MD
363 printf("lluwise\n");
364 print_byte_array(target.c, 8);
365
47e0f2e2 366 bt_bitfield_read(target.c, unsigned char, shift, len, &readval);
6dc2ca62
MD
367 printf("read: %llX\n", readval);
368
369 ret = run_test();
370
371 return ret;
372}
This page took 0.056933 seconds and 4 git commands to generate.