| 1 | #include <stdio.h> |
| 2 | |
| 3 | /* Test that jit_extr(), jit_extr_u() and jit_depr() work correctly with |
| 4 | * C bitfields. |
| 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. |
| 22 | */ |
| 23 | |
| 24 | int |
| 25 | main(int argc, char *argv[]) |
| 26 | { |
| 27 | int i, j; |
| 28 | puts("\ |
| 29 | #include <stdio.h>\n\ |
| 30 | #include <lightning.h>\n\ |
| 31 | \n\ |
| 32 | # if __WORDSIZE == 64 && _WIN32\n\ |
| 33 | # define ONE 1LL\n\ |
| 34 | # else\n\ |
| 35 | # define ONE 1L\n\ |
| 36 | # endif\n\ |
| 37 | /* Avoid clang running out of memory on OpenBSD mips64 */\n\ |
| 38 | #define SKIP_64_BITS (__mips__ && __clang__)\n\ |
| 39 | \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\ |
| 74 | do { \\\n\ |
| 75 | m = -1; \\\n\ |
| 76 | t = 0; \\\n\ |
| 77 | } while (0)\n\ |
| 78 | #else\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\ |
| 111 | # if _WIN32\n\ |
| 112 | # define MININT 0x8000000000000000LL\n\ |
| 113 | # else\n\ |
| 114 | # define MININT 0x8000000000000000L\n\ |
| 115 | # endif\n\ |
| 116 | # define GENMASK64() \\\n\ |
| 117 | do { \\\n\ |
| 118 | m = -1; \\\n\ |
| 119 | t = 0; \\\n\ |
| 120 | } while (0)\n\ |
| 121 | #endif\n\ |
| 122 | #if __BYTE_ORDER == __LITTLE_ENDIAN\n\ |
| 123 | # define GENMASK(L) \\\n\ |
| 124 | do { \\\n\ |
| 125 | m = (ONE << L) - 1; \\\n\ |
| 126 | t = m ^ 1; \\\n\ |
| 127 | } while (0)\n\ |
| 128 | # define SHIFTMASK(B) m = ~(m << (B))\n\ |
| 129 | #else\n\ |
| 130 | # define GENMASK(L) \\\n\ |
| 131 | do { \\\n\ |
| 132 | m = (ONE << L) - 1; \\\n\ |
| 133 | t = m ^ 1; \\\n\ |
| 134 | m = ((jit_word_t)MININT >> (L - 1)); \\\n\ |
| 135 | } while (0)\n\ |
| 136 | # define SHIFTMASK(B) m = ~(m >> ((B) - 1))\n\ |
| 137 | #endif\n\ |
| 138 | \n\ |
| 139 | #define S jit_word_t\n\ |
| 140 | #define U jit_uword_t\n\ |
| 141 | \n\ |
| 142 | #define deftypeSL(L) \\\n\ |
| 143 | typedef union { \\\n\ |
| 144 | struct { \\\n\ |
| 145 | S f: L; \\\n\ |
| 146 | } b; \\\n\ |
| 147 | S s; \\\n\ |
| 148 | } S##L; \\\n\ |
| 149 | static void \\\n\ |
| 150 | CS##L(S##L *u, S (*JS##L)(S##L*)) { \\\n\ |
| 151 | S t, j, m; \\\n\ |
| 152 | GENMASK##L(); \\\n\ |
| 153 | m = ~m; \\\n\ |
| 154 | t = ((t << (__WORDSIZE - L)) >> (__WORDSIZE - L)); \\\n\ |
| 155 | u->s = 0; \\\n\ |
| 156 | j = (*JS##L)(u); \\\n\ |
| 157 | if (u->b.f != t || t != j || (u->s & m)) \\\n\ |
| 158 | abort(); \\\n\ |
| 159 | }\n\ |
| 160 | \n\ |
| 161 | #define deftypeSBL(B, L) \\\n\ |
| 162 | typedef union { \\\n\ |
| 163 | struct { \\\n\ |
| 164 | S _: B; \\\n\ |
| 165 | S f: L; \\\n\ |
| 166 | } b; \\\n\ |
| 167 | S s; \\\n\ |
| 168 | } S##B##_##L; \\\n\ |
| 169 | static void \\\n\ |
| 170 | CS##B##_##L(S##B##_##L *u, S (*JS##B##_##L)(S##B##_##L*)) { \\\n\ |
| 171 | S t, j, m; \\\n\ |
| 172 | GENMASK##L(); \\\n\ |
| 173 | SHIFTMASK(B); \\\n\ |
| 174 | t = ((t << (__WORDSIZE - L)) >> (__WORDSIZE - L)); \\\n\ |
| 175 | u->s = 0; \\\n\ |
| 176 | j = (*JS##B##_##L)(u); \\\n\ |
| 177 | if (u->b.f != t || t != j || (u->s & m)) \\\n\ |
| 178 | abort(); \\\n\ |
| 179 | }\n\ |
| 180 | \n\ |
| 181 | #define deftypeUL(L) \\\n\ |
| 182 | typedef union { \\\n\ |
| 183 | struct { \\\n\ |
| 184 | U f: L; \\\n\ |
| 185 | } b; \\\n\ |
| 186 | U u; \\\n\ |
| 187 | } U##L; \\\n\ |
| 188 | static void \\\n\ |
| 189 | CU##L(U##L *u, U (*JU##L)(U##L*)) { \\\n\ |
| 190 | U t, j, m; \\\n\ |
| 191 | GENMASK##L(); \\\n\ |
| 192 | m = ~m; \\\n\ |
| 193 | t = ((t << (__WORDSIZE - L)) >> (__WORDSIZE - L)); \\\n\ |
| 194 | u->u = 0; \\\n\ |
| 195 | j = (*JU##L)(u); \\\n\ |
| 196 | if (u->b.f != t || t != j || (u->u & m)) \\\n\ |
| 197 | abort(); \\\n\ |
| 198 | }\n\ |
| 199 | \n\ |
| 200 | #define deftypeUBL(B, L) \\\n\ |
| 201 | typedef union { \\\n\ |
| 202 | struct { \\\n\ |
| 203 | U _: B; \\\n\ |
| 204 | U f: L; \\\n\ |
| 205 | } b; \\\n\ |
| 206 | U u; \\\n\ |
| 207 | } U##B##_##L; \\\n\ |
| 208 | static void \\\n\ |
| 209 | CU##B##_##L(U##B##_##L *u, U (*JU##B##_##L)(U##B##_##L*)) { \\\n\ |
| 210 | U t, j, m; \\\n\ |
| 211 | GENMASK##L(); \\\n\ |
| 212 | SHIFTMASK(B); \\\n\ |
| 213 | t = ((t << (__WORDSIZE - L)) >> (__WORDSIZE - L)); \\\n\ |
| 214 | u->u = 0; \\\n\ |
| 215 | j = (*JU##B##_##L)(u); \\\n\ |
| 216 | if (u->b.f != t || t != j || (u->u & m)) \\\n\ |
| 217 | abort(); \\\n\ |
| 218 | }"); |
| 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"); |
| 224 | for (; i <= 64; i++) |
| 225 | printf("deftypeSL(%d)\n", i); |
| 226 | puts("#endif"); |
| 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"); |
| 231 | for (; i <= 64; i++) |
| 232 | printf("deftypeUL(%d)\n", i); |
| 233 | puts("#endif"); |
| 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); |
| 238 | } |
| 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++) { |
| 243 | if (i + j > 32) |
| 244 | printf("deftypeSBL(%d, %d)\n", i, j); |
| 245 | } |
| 246 | } |
| 247 | puts("#endif"); |
| 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); |
| 252 | } |
| 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++) { |
| 257 | if (i + j > 32) |
| 258 | printf("deftypeUBL(%d, %d)\n", i, j); |
| 259 | } |
| 260 | } |
| 261 | puts("#endif"); |
| 262 | |
| 263 | puts("\n\ |
| 264 | int\n\ |
| 265 | main(int argc, char *argv[])\n\ |
| 266 | {\n\ |
| 267 | jit_node_t *arg;\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); |
| 275 | } |
| 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); |
| 280 | } |
| 281 | puts("#endif"); |
| 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); |
| 286 | } |
| 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); |
| 291 | } |
| 292 | puts("#endif"); |
| 293 | |
| 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); |
| 299 | } |
| 300 | } |
| 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++) { |
| 305 | if (i + j > 32) { |
| 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); |
| 308 | } |
| 309 | } |
| 310 | } |
| 311 | puts("#endif"); |
| 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); |
| 317 | } |
| 318 | } |
| 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++) { |
| 323 | if (i + j > 32) { |
| 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); |
| 326 | } |
| 327 | } |
| 328 | } |
| 329 | puts("#endif\n"); |
| 330 | |
| 331 | puts("\ |
| 332 | init_jit(argv[0]);\n\ |
| 333 | _jit = jit_new_state();\n\ |
| 334 | \n\ |
| 335 | jmpi_main = jit_jmpi();\n"); |
| 336 | |
| 337 | puts(" /* Define jit functions for signed bitfields at offset 0 */"); |
| 338 | for (i = 1; i <= 32; i++) { |
| 339 | printf("\ |
| 340 | nS%d = jit_label();\n\ |
| 341 | jit_prolog();\n\ |
| 342 | arg = jit_arg();\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); |
| 347 | else |
| 348 | printf("jit_movi(JIT_R1, 0);\n"); |
| 349 | printf("\ |
| 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\ |
| 353 | jit_retr(JIT_R1);\n\ |
| 354 | jit_epilog();\n", i, i); |
| 355 | } |
| 356 | puts("#if __WORDSIZE == 64 && !SKIP_64_BITS"); |
| 357 | for (; i <= 64; i++) { |
| 358 | printf("\ |
| 359 | nS%d = jit_label();\n\ |
| 360 | jit_prolog();\n\ |
| 361 | arg = jit_arg();\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); |
| 366 | else |
| 367 | printf("jit_movi(JIT_R1, 0);\n"); |
| 368 | printf("\ |
| 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\ |
| 372 | jit_retr(JIT_R1);\n\ |
| 373 | jit_epilog();\n", i, i); |
| 374 | } |
| 375 | puts("#endif"); |
| 376 | |
| 377 | puts(" /* Define jit functions for unsigned bitfields at offset 0 */"); |
| 378 | for (i = 1; i <= 32; i++) { |
| 379 | printf("\ |
| 380 | nU%d = jit_label();\n\ |
| 381 | jit_prolog();\n\ |
| 382 | arg = jit_arg();\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); |
| 387 | else |
| 388 | printf("jit_movi(JIT_R1, 0);\n"); |
| 389 | printf("\ |
| 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\ |
| 393 | jit_retr(JIT_R1);\n\ |
| 394 | jit_epilog();\n", i, i); |
| 395 | } |
| 396 | puts("#if __WORDSIZE == 64 && !SKIP_64_BITS"); |
| 397 | for (; i <= 64; i++) { |
| 398 | printf("\ |
| 399 | nU%d = jit_label();\n\ |
| 400 | jit_prolog();\n\ |
| 401 | arg = jit_arg();\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); |
| 406 | else |
| 407 | printf("jit_movi(JIT_R1, 0);\n"); |
| 408 | printf("\ |
| 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\ |
| 412 | jit_retr(JIT_R1);\n\ |
| 413 | jit_epilog();\n", i, i); |
| 414 | } |
| 415 | puts("#endif"); |
| 416 | |
| 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++) { |
| 420 | printf("\ |
| 421 | nS%d_%d = jit_label();\n\ |
| 422 | jit_prolog();\n\ |
| 423 | arg = jit_arg();\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\ |
| 430 | jit_retr(JIT_R1);\n\ |
| 431 | jit_epilog();\n", i, j, j, i, j, i, j); |
| 432 | } |
| 433 | } |
| 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++) { |
| 438 | if (i + j > 32) |
| 439 | printf("\ |
| 440 | nS%d_%d = jit_label();\n\ |
| 441 | jit_prolog();\n\ |
| 442 | arg = jit_arg();\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\ |
| 449 | jit_retr(JIT_R1);\n\ |
| 450 | jit_epilog();\n", i, j, j, i, j, i, j); |
| 451 | } |
| 452 | } |
| 453 | puts("#endif"); |
| 454 | |
| 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++) { |
| 458 | printf("\ |
| 459 | nU%d_%d = jit_label();\n\ |
| 460 | jit_prolog();\n\ |
| 461 | arg = jit_arg();\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\ |
| 468 | jit_retr(JIT_R1);\n\ |
| 469 | jit_epilog();\n", i, j, j, i, j, i, j); |
| 470 | } |
| 471 | } |
| 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++) { |
| 476 | if (i + j > 32) |
| 477 | printf("\ |
| 478 | nU%d_%d = jit_label();\n\ |
| 479 | jit_prolog();\n\ |
| 480 | arg = jit_arg();\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\ |
| 487 | jit_retr(JIT_R1);\n\ |
| 488 | jit_epilog();\n", i, j, j, i, j, i, j); |
| 489 | } |
| 490 | } |
| 491 | puts("#endif"); |
| 492 | |
| 493 | puts("\n\ |
| 494 | jit_patch(jmpi_main);\n\ |
| 495 | jit_name(\"main\");\n\ |
| 496 | jit_note(\"cbit.c\", __LINE__);\n\ |
| 497 | jit_prolog();\n"); |
| 498 | |
| 499 | puts(" /* Call C functions for signed bitfields at offset 0 */"); |
| 500 | for (i = 1; i <= 32; i++) |
| 501 | printf("\ |
| 502 | jit_patch_at(jit_movi(JIT_R0, 0), nS%d);\n\ |
| 503 | jit_prepare();\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"); |
| 508 | for (; i <= 64; i++) |
| 509 | printf("\ |
| 510 | jit_patch_at(jit_movi(JIT_R0, 0), nS%d);\n\ |
| 511 | jit_prepare();\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); |
| 515 | puts("#endif"); |
| 516 | puts(" /* Call C functions for unsigned bitfields at offset 0 */"); |
| 517 | for (i = 1; i <= 32; i++) |
| 518 | printf("\ |
| 519 | jit_patch_at(jit_movi(JIT_R0, 0), nU%d);\n\ |
| 520 | jit_prepare();\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"); |
| 525 | for (; i <= 64; i++) |
| 526 | printf("\ |
| 527 | jit_patch_at(jit_movi(JIT_R0, 0), nU%d);\n\ |
| 528 | jit_prepare();\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); |
| 532 | puts("#endif"); |
| 533 | |
| 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++) { |
| 537 | printf("\ |
| 538 | jit_patch_at(jit_movi(JIT_R0, 0), nS%d_%d);\n\ |
| 539 | jit_prepare();\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); |
| 543 | } |
| 544 | } |
| 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++) { |
| 549 | if (i + j > 32) |
| 550 | printf("\ |
| 551 | jit_patch_at(jit_movi(JIT_R0, 0), nS%d_%d);\n\ |
| 552 | jit_prepare();\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); |
| 556 | } |
| 557 | } |
| 558 | puts("#endif"); |
| 559 | |
| 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++) { |
| 563 | printf("\ |
| 564 | jit_patch_at(jit_movi(JIT_R0, 0), nU%d_%d);\n\ |
| 565 | jit_prepare();\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); |
| 569 | } |
| 570 | } |
| 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++) { |
| 575 | if (i + j > 32) |
| 576 | printf("\ |
| 577 | jit_patch_at(jit_movi(JIT_R0, 0), nU%d_%d);\n\ |
| 578 | jit_prepare();\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); |
| 582 | } |
| 583 | } |
| 584 | puts("#endif"); |
| 585 | |
| 586 | puts("\n\ |
| 587 | jit_ret();\n\ |
| 588 | jit_epilog();\n\ |
| 589 | \n\ |
| 590 | code = jit_emit();\n\ |
| 591 | \n\ |
| 592 | jit_clear_state();\n\ |
| 593 | \n\ |
| 594 | (*code)();\n\ |
| 595 | jit_destroy_state();\n\ |
| 596 | \n\ |
| 597 | finish_jit();\n\ |
| 598 | \n\ |
| 599 | return (0);\n\ |
| 600 | }"); |
| 601 | |
| 602 | return (0); |
| 603 | } |