3 /* Test that jit_extr(), jit_extr_u() and jit_depr() work correctly with
5 * Note that to be compatible with C bitfields, behavior is different
6 * for big endian and little endian. For big endian, the bitfield
7 * offset is changed to (__WORDSIZE - offset).
8 * The logic is to create a C function that receives a pointer to
9 * a single word union (that has a bitfield and a word) and a jit function
10 * pointer that knows about the bitfield. The C function calls the jit
11 * function passing the pointer to the bitfield, and the jit function
12 * changes the bitfield with a computed known value specific for the test.
13 * After calling the jit function, the C function validates that the
14 * bitfield has the expected value, and also validates no bits outside of
15 * the bitfield were modified.
16 * The test is done for signed and unsigned bitfields.
17 * The test does a brute force validation that all possible bitfields
18 * using a machine word work as expected.
19 * Tests for possible register clobber is done in check/ext.tst.
20 * The test is dynamically generated because the generated source file
21 * is too large to be kept under version control.
25 main(int argc, char *argv[])
30 #include <lightning.h>\n\
32 # if __WORDSIZE == 64 && _WIN32\n\
37 /* Avoid clang running out of memory on OpenBSD mips64 */\n\
38 #define SKIP_64_BITS (__mips__ && __clang__)\n\
40 #define GENMASK1() GENMASK(1)\n\
41 #define GENMASK2() GENMASK(2)\n\
42 #define GENMASK3() GENMASK(3)\n\
43 #define GENMASK4() GENMASK(4)\n\
44 #define GENMASK5() GENMASK(5)\n\
45 #define GENMASK6() GENMASK(6)\n\
46 #define GENMASK7() GENMASK(7)\n\
47 #define GENMASK8() GENMASK(8)\n\
48 #define GENMASK9() GENMASK(9)\n\
49 #define GENMASK10() GENMASK(10)\n\
50 #define GENMASK11() GENMASK(11)\n\
51 #define GENMASK12() GENMASK(12)\n\
52 #define GENMASK13() GENMASK(13)\n\
53 #define GENMASK14() GENMASK(14)\n\
54 #define GENMASK15() GENMASK(15)\n\
55 #define GENMASK16() GENMASK(16)\n\
56 #define GENMASK17() GENMASK(17)\n\
57 #define GENMASK18() GENMASK(18)\n\
58 #define GENMASK19() GENMASK(19)\n\
59 #define GENMASK20() GENMASK(20)\n\
60 #define GENMASK21() GENMASK(21)\n\
61 #define GENMASK22() GENMASK(22)\n\
62 #define GENMASK23() GENMASK(23)\n\
63 #define GENMASK24() GENMASK(24)\n\
64 #define GENMASK25() GENMASK(25)\n\
65 #define GENMASK26() GENMASK(26)\n\
66 #define GENMASK27() GENMASK(27)\n\
67 #define GENMASK28() GENMASK(28)\n\
68 #define GENMASK29() GENMASK(29)\n\
69 #define GENMASK30() GENMASK(30)\n\
70 #define GENMASK31() GENMASK(31)\n\
71 #if __WORDSIZE == 32\n\
72 # define MININT 0x80000000L\n\
73 # define GENMASK32() \\\n\
79 # define GENMASK32() GENMASK(32)\n\
80 # define GENMASK33() GENMASK(33)\n\
81 # define GENMASK34() GENMASK(34)\n\
82 # define GENMASK35() GENMASK(35)\n\
83 # define GENMASK36() GENMASK(36)\n\
84 # define GENMASK37() GENMASK(37)\n\
85 # define GENMASK38() GENMASK(38)\n\
86 # define GENMASK39() GENMASK(39)\n\
87 # define GENMASK40() GENMASK(40)\n\
88 # define GENMASK41() GENMASK(41)\n\
89 # define GENMASK42() GENMASK(42)\n\
90 # define GENMASK43() GENMASK(43)\n\
91 # define GENMASK44() GENMASK(44)\n\
92 # define GENMASK45() GENMASK(45)\n\
93 # define GENMASK46() GENMASK(46)\n\
94 # define GENMASK47() GENMASK(47)\n\
95 # define GENMASK48() GENMASK(48)\n\
96 # define GENMASK49() GENMASK(49)\n\
97 # define GENMASK50() GENMASK(50)\n\
98 # define GENMASK51() GENMASK(51)\n\
99 # define GENMASK52() GENMASK(52)\n\
100 # define GENMASK53() GENMASK(53)\n\
101 # define GENMASK54() GENMASK(54)\n\
102 # define GENMASK55() GENMASK(55)\n\
103 # define GENMASK56() GENMASK(56)\n\
104 # define GENMASK57() GENMASK(57)\n\
105 # define GENMASK58() GENMASK(58)\n\
106 # define GENMASK59() GENMASK(59)\n\
107 # define GENMASK60() GENMASK(60)\n\
108 # define GENMASK61() GENMASK(61)\n\
109 # define GENMASK62() GENMASK(62)\n\
110 # define GENMASK63() GENMASK(63)\n\
112 # define MININT 0x8000000000000000LL\n\
114 # define MININT 0x8000000000000000L\n\
116 # define GENMASK64() \\\n\
122 #if __BYTE_ORDER == __LITTLE_ENDIAN\n\
123 # define GENMASK(L) \\\n\
125 m = (ONE << L) - 1; \\\n\
128 # define SHIFTMASK(B) m = ~(m << (B))\n\
130 # define GENMASK(L) \\\n\
132 m = (ONE << L) - 1; \\\n\
134 m = ((jit_word_t)MININT >> (L - 1)); \\\n\
136 # define SHIFTMASK(B) m = ~(m >> ((B) - 1))\n\
139 #define S jit_word_t\n\
140 #define U jit_uword_t\n\
142 #define deftypeSL(L) \\\n\
143 typedef union { \\\n\
150 CS##L(S##L *u, S (*JS##L)(S##L*)) { \\\n\
154 t = ((t << (__WORDSIZE - L)) >> (__WORDSIZE - L)); \\\n\
156 j = (*JS##L)(u); \\\n\
157 if (u->b.f != t || t != j || (u->s & m)) \\\n\
161 #define deftypeSBL(B, L) \\\n\
162 typedef union { \\\n\
170 CS##B##_##L(S##B##_##L *u, S (*JS##B##_##L)(S##B##_##L*)) { \\\n\
174 t = ((t << (__WORDSIZE - L)) >> (__WORDSIZE - L)); \\\n\
176 j = (*JS##B##_##L)(u); \\\n\
177 if (u->b.f != t || t != j || (u->s & m)) \\\n\
181 #define deftypeUL(L) \\\n\
182 typedef union { \\\n\
189 CU##L(U##L *u, U (*JU##L)(U##L*)) { \\\n\
193 t = ((t << (__WORDSIZE - L)) >> (__WORDSIZE - L)); \\\n\
195 j = (*JU##L)(u); \\\n\
196 if (u->b.f != t || t != j || (u->u & m)) \\\n\
200 #define deftypeUBL(B, L) \\\n\
201 typedef union { \\\n\
209 CU##B##_##L(U##B##_##L *u, U (*JU##B##_##L)(U##B##_##L*)) { \\\n\
213 t = ((t << (__WORDSIZE - L)) >> (__WORDSIZE - L)); \\\n\
215 j = (*JU##B##_##L)(u); \\\n\
216 if (u->b.f != t || t != j || (u->u & m)) \\\n\
219 puts("\n/* Define signed bitfields at offset 0 */");
220 for (i = 1; i <= 32; i++)
221 printf("deftypeSL(%d)\n", i);
222 /* Avoid clang running out of memory on OpenBSD mips64 */
223 puts("#if __WORDSIZE == 64 && !SKIP_64_BITS");
225 printf("deftypeSL(%d)\n", i);
227 puts("/* Define unsigned bitfields at offset 0 */");
228 for (i = 1; i <= 32; i++)
229 printf("deftypeUL(%d)\n", i);
230 puts("#if __WORDSIZE == 64 && !SKIP_64_BITS");
232 printf("deftypeUL(%d)\n", i);
234 for (i = 1; i <= 31; i++) {
235 printf("/* Define signed bitfields at offset %d */\n", i);
236 for (j = 1; j <= 32 - i; j++)
237 printf("deftypeSBL(%d, %d)\n", i, j);
239 puts("#if __WORDSIZE == 64 && !SKIP_64_BITS");
240 for (i = 1; i < 64; i++) {
241 printf("/* Define signed bitfields at offset %d */\n", i);
242 for (j = 1; j <= 64 - i; j++) {
244 printf("deftypeSBL(%d, %d)\n", i, j);
248 for (i = 1; i <= 31; i++) {
249 printf("/* Define unsigned bitfields at offset %d */\n", i);
250 for (j = 1; j <= 32 - i; j++)
251 printf("deftypeUBL(%d, %d)\n", i, j);
253 puts("#if __WORDSIZE == 64 && !SKIP_64_BITS");
254 for (i = 1; i < 64; i++) {
255 printf("/* Define unsigned bitfields at offset %d */\n", i);
256 for (j = 1; j <= 64 - i; j++) {
258 printf("deftypeUBL(%d, %d)\n", i, j);
265 main(int argc, char *argv[])\n\
268 jit_node_t *jmpi_main;\n\
269 jit_state_t *_jit;\n\
270 void (*code)(void);");
271 puts(" /* Declare signed bitfields at offset 0 */");
272 for (i = 1; i <= 32; i++) {
273 printf(" S%d pS%d;\n", i, i);
274 printf(" jit_node_t *nS%d;\n", i);
276 puts("#if __WORDSIZE == 64 && !SKIP_64_BITS");
277 for (; i <= 64; i++) {
278 printf(" S%d pS%d;\n", i, i);
279 printf(" jit_node_t *nS%d;\n", i);
282 puts(" /* Declare unsigned bitfields at offset 0 */");
283 for (i = 1; i <= 32; i++) {
284 printf(" U%d pU%d;\n", i, i);
285 printf(" jit_node_t *nU%d;\n", i);
287 puts("#if __WORDSIZE == 64 && !SKIP_64_BITS");
288 for (; i <= 64; i++) {
289 printf(" U%d pU%d;\n", i, i);
290 printf(" jit_node_t *nU%d;\n", i);
294 for (i = 1; i <= 31; i++) {
295 printf(" /* Declare signed bitfields at offset %d */\n", i);
296 for (j = 1; j <= 32 - i; j++) {
297 printf(" S%d_%d pS%d_%d;\n", i, j, i, j);
298 printf(" jit_node_t\t *nS%d_%d;\n", i, j);
301 puts("#if __WORDSIZE == 64 && !SKIP_64_BITS");
302 for (i = 1; i < 64; i++) {
303 printf(" /* Declare signed bitfields at offset %d */\n", i);
304 for (j = 1; j <= 64 - i; j++) {
306 printf(" S%d_%d pS%d_%d;\n", i, j, i, j);
307 printf(" jit_node_t\t *nS%d_%d;\n", i, j);
312 for (i = 1; i <= 31; i++) {
313 printf(" /* Declare unsigned bitfields at offset %d */\n", i);
314 for (j = 1; j <= 32 - i; j++) {
315 printf(" U%d_%d pU%d_%d;\n", i, j, i, j);
316 printf(" jit_node_t\t *nU%d_%d;\n", i, j);
319 puts("#if __WORDSIZE == 64 && !SKIP_64_BITS");
320 for (i = 1; i < 64; i++) {
321 printf(" /* Declare unsigned bitfields at offset %d */\n", i);
322 for (j = 1; j <= 64 - i; j++) {
324 printf(" U%d_%d pU%d_%d;\n", i, j, i, j);
325 printf(" jit_node_t\t *nU%d_%d;\n", i, j);
332 init_jit(argv[0]);\n\
333 _jit = jit_new_state();\n\
335 jmpi_main = jit_jmpi();\n");
337 puts(" /* Define jit functions for signed bitfields at offset 0 */");
338 for (i = 1; i <= 32; i++) {
340 nS%d = jit_label();\n\
343 jit_getarg(JIT_R0, arg);\n\
344 jit_ldr(JIT_R2, JIT_R0);\n", i);
345 if ((i >> 3) < sizeof(void*))
346 printf("jit_movi(JIT_R1, ((ONE << %d) - 1) ^ 1);\n", i);
348 printf("jit_movi(JIT_R1, 0);\n");
350 jit_depr(JIT_R2, JIT_R1, 0, %d);\n\
351 jit_extr(JIT_R1, JIT_R2, 0, %d);\n\
352 jit_str(JIT_R0, JIT_R2);\n\
354 jit_epilog();\n", i, i);
356 puts("#if __WORDSIZE == 64 && !SKIP_64_BITS");
357 for (; i <= 64; i++) {
359 nS%d = jit_label();\n\
362 jit_getarg(JIT_R0, arg);\n\
363 jit_ldr(JIT_R2, JIT_R0);\n", i);
364 if ((i >> 3) < sizeof(void*))
365 printf("jit_movi(JIT_R1, ((ONE << %d) - 1) ^ 1);\n", i);
367 printf("jit_movi(JIT_R1, 0);\n");
369 jit_depr(JIT_R2, JIT_R1, 0, %d);\n\
370 jit_extr(JIT_R1, JIT_R2, 0, %d);\n\
371 jit_str(JIT_R0, JIT_R2);\n\
373 jit_epilog();\n", i, i);
377 puts(" /* Define jit functions for unsigned bitfields at offset 0 */");
378 for (i = 1; i <= 32; i++) {
380 nU%d = jit_label();\n\
383 jit_getarg(JIT_R0, arg);\n\
384 jit_ldr(JIT_R2, JIT_R0);\n", i);
385 if ((i >> 3) < sizeof(void*))
386 printf("jit_movi(JIT_R1, ((ONE << %d) - 1) ^ 1);\n", i);
388 printf("jit_movi(JIT_R1, 0);\n");
390 jit_depr(JIT_R2, JIT_R1, 0, %d);\n\
391 jit_extr_u(JIT_R1, JIT_R2, 0, %d);\n\
392 jit_str(JIT_R0, JIT_R2);\n\
394 jit_epilog();\n", i, i);
396 puts("#if __WORDSIZE == 64 && !SKIP_64_BITS");
397 for (; i <= 64; i++) {
399 nU%d = jit_label();\n\
402 jit_getarg(JIT_R0, arg);\n\
403 jit_ldr(JIT_R2, JIT_R0);\n", i);
404 if ((i >> 3) < sizeof(void*))
405 printf("jit_movi(JIT_R1, ((ONE << %d) - 1) ^ 1);\n", i);
407 printf("jit_movi(JIT_R1, 0);\n");
409 jit_depr(JIT_R2, JIT_R1, 0, %d);\n\
410 jit_extr_u(JIT_R1, JIT_R2, 0, %d);\n\
411 jit_str(JIT_R0, JIT_R2);\n\
413 jit_epilog();\n", i, i);
417 for (i = 1; i <= 31; i++) {
418 printf(" /* Define jit functions for signed bitfields at offset %d */\n", i);
419 for (j = 1; j <= 32 - i; j++) {
421 nS%d_%d = jit_label();\n\
424 jit_getarg(JIT_R0, arg);\n\
425 jit_ldr(JIT_R2, JIT_R0);\n\
426 jit_movi(JIT_R1, ((ONE << %d) - 1) ^ 1);\n\
427 jit_depr(JIT_R2, JIT_R1, %d, %d);\n\
428 jit_extr(JIT_R1, JIT_R2, %d, %d);\n\
429 jit_str(JIT_R0, JIT_R2);\n\
431 jit_epilog();\n", i, j, j, i, j, i, j);
434 puts("#if __WORDSIZE == 64 && !SKIP_64_BITS");
435 for (i = 1; i < 64; i++) {
436 printf(" /* Declare jit functions for signed bitfields at offset %d */\n", i);
437 for (j = 1; j <= 64 - i; j++) {
440 nS%d_%d = jit_label();\n\
443 jit_getarg(JIT_R0, arg);\n\
444 jit_ldr(JIT_R2, JIT_R0);\n\
445 jit_movi(JIT_R1, ((ONE << %d) - 1) ^ 1);\n\
446 jit_depr(JIT_R2, JIT_R1, %d, %d);\n\
447 jit_extr(JIT_R1, JIT_R2, %d, %d);\n\
448 jit_str(JIT_R0, JIT_R2);\n\
450 jit_epilog();\n", i, j, j, i, j, i, j);
455 for (i = 1; i <= 31; i++) {
456 printf(" /* Define jit functions for unsigned bitfields at offset %d */\n", i);
457 for (j = 1; j <= 32 - i; j++) {
459 nU%d_%d = jit_label();\n\
462 jit_getarg(JIT_R0, arg);\n\
463 jit_ldr(JIT_R2, JIT_R0);\n\
464 jit_movi(JIT_R1, ((ONE << %d) - 1) ^ 1);\n\
465 jit_depr(JIT_R2, JIT_R1, %d, %d);\n\
466 jit_extr_u(JIT_R1, JIT_R2, %d, %d);\n\
467 jit_str(JIT_R0, JIT_R2);\n\
469 jit_epilog();\n", i, j, j, i, j, i, j);
472 puts("#if __WORDSIZE == 64 && !SKIP_64_BITS");
473 for (i = 1; i < 64; i++) {
474 printf(" /* Declare jit functions for unsigned bitfields at offset %d */\n", i);
475 for (j = 1; j <= 64 - i; j++) {
478 nU%d_%d = jit_label();\n\
481 jit_getarg(JIT_R0, arg);\n\
482 jit_ldr(JIT_R2, JIT_R0);\n\
483 jit_movi(JIT_R1, ((ONE << %d) - 1) ^ 1);\n\
484 jit_depr(JIT_R2, JIT_R1, %d, %d);\n\
485 jit_extr_u(JIT_R1, JIT_R2, %d, %d);\n\
486 jit_str(JIT_R0, JIT_R2);\n\
488 jit_epilog();\n", i, j, j, i, j, i, j);
494 jit_patch(jmpi_main);\n\
495 jit_name(\"main\");\n\
496 jit_note(\"cbit.c\", __LINE__);\n\
499 puts(" /* Call C functions for signed bitfields at offset 0 */");
500 for (i = 1; i <= 32; i++)
502 jit_patch_at(jit_movi(JIT_R0, 0), nS%d);\n\
504 jit_pushargi((jit_word_t)&pS%d);\n\
505 jit_pushargr(JIT_R0);\n\
506 jit_finishi((jit_word_t*)CS%d);\n", i, i, i);
507 puts("#if __WORDSIZE == 64 && !SKIP_64_BITS");
510 jit_patch_at(jit_movi(JIT_R0, 0), nS%d);\n\
512 jit_pushargi((jit_word_t)&pS%d);\n\
513 jit_pushargr(JIT_R0);\n\
514 jit_finishi((jit_word_t*)CS%d);\n", i, i, i);
516 puts(" /* Call C functions for unsigned bitfields at offset 0 */");
517 for (i = 1; i <= 32; i++)
519 jit_patch_at(jit_movi(JIT_R0, 0), nU%d);\n\
521 jit_pushargi((jit_word_t)&pU%d);\n\
522 jit_pushargr(JIT_R0);\n\
523 jit_finishi((jit_word_t*)CU%d);\n", i, i, i);
524 puts("#if __WORDSIZE == 64 && !SKIP_64_BITS");
527 jit_patch_at(jit_movi(JIT_R0, 0), nU%d);\n\
529 jit_pushargi((jit_word_t)&pU%d);\n\
530 jit_pushargr(JIT_R0);\n\
531 jit_finishi((jit_word_t*)CU%d);\n", i, i, i);
534 for (i = 1; i <= 31; i++) {
535 printf(" /* Call C functions for signed bitfields at offset %d */\n", i);
536 for (j = 1; j <= 32 - i; j++) {
538 jit_patch_at(jit_movi(JIT_R0, 0), nS%d_%d);\n\
540 jit_pushargi((jit_word_t)&pS%d_%d);\n\
541 jit_pushargr(JIT_R0);\n\
542 jit_finishi((jit_word_t*)CS%d_%d);\n", i, j, i, j, i, j);
545 puts("#if __WORDSIZE == 64 && !SKIP_64_BITS");
546 for (i = 1; i < 64; i++) {
547 printf(" /* Call C functions for signed bitfields at offset %d */\n", i);
548 for (j = 1; j <= 64 - i; j++) {
551 jit_patch_at(jit_movi(JIT_R0, 0), nS%d_%d);\n\
553 jit_pushargi((jit_word_t)&pS%d_%d);\n\
554 jit_pushargr(JIT_R0);\n\
555 jit_finishi((jit_word_t*)CS%d_%d);\n", i, j, i, j, i, j);
560 for (i = 1; i <= 31; i++) {
561 printf(" /* Call C functions for unsigned bitfields at offset %d */\n", i);
562 for (j = 1; j <= 32 - i; j++) {
564 jit_patch_at(jit_movi(JIT_R0, 0), nU%d_%d);\n\
566 jit_pushargi((jit_word_t)&pU%d_%d);\n\
567 jit_pushargr(JIT_R0);\n\
568 jit_finishi((jit_word_t*)CU%d_%d);\n", i, j, i, j, i, j);
571 puts("#if __WORDSIZE == 64 && !SKIP_64_BITS");
572 for (i = 1; i < 64; i++) {
573 printf(" /* Call C functions for unsigned bitfields at offset %d */\n", i);
574 for (j = 1; j <= 64 - i; j++) {
577 jit_patch_at(jit_movi(JIT_R0, 0), nU%d_%d);\n\
579 jit_pushargi((jit_word_t)&pU%d_%d);\n\
580 jit_pushargr(JIT_R0);\n\
581 jit_finishi((jit_word_t*)CU%d_%d);\n", i, j, i, j, i, j);
590 code = jit_emit();\n\
592 jit_clear_state();\n\
595 jit_destroy_state();\n\