1 /* 2 * Stack-less Just-In-Time compiler 3 * 4 * Copyright 2009-2012 Zoltan Herczeg (hzmester (at) freemail.hu). All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without modification, are 7 * permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright notice, this list of 10 * conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright notice, this list 13 * of conditions and the following disclaimer in the documentation and/or other materials 14 * provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 19 * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 21 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 22 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 24 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 #include "sljitLir.h" 28 29 #define CHECK_ERROR() \ 30 do { \ 31 if (SLJIT_UNLIKELY(compiler->error)) \ 32 return compiler->error; \ 33 } while (0) 34 35 #define CHECK_ERROR_PTR() \ 36 do { \ 37 if (SLJIT_UNLIKELY(compiler->error)) \ 38 return NULL; \ 39 } while (0) 40 41 #define FAIL_IF(expr) \ 42 do { \ 43 if (SLJIT_UNLIKELY(expr)) \ 44 return compiler->error; \ 45 } while (0) 46 47 #define PTR_FAIL_IF(expr) \ 48 do { \ 49 if (SLJIT_UNLIKELY(expr)) \ 50 return NULL; \ 51 } while (0) 52 53 #define FAIL_IF_NULL(ptr) \ 54 do { \ 55 if (SLJIT_UNLIKELY(!(ptr))) { \ 56 compiler->error = SLJIT_ERR_ALLOC_FAILED; \ 57 return SLJIT_ERR_ALLOC_FAILED; \ 58 } \ 59 } while (0) 60 61 #define PTR_FAIL_IF_NULL(ptr) \ 62 do { \ 63 if (SLJIT_UNLIKELY(!(ptr))) { \ 64 compiler->error = SLJIT_ERR_ALLOC_FAILED; \ 65 return NULL; \ 66 } \ 67 } while (0) 68 69 #define PTR_FAIL_WITH_EXEC_IF(ptr) \ 70 do { \ 71 if (SLJIT_UNLIKELY(!(ptr))) { \ 72 compiler->error = SLJIT_ERR_EX_ALLOC_FAILED; \ 73 return NULL; \ 74 } \ 75 } while (0) 76 77 #if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) 78 79 #define GET_OPCODE(op) \ 80 ((op) & ~(SLJIT_I32_OP | SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS)) 81 82 #define GET_FLAGS(op) \ 83 ((op) & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C)) 84 85 #define GET_ALL_FLAGS(op) \ 86 ((op) & (SLJIT_I32_OP | SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS)) 87 88 #define TYPE_CAST_NEEDED(op) \ 89 (((op) >= SLJIT_MOV_U8 && (op) <= SLJIT_MOV_S16) || ((op) >= SLJIT_MOVU_U8 && (op) <= SLJIT_MOVU_S16)) 90 91 #define BUF_SIZE 4096 92 93 #if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE) 94 #define ABUF_SIZE 2048 95 #else 96 #define ABUF_SIZE 4096 97 #endif 98 99 /* Parameter parsing. */ 100 #define REG_MASK 0x3f 101 #define OFFS_REG(reg) (((reg) >> 8) & REG_MASK) 102 #define OFFS_REG_MASK (REG_MASK << 8) 103 #define TO_OFFS_REG(reg) ((reg) << 8) 104 /* When reg cannot be unused. */ 105 #define FAST_IS_REG(reg) ((reg) <= REG_MASK) 106 /* When reg can be unused. */ 107 #define SLOW_IS_REG(reg) ((reg) > 0 && (reg) <= REG_MASK) 108 109 /* Jump flags. */ 110 #define JUMP_LABEL 0x1 111 #define JUMP_ADDR 0x2 112 /* SLJIT_REWRITABLE_JUMP is 0x1000. */ 113 114 #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) 115 # define PATCH_MB 0x4 116 # define PATCH_MW 0x8 117 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) 118 # define PATCH_MD 0x10 119 #endif 120 #endif 121 122 #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) 123 # define IS_BL 0x4 124 # define PATCH_B 0x8 125 #endif 126 127 #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) 128 # define CPOOL_SIZE 512 129 #endif 130 131 #if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) 132 # define IS_COND 0x04 133 # define IS_BL 0x08 134 /* conditional + imm8 */ 135 # define PATCH_TYPE1 0x10 136 /* conditional + imm20 */ 137 # define PATCH_TYPE2 0x20 138 /* IT + imm24 */ 139 # define PATCH_TYPE3 0x30 140 /* imm11 */ 141 # define PATCH_TYPE4 0x40 142 /* imm24 */ 143 # define PATCH_TYPE5 0x50 144 /* BL + imm24 */ 145 # define PATCH_BL 0x60 146 /* 0xf00 cc code for branches */ 147 #endif 148 149 #if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) 150 # define IS_COND 0x004 151 # define IS_CBZ 0x008 152 # define IS_BL 0x010 153 # define PATCH_B 0x020 154 # define PATCH_COND 0x040 155 # define PATCH_ABS48 0x080 156 # define PATCH_ABS64 0x100 157 #endif 158 159 #if (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) 160 # define IS_COND 0x004 161 # define IS_CALL 0x008 162 # define PATCH_B 0x010 163 # define PATCH_ABS_B 0x020 164 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) 165 # define PATCH_ABS32 0x040 166 # define PATCH_ABS48 0x080 167 #endif 168 # define REMOVE_COND 0x100 169 #endif 170 171 #if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) 172 # define IS_MOVABLE 0x004 173 # define IS_JAL 0x008 174 # define IS_CALL 0x010 175 # define IS_BIT26_COND 0x020 176 # define IS_BIT16_COND 0x040 177 178 # define IS_COND (IS_BIT26_COND | IS_BIT16_COND) 179 180 # define PATCH_B 0x080 181 # define PATCH_J 0x100 182 183 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) 184 # define PATCH_ABS32 0x200 185 # define PATCH_ABS48 0x400 186 #endif 187 188 /* instruction types */ 189 # define MOVABLE_INS 0 190 /* 1 - 31 last destination register */ 191 /* no destination (i.e: store) */ 192 # define UNMOVABLE_INS 32 193 /* FPU status register */ 194 # define FCSR_FCC 33 195 #endif 196 197 #if (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) 198 # define IS_JAL 0x04 199 # define IS_COND 0x08 200 201 # define PATCH_B 0x10 202 # define PATCH_J 0x20 203 #endif 204 205 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) 206 # define IS_MOVABLE 0x04 207 # define IS_COND 0x08 208 # define IS_CALL 0x10 209 210 # define PATCH_B 0x20 211 # define PATCH_CALL 0x40 212 213 /* instruction types */ 214 # define MOVABLE_INS 0 215 /* 1 - 31 last destination register */ 216 /* no destination (i.e: store) */ 217 # define UNMOVABLE_INS 32 218 219 # define DST_INS_MASK 0xff 220 221 /* ICC_SET is the same as SET_FLAGS. */ 222 # define ICC_IS_SET (1 << 23) 223 # define FCC_IS_SET (1 << 24) 224 #endif 225 226 /* Stack management. */ 227 228 #define GET_SAVED_REGISTERS_SIZE(scratches, saveds, extra) \ 229 (((scratches < SLJIT_NUMBER_OF_SCRATCH_REGISTERS ? 0 : (scratches - SLJIT_NUMBER_OF_SCRATCH_REGISTERS)) + \ 230 (saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? saveds : SLJIT_NUMBER_OF_SAVED_REGISTERS) + \ 231 extra) * sizeof(sljit_sw)) 232 233 #define ADJUST_LOCAL_OFFSET(p, i) \ 234 if ((p) == (SLJIT_MEM1(SLJIT_SP))) \ 235 (i) += SLJIT_LOCALS_OFFSET; 236 237 #endif /* !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) */ 238 239 /* Utils can still be used even if SLJIT_CONFIG_UNSUPPORTED is set. */ 240 #include "sljitUtils.c" 241 242 #if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) 243 244 #if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) 245 #include "sljitExecAllocator.c" 246 #endif 247 248 /* Argument checking features. */ 249 250 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) 251 252 /* Returns with error when an invalid argument is passed. */ 253 254 #define CHECK_ARGUMENT(x) \ 255 do { \ 256 if (SLJIT_UNLIKELY(!(x))) \ 257 return 1; \ 258 } while (0) 259 260 #define CHECK_RETURN_TYPE sljit_s32 261 #define CHECK_RETURN_OK return 0 262 263 #define CHECK(x) \ 264 do { \ 265 if (SLJIT_UNLIKELY(x)) { \ 266 compiler->error = SLJIT_ERR_BAD_ARGUMENT; \ 267 return SLJIT_ERR_BAD_ARGUMENT; \ 268 } \ 269 } while (0) 270 271 #define CHECK_PTR(x) \ 272 do { \ 273 if (SLJIT_UNLIKELY(x)) { \ 274 compiler->error = SLJIT_ERR_BAD_ARGUMENT; \ 275 return NULL; \ 276 } \ 277 } while (0) 278 279 #define CHECK_REG_INDEX(x) \ 280 do { \ 281 if (SLJIT_UNLIKELY(x)) { \ 282 return -2; \ 283 } \ 284 } while (0) 285 286 #elif (defined SLJIT_DEBUG && SLJIT_DEBUG) 287 288 /* Assertion failure occures if an invalid argument is passed. */ 289 #undef SLJIT_ARGUMENT_CHECKS 290 #define SLJIT_ARGUMENT_CHECKS 1 291 292 #define CHECK_ARGUMENT(x) SLJIT_ASSERT(x) 293 #define CHECK_RETURN_TYPE void 294 #define CHECK_RETURN_OK return 295 #define CHECK(x) x 296 #define CHECK_PTR(x) x 297 #define CHECK_REG_INDEX(x) x 298 299 #elif (defined SLJIT_VERBOSE && SLJIT_VERBOSE) 300 301 /* Arguments are not checked. */ 302 #define CHECK_RETURN_TYPE void 303 #define CHECK_RETURN_OK return 304 #define CHECK(x) x 305 #define CHECK_PTR(x) x 306 #define CHECK_REG_INDEX(x) x 307 308 #else 309 310 /* Arguments are not checked. */ 311 #define CHECK(x) 312 #define CHECK_PTR(x) 313 #define CHECK_REG_INDEX(x) 314 315 #endif /* SLJIT_ARGUMENT_CHECKS */ 316 317 /* --------------------------------------------------------------------- */ 318 /* Public functions */ 319 /* --------------------------------------------------------------------- */ 320 321 #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) 322 #define SLJIT_NEEDS_COMPILER_INIT 1 323 static sljit_s32 compiler_initialized = 0; 324 /* A thread safe initialization. */ 325 static void init_compiler(void); 326 #endif 327 328 SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data) 329 { 330 struct sljit_compiler *compiler = (struct sljit_compiler*)SLJIT_MALLOC(sizeof(struct sljit_compiler), allocator_data); 331 if (!compiler) 332 return NULL; 333 SLJIT_ZEROMEM(compiler, sizeof(struct sljit_compiler)); 334 335 SLJIT_COMPILE_ASSERT( 336 sizeof(sljit_s8) == 1 && sizeof(sljit_u8) == 1 337 && sizeof(sljit_s16) == 2 && sizeof(sljit_u16) == 2 338 && sizeof(sljit_s32) == 4 && sizeof(sljit_u32) == 4 339 && (sizeof(sljit_p) == 4 || sizeof(sljit_p) == 8) 340 && sizeof(sljit_p) <= sizeof(sljit_sw) 341 && (sizeof(sljit_sw) == 4 || sizeof(sljit_sw) == 8) 342 && (sizeof(sljit_uw) == 4 || sizeof(sljit_uw) == 8), 343 invalid_integer_types); 344 SLJIT_COMPILE_ASSERT(SLJIT_I32_OP == SLJIT_F32_OP, 345 int_op_and_single_op_must_be_the_same); 346 SLJIT_COMPILE_ASSERT(SLJIT_REWRITABLE_JUMP != SLJIT_F32_OP, 347 rewritable_jump_and_single_op_must_not_be_the_same); 348 349 /* Only the non-zero members must be set. */ 350 compiler->error = SLJIT_SUCCESS; 351 352 compiler->allocator_data = allocator_data; 353 compiler->buf = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE, allocator_data); 354 compiler->abuf = (struct sljit_memory_fragment*)SLJIT_MALLOC(ABUF_SIZE, allocator_data); 355 356 if (!compiler->buf || !compiler->abuf) { 357 if (compiler->buf) 358 SLJIT_FREE(compiler->buf, allocator_data); 359 if (compiler->abuf) 360 SLJIT_FREE(compiler->abuf, allocator_data); 361 SLJIT_FREE(compiler, allocator_data); 362 return NULL; 363 } 364 365 compiler->buf->next = NULL; 366 compiler->buf->used_size = 0; 367 compiler->abuf->next = NULL; 368 compiler->abuf->used_size = 0; 369 370 compiler->scratches = -1; 371 compiler->saveds = -1; 372 compiler->fscratches = -1; 373 compiler->fsaveds = -1; 374 compiler->local_size = -1; 375 376 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) 377 compiler->args = -1; 378 #endif 379 380 #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) 381 compiler->cpool = (sljit_uw*)SLJIT_MALLOC(CPOOL_SIZE * sizeof(sljit_uw) 382 + CPOOL_SIZE * sizeof(sljit_u8), allocator_data); 383 if (!compiler->cpool) { 384 SLJIT_FREE(compiler->buf, allocator_data); 385 SLJIT_FREE(compiler->abuf, allocator_data); 386 SLJIT_FREE(compiler, allocator_data); 387 return NULL; 388 } 389 compiler->cpool_unique = (sljit_u8*)(compiler->cpool + CPOOL_SIZE); 390 compiler->cpool_diff = 0xffffffff; 391 #endif 392 393 #if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) 394 compiler->delay_slot = UNMOVABLE_INS; 395 #endif 396 397 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) 398 compiler->delay_slot = UNMOVABLE_INS; 399 #endif 400 401 #if (defined SLJIT_NEEDS_COMPILER_INIT && SLJIT_NEEDS_COMPILER_INIT) 402 if (!compiler_initialized) { 403 init_compiler(); 404 compiler_initialized = 1; 405 } 406 #endif 407 408 return compiler; 409 } 410 411 SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler) 412 { 413 struct sljit_memory_fragment *buf; 414 struct sljit_memory_fragment *curr; 415 void *allocator_data = compiler->allocator_data; 416 SLJIT_UNUSED_ARG(allocator_data); 417 418 buf = compiler->buf; 419 while (buf) { 420 curr = buf; 421 buf = buf->next; 422 SLJIT_FREE(curr, allocator_data); 423 } 424 425 buf = compiler->abuf; 426 while (buf) { 427 curr = buf; 428 buf = buf->next; 429 SLJIT_FREE(curr, allocator_data); 430 } 431 432 #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) 433 SLJIT_FREE(compiler->cpool, allocator_data); 434 #endif 435 SLJIT_FREE(compiler, allocator_data); 436 } 437 438 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compiler *compiler) 439 { 440 if (compiler->error == SLJIT_SUCCESS) 441 compiler->error = SLJIT_ERR_ALLOC_FAILED; 442 } 443 444 #if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) 445 SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code) 446 { 447 /* Remove thumb mode flag. */ 448 SLJIT_FREE_EXEC((void*)((sljit_uw)code & ~0x1)); 449 } 450 #elif (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) 451 SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code) 452 { 453 /* Resolve indirection. */ 454 code = (void*)(*(sljit_uw*)code); 455 SLJIT_FREE_EXEC(code); 456 } 457 #else 458 SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code) 459 { 460 SLJIT_FREE_EXEC(code); 461 } 462 #endif 463 464 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label) 465 { 466 if (SLJIT_LIKELY(!!jump) && SLJIT_LIKELY(!!label)) { 467 jump->flags &= ~JUMP_ADDR; 468 jump->flags |= JUMP_LABEL; 469 jump->u.label = label; 470 } 471 } 472 473 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target) 474 { 475 if (SLJIT_LIKELY(!!jump)) { 476 jump->flags &= ~JUMP_LABEL; 477 jump->flags |= JUMP_ADDR; 478 jump->u.target = target; 479 } 480 } 481 482 /* --------------------------------------------------------------------- */ 483 /* Private functions */ 484 /* --------------------------------------------------------------------- */ 485 486 static void* ensure_buf(struct sljit_compiler *compiler, sljit_uw size) 487 { 488 sljit_u8 *ret; 489 struct sljit_memory_fragment *new_frag; 490 491 SLJIT_ASSERT(size <= 256); 492 if (compiler->buf->used_size + size <= (BUF_SIZE - (sljit_uw)SLJIT_OFFSETOF(struct sljit_memory_fragment, memory))) { 493 ret = compiler->buf->memory + compiler->buf->used_size; 494 compiler->buf->used_size += size; 495 return ret; 496 } 497 new_frag = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE, compiler->allocator_data); 498 PTR_FAIL_IF_NULL(new_frag); 499 new_frag->next = compiler->buf; 500 compiler->buf = new_frag; 501 new_frag->used_size = size; 502 return new_frag->memory; 503 } 504 505 static void* ensure_abuf(struct sljit_compiler *compiler, sljit_uw size) 506 { 507 sljit_u8 *ret; 508 struct sljit_memory_fragment *new_frag; 509 510 SLJIT_ASSERT(size <= 256); 511 if (compiler->abuf->used_size + size <= (ABUF_SIZE - (sljit_uw)SLJIT_OFFSETOF(struct sljit_memory_fragment, memory))) { 512 ret = compiler->abuf->memory + compiler->abuf->used_size; 513 compiler->abuf->used_size += size; 514 return ret; 515 } 516 new_frag = (struct sljit_memory_fragment*)SLJIT_MALLOC(ABUF_SIZE, compiler->allocator_data); 517 PTR_FAIL_IF_NULL(new_frag); 518 new_frag->next = compiler->abuf; 519 compiler->abuf = new_frag; 520 new_frag->used_size = size; 521 return new_frag->memory; 522 } 523 524 SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_s32 size) 525 { 526 CHECK_ERROR_PTR(); 527 528 #if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE) 529 if (size <= 0 || size > 128) 530 return NULL; 531 size = (size + 7) & ~7; 532 #else 533 if (size <= 0 || size > 64) 534 return NULL; 535 size = (size + 3) & ~3; 536 #endif 537 return ensure_abuf(compiler, size); 538 } 539 540 static SLJIT_INLINE void reverse_buf(struct sljit_compiler *compiler) 541 { 542 struct sljit_memory_fragment *buf = compiler->buf; 543 struct sljit_memory_fragment *prev = NULL; 544 struct sljit_memory_fragment *tmp; 545 546 do { 547 tmp = buf->next; 548 buf->next = prev; 549 prev = buf; 550 buf = tmp; 551 } while (buf != NULL); 552 553 compiler->buf = prev; 554 } 555 556 static SLJIT_INLINE void set_emit_enter(struct sljit_compiler *compiler, 557 sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, 558 sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) 559 { 560 SLJIT_UNUSED_ARG(args); 561 SLJIT_UNUSED_ARG(local_size); 562 563 compiler->options = options; 564 compiler->scratches = scratches; 565 compiler->saveds = saveds; 566 compiler->fscratches = fscratches; 567 compiler->fsaveds = fsaveds; 568 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) 569 compiler->logical_local_size = local_size; 570 #endif 571 } 572 573 static SLJIT_INLINE void set_set_context(struct sljit_compiler *compiler, 574 sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, 575 sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) 576 { 577 SLJIT_UNUSED_ARG(args); 578 SLJIT_UNUSED_ARG(local_size); 579 580 compiler->options = options; 581 compiler->scratches = scratches; 582 compiler->saveds = saveds; 583 compiler->fscratches = fscratches; 584 compiler->fsaveds = fsaveds; 585 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) 586 compiler->logical_local_size = local_size; 587 #endif 588 } 589 590 static SLJIT_INLINE void set_label(struct sljit_label *label, struct sljit_compiler *compiler) 591 { 592 label->next = NULL; 593 label->size = compiler->size; 594 if (compiler->last_label) 595 compiler->last_label->next = label; 596 else 597 compiler->labels = label; 598 compiler->last_label = label; 599 } 600 601 static SLJIT_INLINE void set_jump(struct sljit_jump *jump, struct sljit_compiler *compiler, sljit_s32 flags) 602 { 603 jump->next = NULL; 604 jump->flags = flags; 605 if (compiler->last_jump) 606 compiler->last_jump->next = jump; 607 else 608 compiler->jumps = jump; 609 compiler->last_jump = jump; 610 } 611 612 static SLJIT_INLINE void set_const(struct sljit_const *const_, struct sljit_compiler *compiler) 613 { 614 const_->next = NULL; 615 const_->addr = compiler->size; 616 if (compiler->last_const) 617 compiler->last_const->next = const_; 618 else 619 compiler->consts = const_; 620 compiler->last_const = const_; 621 } 622 623 #define ADDRESSING_DEPENDS_ON(exp, reg) \ 624 (((exp) & SLJIT_MEM) && (((exp) & REG_MASK) == reg || OFFS_REG(exp) == reg)) 625 626 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) 627 #define FUNCTION_CHECK_OP() \ 628 CHECK_ARGUMENT(!GET_FLAGS(op) || !(op & SLJIT_KEEP_FLAGS)); \ 629 switch (GET_OPCODE(op)) { \ 630 case SLJIT_NOT: \ 631 case SLJIT_CLZ: \ 632 case SLJIT_AND: \ 633 case SLJIT_OR: \ 634 case SLJIT_XOR: \ 635 case SLJIT_SHL: \ 636 case SLJIT_LSHR: \ 637 case SLJIT_ASHR: \ 638 CHECK_ARGUMENT(!(op & (SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C))); \ 639 break; \ 640 case SLJIT_NEG: \ 641 CHECK_ARGUMENT(!(op & (SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_C))); \ 642 break; \ 643 case SLJIT_MUL: \ 644 CHECK_ARGUMENT(!(op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_C))); \ 645 break; \ 646 case SLJIT_ADD: \ 647 CHECK_ARGUMENT(!(op & (SLJIT_SET_U | SLJIT_SET_S))); \ 648 break; \ 649 case SLJIT_SUB: \ 650 break; \ 651 case SLJIT_ADDC: \ 652 case SLJIT_SUBC: \ 653 CHECK_ARGUMENT(!(op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O))); \ 654 break; \ 655 case SLJIT_BREAKPOINT: \ 656 case SLJIT_NOP: \ 657 case SLJIT_LMUL_UW: \ 658 case SLJIT_LMUL_SW: \ 659 case SLJIT_MOV: \ 660 case SLJIT_MOV_U32: \ 661 case SLJIT_MOV_P: \ 662 case SLJIT_MOVU: \ 663 case SLJIT_MOVU_U32: \ 664 case SLJIT_MOVU_P: \ 665 /* Nothing allowed */ \ 666 CHECK_ARGUMENT(!(op & (SLJIT_I32_OP | SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \ 667 break; \ 668 default: \ 669 /* Only SLJIT_I32_OP or SLJIT_F32_OP is allowed. */ \ 670 CHECK_ARGUMENT(!(op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \ 671 break; \ 672 } 673 674 #define FUNCTION_CHECK_FOP() \ 675 CHECK_ARGUMENT(!GET_FLAGS(op) || !(op & SLJIT_KEEP_FLAGS)); \ 676 switch (GET_OPCODE(op)) { \ 677 case SLJIT_CMP_F64: \ 678 CHECK_ARGUMENT(!(op & (SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \ 679 CHECK_ARGUMENT((op & (SLJIT_SET_E | SLJIT_SET_S))); \ 680 break; \ 681 default: \ 682 /* Only SLJIT_I32_OP or SLJIT_F32_OP is allowed. */ \ 683 CHECK_ARGUMENT(!(op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \ 684 break; \ 685 } 686 687 #define FUNCTION_CHECK_IS_REG(r) \ 688 (((r) >= SLJIT_R0 && (r) < (SLJIT_R0 + compiler->scratches)) || \ 689 ((r) > (SLJIT_S0 - compiler->saveds) && (r) <= SLJIT_S0)) 690 691 #define FUNCTION_CHECK_IS_REG_OR_UNUSED(r) \ 692 ((r) == SLJIT_UNUSED || \ 693 ((r) >= SLJIT_R0 && (r) < (SLJIT_R0 + compiler->scratches)) || \ 694 ((r) > (SLJIT_S0 - compiler->saveds) && (r) <= SLJIT_S0)) 695 696 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) 697 #define CHECK_NOT_VIRTUAL_REGISTER(p) \ 698 CHECK_ARGUMENT((p) < SLJIT_R3 || (p) > SLJIT_R6); 699 #else 700 #define CHECK_NOT_VIRTUAL_REGISTER(p) 701 #endif 702 703 #define FUNCTION_CHECK_SRC(p, i) \ 704 CHECK_ARGUMENT(compiler->scratches != -1 && compiler->saveds != -1); \ 705 if (FUNCTION_CHECK_IS_REG(p)) \ 706 CHECK_ARGUMENT((i) == 0); \ 707 else if ((p) == SLJIT_IMM) \ 708 ; \ 709 else if ((p) == (SLJIT_MEM1(SLJIT_SP))) \ 710 CHECK_ARGUMENT((i) >= 0 && (i) < compiler->logical_local_size); \ 711 else { \ 712 CHECK_ARGUMENT((p) & SLJIT_MEM); \ 713 CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG_OR_UNUSED((p) & REG_MASK)); \ 714 CHECK_NOT_VIRTUAL_REGISTER((p) & REG_MASK); \ 715 if ((p) & OFFS_REG_MASK) { \ 716 CHECK_ARGUMENT(((p) & REG_MASK) != SLJIT_UNUSED); \ 717 CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(OFFS_REG(p))); \ 718 CHECK_NOT_VIRTUAL_REGISTER(OFFS_REG(p)); \ 719 CHECK_ARGUMENT(!((i) & ~0x3)); \ 720 } \ 721 CHECK_ARGUMENT(!((p) & ~(SLJIT_MEM | SLJIT_IMM | REG_MASK | OFFS_REG_MASK))); \ 722 } 723 724 #define FUNCTION_CHECK_DST(p, i) \ 725 CHECK_ARGUMENT(compiler->scratches != -1 && compiler->saveds != -1); \ 726 if (FUNCTION_CHECK_IS_REG_OR_UNUSED(p)) \ 727 CHECK_ARGUMENT((i) == 0); \ 728 else if ((p) == (SLJIT_MEM1(SLJIT_SP))) \ 729 CHECK_ARGUMENT((i) >= 0 && (i) < compiler->logical_local_size); \ 730 else { \ 731 CHECK_ARGUMENT((p) & SLJIT_MEM); \ 732 CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG_OR_UNUSED((p) & REG_MASK)); \ 733 CHECK_NOT_VIRTUAL_REGISTER((p) & REG_MASK); \ 734 if ((p) & OFFS_REG_MASK) { \ 735 CHECK_ARGUMENT(((p) & REG_MASK) != SLJIT_UNUSED); \ 736 CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(OFFS_REG(p))); \ 737 CHECK_NOT_VIRTUAL_REGISTER(OFFS_REG(p)); \ 738 CHECK_ARGUMENT(!((i) & ~0x3)); \ 739 } \ 740 CHECK_ARGUMENT(!((p) & ~(SLJIT_MEM | SLJIT_IMM | REG_MASK | OFFS_REG_MASK))); \ 741 } 742 743 #define FUNCTION_FCHECK(p, i) \ 744 CHECK_ARGUMENT(compiler->fscratches != -1 && compiler->fsaveds != -1); \ 745 if (((p) >= SLJIT_FR0 && (p) < (SLJIT_FR0 + compiler->fscratches)) || \ 746 ((p) > (SLJIT_FS0 - compiler->fsaveds) && (p) <= SLJIT_FS0)) \ 747 CHECK_ARGUMENT(i == 0); \ 748 else if ((p) == (SLJIT_MEM1(SLJIT_SP))) \ 749 CHECK_ARGUMENT((i) >= 0 && (i) < compiler->logical_local_size); \ 750 else { \ 751 CHECK_ARGUMENT((p) & SLJIT_MEM); \ 752 CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG_OR_UNUSED((p) & REG_MASK)); \ 753 CHECK_NOT_VIRTUAL_REGISTER((p) & REG_MASK); \ 754 if ((p) & OFFS_REG_MASK) { \ 755 CHECK_ARGUMENT(((p) & REG_MASK) != SLJIT_UNUSED); \ 756 CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(OFFS_REG(p))); \ 757 CHECK_NOT_VIRTUAL_REGISTER(OFFS_REG(p)); \ 758 CHECK_ARGUMENT(((p) & OFFS_REG_MASK) != TO_OFFS_REG(SLJIT_SP) && !(i & ~0x3)); \ 759 } \ 760 CHECK_ARGUMENT(!((p) & ~(SLJIT_MEM | SLJIT_IMM | REG_MASK | OFFS_REG_MASK))); \ 761 } 762 763 #define FUNCTION_CHECK_OP1() \ 764 if (GET_OPCODE(op) >= SLJIT_MOVU && GET_OPCODE(op) <= SLJIT_MOVU_P) { \ 765 CHECK_ARGUMENT(!(src & SLJIT_MEM) || (src & REG_MASK) != SLJIT_SP); \ 766 CHECK_ARGUMENT(!(dst & SLJIT_MEM) || (dst & REG_MASK) != SLJIT_SP); \ 767 if ((src & SLJIT_MEM) && (src & REG_MASK)) \ 768 CHECK_ARGUMENT((dst & REG_MASK) != (src & REG_MASK) && OFFS_REG(dst) != (src & REG_MASK)); \ 769 } 770 771 #endif /* SLJIT_ARGUMENT_CHECKS */ 772 773 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) 774 775 SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose) 776 { 777 compiler->verbose = verbose; 778 } 779 780 #if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE) 781 #ifdef _WIN64 782 # define SLJIT_PRINT_D "I64" 783 #else 784 # define SLJIT_PRINT_D "l" 785 #endif 786 #else 787 # define SLJIT_PRINT_D "" 788 #endif 789 790 #define sljit_verbose_reg(compiler, r) \ 791 do { \ 792 if ((r) < (SLJIT_R0 + compiler->scratches)) \ 793 fprintf(compiler->verbose, "r%d", (r) - SLJIT_R0); \ 794 else \ 795 fprintf(compiler->verbose, "s%d", SLJIT_NUMBER_OF_REGISTERS - (r)); \ 796 } while (0) 797 798 #define sljit_verbose_param(compiler, p, i) \ 799 if ((p) & SLJIT_IMM) \ 800 fprintf(compiler->verbose, "#%" SLJIT_PRINT_D "d", (i)); \ 801 else if ((p) & SLJIT_MEM) { \ 802 if ((p) & REG_MASK) { \ 803 fputc('[', compiler->verbose); \ 804 sljit_verbose_reg(compiler, (p) & REG_MASK); \ 805 if ((p) & OFFS_REG_MASK) { \ 806 fprintf(compiler->verbose, " + "); \ 807 sljit_verbose_reg(compiler, OFFS_REG(p)); \ 808 if (i) \ 809 fprintf(compiler->verbose, " * %d", 1 << (i)); \ 810 } \ 811 else if (i) \ 812 fprintf(compiler->verbose, " + %" SLJIT_PRINT_D "d", (i)); \ 813 fputc(']', compiler->verbose); \ 814 } \ 815 else \ 816 fprintf(compiler->verbose, "[#%" SLJIT_PRINT_D "d]", (i)); \ 817 } else if (p) \ 818 sljit_verbose_reg(compiler, p); \ 819 else \ 820 fprintf(compiler->verbose, "unused"); 821 822 #define sljit_verbose_fparam(compiler, p, i) \ 823 if ((p) & SLJIT_MEM) { \ 824 if ((p) & REG_MASK) { \ 825 fputc('[', compiler->verbose); \ 826 sljit_verbose_reg(compiler, (p) & REG_MASK); \ 827 if ((p) & OFFS_REG_MASK) { \ 828 fprintf(compiler->verbose, " + "); \ 829 sljit_verbose_reg(compiler, OFFS_REG(p)); \ 830 if (i) \ 831 fprintf(compiler->verbose, "%d", 1 << (i)); \ 832 } \ 833 else if (i) \ 834 fprintf(compiler->verbose, "%" SLJIT_PRINT_D "d", (i)); \ 835 fputc(']', compiler->verbose); \ 836 } \ 837 else \ 838 fprintf(compiler->verbose, "[#%" SLJIT_PRINT_D "d]", (i)); \ 839 } \ 840 else { \ 841 if ((p) < (SLJIT_FR0 + compiler->fscratches)) \ 842 fprintf(compiler->verbose, "fr%d", (p) - SLJIT_FR0); \ 843 else \ 844 fprintf(compiler->verbose, "fs%d", SLJIT_NUMBER_OF_FLOAT_REGISTERS - (p)); \ 845 } 846 847 static const char* op0_names[] = { 848 (char*)"breakpoint", (char*)"nop", (char*)"lmul.uw", (char*)"lmul.sw", 849 (char*)"divmod.u", (char*)"divmod.s", (char*)"div.u", (char*)"div.s" 850 }; 851 852 static const char* op1_names[] = { 853 (char*)"", (char*)".u8", (char*)".s8", (char*)".u16", 854 (char*)".s16", (char*)".u32", (char*)".s32", (char*)".p", 855 (char*)"", (char*)".u8", (char*)".s8", (char*)".u16", 856 (char*)".s16", (char*)".u32", (char*)".s32", (char*)".p", 857 (char*)"not", (char*)"neg", (char*)"clz", 858 }; 859 860 static const char* op2_names[] = { 861 (char*)"add", (char*)"addc", (char*)"sub", (char*)"subc", 862 (char*)"mul", (char*)"and", (char*)"or", (char*)"xor", 863 (char*)"shl", (char*)"lshr", (char*)"ashr", 864 }; 865 866 static const char* fop1_names[] = { 867 (char*)"mov", (char*)"conv", (char*)"conv", (char*)"conv", 868 (char*)"conv", (char*)"conv", (char*)"cmp", (char*)"neg", 869 (char*)"abs", 870 }; 871 872 static const char* fop2_names[] = { 873 (char*)"add", (char*)"sub", (char*)"mul", (char*)"div" 874 }; 875 876 #define JUMP_POSTFIX(type) \ 877 ((type & 0xff) <= SLJIT_MUL_NOT_OVERFLOW ? ((type & SLJIT_I32_OP) ? "32" : "") \ 878 : ((type & 0xff) <= SLJIT_ORDERED_F64 ? ((type & SLJIT_F32_OP) ? ".f32" : ".f64") : "")) 879 880 static char* jump_names[] = { 881 (char*)"equal", (char*)"not_equal", 882 (char*)"less", (char*)"greater_equal", 883 (char*)"greater", (char*)"less_equal", 884 (char*)"sig_less", (char*)"sig_greater_equal", 885 (char*)"sig_greater", (char*)"sig_less_equal", 886 (char*)"overflow", (char*)"not_overflow", 887 (char*)"mul_overflow", (char*)"mul_not_overflow", 888 (char*)"equal", (char*)"not_equal", 889 (char*)"less", (char*)"greater_equal", 890 (char*)"greater", (char*)"less_equal", 891 (char*)"unordered", (char*)"ordered", 892 (char*)"jump", (char*)"fast_call", 893 (char*)"call0", (char*)"call1", (char*)"call2", (char*)"call3" 894 }; 895 896 #endif /* SLJIT_VERBOSE */ 897 898 /* --------------------------------------------------------------------- */ 899 /* Arch dependent */ 900 /* --------------------------------------------------------------------- */ 901 902 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ 903 || (defined SLJIT_VERBOSE && SLJIT_VERBOSE) 904 905 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_generate_code(struct sljit_compiler *compiler) 906 { 907 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) 908 struct sljit_jump *jump; 909 #endif 910 911 SLJIT_UNUSED_ARG(compiler); 912 913 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) 914 CHECK_ARGUMENT(compiler->size > 0); 915 jump = compiler->jumps; 916 while (jump) { 917 /* All jumps have target. */ 918 CHECK_ARGUMENT(jump->flags & (JUMP_LABEL | JUMP_ADDR)); 919 jump = jump->next; 920 } 921 #endif 922 CHECK_RETURN_OK; 923 } 924 925 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_enter(struct sljit_compiler *compiler, 926 sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, 927 sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) 928 { 929 SLJIT_UNUSED_ARG(compiler); 930 931 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) 932 CHECK_ARGUMENT(!(options & ~SLJIT_DOUBLE_ALIGNMENT)); 933 CHECK_ARGUMENT(args >= 0 && args <= 3); 934 CHECK_ARGUMENT(scratches >= 0 && scratches <= SLJIT_NUMBER_OF_REGISTERS); 935 CHECK_ARGUMENT(saveds >= 0 && saveds <= SLJIT_NUMBER_OF_REGISTERS); 936 CHECK_ARGUMENT(scratches + saveds <= SLJIT_NUMBER_OF_REGISTERS); 937 CHECK_ARGUMENT(args <= saveds); 938 CHECK_ARGUMENT(fscratches >= 0 && fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS); 939 CHECK_ARGUMENT(fsaveds >= 0 && fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS); 940 CHECK_ARGUMENT(fscratches + fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS); 941 CHECK_ARGUMENT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE); 942 #endif 943 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) 944 if (SLJIT_UNLIKELY(!!compiler->verbose)) 945 fprintf(compiler->verbose, " enter options:none args:%d scratches:%d saveds:%d fscratches:%d fsaveds:%d local_size:%d\n", 946 args, scratches, saveds, fscratches, fsaveds, local_size); 947 #endif 948 CHECK_RETURN_OK; 949 } 950 951 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_set_context(struct sljit_compiler *compiler, 952 sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, 953 sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) 954 { 955 if (SLJIT_UNLIKELY(compiler->skip_checks)) { 956 compiler->skip_checks = 0; 957 CHECK_RETURN_OK; 958 } 959 960 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) 961 CHECK_ARGUMENT(!(options & ~SLJIT_DOUBLE_ALIGNMENT)); 962 CHECK_ARGUMENT(args >= 0 && args <= 3); 963 CHECK_ARGUMENT(scratches >= 0 && scratches <= SLJIT_NUMBER_OF_REGISTERS); 964 CHECK_ARGUMENT(saveds >= 0 && saveds <= SLJIT_NUMBER_OF_REGISTERS); 965 CHECK_ARGUMENT(scratches + saveds <= SLJIT_NUMBER_OF_REGISTERS); 966 CHECK_ARGUMENT(args <= saveds); 967 CHECK_ARGUMENT(fscratches >= 0 && fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS); 968 CHECK_ARGUMENT(fsaveds >= 0 && fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS); 969 CHECK_ARGUMENT(fscratches + fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS); 970 CHECK_ARGUMENT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE); 971 #endif 972 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) 973 if (SLJIT_UNLIKELY(!!compiler->verbose)) 974 fprintf(compiler->verbose, " set_context options:none args:%d scratches:%d saveds:%d fscratches:%d fsaveds:%d local_size:%d\n", 975 args, scratches, saveds, fscratches, fsaveds, local_size); 976 #endif 977 CHECK_RETURN_OK; 978 } 979 980 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw) 981 { 982 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) 983 CHECK_ARGUMENT(compiler->scratches >= 0); 984 if (op != SLJIT_UNUSED) { 985 CHECK_ARGUMENT(op >= SLJIT_MOV && op <= SLJIT_MOV_P); 986 FUNCTION_CHECK_SRC(src, srcw); 987 } 988 else 989 CHECK_ARGUMENT(src == 0 && srcw == 0); 990 #endif 991 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) 992 if (SLJIT_UNLIKELY(!!compiler->verbose)) { 993 if (op == SLJIT_UNUSED) 994 fprintf(compiler->verbose, " return\n"); 995 else { 996 fprintf(compiler->verbose, " return%s ", op1_names[op - SLJIT_OP1_BASE]); 997 sljit_verbose_param(compiler, src, srcw); 998 fprintf(compiler->verbose, "\n"); 999 } 1000 } 1001 #endif 1002 CHECK_RETURN_OK; 1003 } 1004 1005 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) 1006 { 1007 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) 1008 FUNCTION_CHECK_DST(dst, dstw); 1009 #endif 1010 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) 1011 if (SLJIT_UNLIKELY(!!compiler->verbose)) { 1012 fprintf(compiler->verbose, " fast_enter "); 1013 sljit_verbose_param(compiler, dst, dstw); 1014 fprintf(compiler->verbose, "\n"); 1015 } 1016 #endif 1017 CHECK_RETURN_OK; 1018 } 1019 1020 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) 1021 { 1022 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) 1023 FUNCTION_CHECK_SRC(src, srcw); 1024 #endif 1025 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) 1026 if (SLJIT_UNLIKELY(!!compiler->verbose)) { 1027 fprintf(compiler->verbose, " fast_return "); 1028 sljit_verbose_param(compiler, src, srcw); 1029 fprintf(compiler->verbose, "\n"); 1030 } 1031 #endif 1032 CHECK_RETURN_OK; 1033 } 1034 1035 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) 1036 { 1037 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) 1038 CHECK_ARGUMENT((op >= SLJIT_BREAKPOINT && op <= SLJIT_LMUL_SW) 1039 || ((op & ~SLJIT_I32_OP) >= SLJIT_DIVMOD_UW && (op & ~SLJIT_I32_OP) <= SLJIT_DIV_SW)); 1040 CHECK_ARGUMENT(op < SLJIT_LMUL_UW || compiler->scratches >= 2); 1041 #endif 1042 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) 1043 if (SLJIT_UNLIKELY(!!compiler->verbose)) 1044 { 1045 fprintf(compiler->verbose, " %s", op0_names[GET_OPCODE(op) - SLJIT_OP0_BASE]); 1046 if (GET_OPCODE(op) >= SLJIT_DIVMOD_UW) { 1047 fprintf(compiler->verbose, (op & SLJIT_I32_OP) ? "32" : "w"); 1048 } 1049 fprintf(compiler->verbose, "\n"); 1050 } 1051 #endif 1052 CHECK_RETURN_OK; 1053 } 1054 1055 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, 1056 sljit_s32 dst, sljit_sw dstw, 1057 sljit_s32 src, sljit_sw srcw) 1058 { 1059 if (SLJIT_UNLIKELY(compiler->skip_checks)) { 1060 compiler->skip_checks = 0; 1061 CHECK_RETURN_OK; 1062 } 1063 1064 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) 1065 CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_CLZ); 1066 FUNCTION_CHECK_OP(); 1067 FUNCTION_CHECK_SRC(src, srcw); 1068 FUNCTION_CHECK_DST(dst, dstw); 1069 FUNCTION_CHECK_OP1(); 1070 #endif 1071 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) 1072 if (SLJIT_UNLIKELY(!!compiler->verbose)) { 1073 if (GET_OPCODE(op) <= SLJIT_MOVU_P) 1074 { 1075 fprintf(compiler->verbose, " mov%s%s%s ", (GET_OPCODE(op) >= SLJIT_MOVU) ? "u" : "", 1076 !(op & SLJIT_I32_OP) ? "" : "32", (op != SLJIT_MOV32 && op != SLJIT_MOVU32) ? op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE] : ""); 1077 } 1078 else 1079 { 1080 fprintf(compiler->verbose, " %s%s%s%s%s%s%s%s ", op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE], !(op & SLJIT_I32_OP) ? "" : "32", 1081 !(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_SET_U) ? "" : ".u", !(op & SLJIT_SET_S) ? "" : ".s", 1082 !(op & SLJIT_SET_O) ? "" : ".o", !(op & SLJIT_SET_C) ? "" : ".c", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k"); 1083 } 1084 1085 sljit_verbose_param(compiler, dst, dstw); 1086 fprintf(compiler->verbose, ", "); 1087 sljit_verbose_param(compiler, src, srcw); 1088 fprintf(compiler->verbose, "\n"); 1089 } 1090 #endif 1091 CHECK_RETURN_OK; 1092 } 1093 1094 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, 1095 sljit_s32 dst, sljit_sw dstw, 1096 sljit_s32 src1, sljit_sw src1w, 1097 sljit_s32 src2, sljit_sw src2w) 1098 { 1099 if (SLJIT_UNLIKELY(compiler->skip_checks)) { 1100 compiler->skip_checks = 0; 1101 CHECK_RETURN_OK; 1102 } 1103 1104 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) 1105 CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_ADD && GET_OPCODE(op) <= SLJIT_ASHR); 1106 FUNCTION_CHECK_OP(); 1107 FUNCTION_CHECK_SRC(src1, src1w); 1108 FUNCTION_CHECK_SRC(src2, src2w); 1109 FUNCTION_CHECK_DST(dst, dstw); 1110 #endif 1111 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) 1112 if (SLJIT_UNLIKELY(!!compiler->verbose)) { 1113 fprintf(compiler->verbose, " %s%s%s%s%s%s%s%s ", op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE], !(op & SLJIT_I32_OP) ? "" : "32", 1114 !(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_SET_U) ? "" : ".u", !(op & SLJIT_SET_S) ? "" : ".s", 1115 !(op & SLJIT_SET_O) ? "" : ".o", !(op & SLJIT_SET_C) ? "" : ".c", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k"); 1116 sljit_verbose_param(compiler, dst, dstw); 1117 fprintf(compiler->verbose, ", "); 1118 sljit_verbose_param(compiler, src1, src1w); 1119 fprintf(compiler->verbose, ", "); 1120 sljit_verbose_param(compiler, src2, src2w); 1121 fprintf(compiler->verbose, "\n"); 1122 } 1123 #endif 1124 CHECK_RETURN_OK; 1125 } 1126 1127 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_register_index(sljit_s32 reg) 1128 { 1129 SLJIT_UNUSED_ARG(reg); 1130 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) 1131 CHECK_ARGUMENT(reg > 0 && reg <= SLJIT_NUMBER_OF_REGISTERS); 1132 #endif 1133 CHECK_RETURN_OK; 1134 } 1135 1136 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_float_register_index(sljit_s32 reg) 1137 { 1138 SLJIT_UNUSED_ARG(reg); 1139 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) 1140 CHECK_ARGUMENT(reg > 0 && reg <= SLJIT_NUMBER_OF_FLOAT_REGISTERS); 1141 #endif 1142 CHECK_RETURN_OK; 1143 } 1144 1145 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_custom(struct sljit_compiler *compiler, 1146 void *instruction, sljit_s32 size) 1147 { 1148 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) 1149 int i; 1150 #endif 1151 1152 SLJIT_UNUSED_ARG(compiler); 1153 1154 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) 1155 CHECK_ARGUMENT(instruction); 1156 #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) 1157 CHECK_ARGUMENT(size > 0 && size < 16); 1158 #elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) 1159 CHECK_ARGUMENT((size == 2 && (((sljit_sw)instruction) & 0x1) == 0) 1160 || (size == 4 && (((sljit_sw)instruction) & 0x3) == 0)); 1161 #else 1162 CHECK_ARGUMENT(size == 4 && (((sljit_sw)instruction) & 0x3) == 0); 1163 #endif 1164 1165 #endif 1166 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) 1167 if (SLJIT_UNLIKELY(!!compiler->verbose)) { 1168 fprintf(compiler->verbose, " op_custom"); 1169 for (i = 0; i < size; i++) 1170 fprintf(compiler->verbose, " 0x%x", ((sljit_u8*)instruction)[i]); 1171 fprintf(compiler->verbose, "\n"); 1172 } 1173 #endif 1174 CHECK_RETURN_OK; 1175 } 1176 1177 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, 1178 sljit_s32 dst, sljit_sw dstw, 1179 sljit_s32 src, sljit_sw srcw) 1180 { 1181 if (SLJIT_UNLIKELY(compiler->skip_checks)) { 1182 compiler->skip_checks = 0; 1183 CHECK_RETURN_OK; 1184 } 1185 1186 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) 1187 CHECK_ARGUMENT(sljit_is_fpu_available()); 1188 CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV_F64 && GET_OPCODE(op) <= SLJIT_ABS_F64); 1189 FUNCTION_CHECK_FOP(); 1190 FUNCTION_FCHECK(src, srcw); 1191 FUNCTION_FCHECK(dst, dstw); 1192 #endif 1193 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) 1194 if (SLJIT_UNLIKELY(!!compiler->verbose)) { 1195 if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32) 1196 fprintf(compiler->verbose, " %s%s ", fop1_names[SLJIT_CONV_F64_FROM_F32 - SLJIT_FOP1_BASE], 1197 (op & SLJIT_F32_OP) ? ".f32.from.f64" : ".f64.from.f32"); 1198 else 1199 fprintf(compiler->verbose, " %s%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE], 1200 (op & SLJIT_F32_OP) ? ".f32" : ".f64"); 1201 1202 sljit_verbose_fparam(compiler, dst, dstw); 1203 fprintf(compiler->verbose, ", "); 1204 sljit_verbose_fparam(compiler, src, srcw); 1205 fprintf(compiler->verbose, "\n"); 1206 } 1207 #endif 1208 CHECK_RETURN_OK; 1209 } 1210 1211 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op, 1212 sljit_s32 src1, sljit_sw src1w, 1213 sljit_s32 src2, sljit_sw src2w) 1214 { 1215 if (SLJIT_UNLIKELY(compiler->skip_checks)) { 1216 compiler->skip_checks = 0; 1217 CHECK_RETURN_OK; 1218 } 1219 1220 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) 1221 CHECK_ARGUMENT(sljit_is_fpu_available()); 1222 CHECK_ARGUMENT(GET_OPCODE(op) == SLJIT_CMP_F64); 1223 FUNCTION_CHECK_FOP(); 1224 FUNCTION_FCHECK(src1, src1w); 1225 FUNCTION_FCHECK(src2, src2w); 1226 #endif 1227 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) 1228 if (SLJIT_UNLIKELY(!!compiler->verbose)) { 1229 fprintf(compiler->verbose, " %s%s%s%s ", fop1_names[SLJIT_CMP_F64 - SLJIT_FOP1_BASE], (op & SLJIT_F32_OP) ? ".f32" : ".f64", 1230 (op & SLJIT_SET_E) ? ".e" : "", (op & SLJIT_SET_S) ? ".s" : ""); 1231 sljit_verbose_fparam(compiler, src1, src1w); 1232 fprintf(compiler->verbose, ", "); 1233 sljit_verbose_fparam(compiler, src2, src2w); 1234 fprintf(compiler->verbose, "\n"); 1235 } 1236 #endif 1237 CHECK_RETURN_OK; 1238 } 1239 1240 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op, 1241 sljit_s32 dst, sljit_sw dstw, 1242 sljit_s32 src, sljit_sw srcw) 1243 { 1244 if (SLJIT_UNLIKELY(compiler->skip_checks)) { 1245 compiler->skip_checks = 0; 1246 CHECK_RETURN_OK; 1247 } 1248 1249 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) 1250 CHECK_ARGUMENT(sljit_is_fpu_available()); 1251 CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_CONV_SW_FROM_F64 && GET_OPCODE(op) <= SLJIT_CONV_S32_FROM_F64); 1252 FUNCTION_CHECK_FOP(); 1253 FUNCTION_FCHECK(src, srcw); 1254 FUNCTION_CHECK_DST(dst, dstw); 1255 #endif 1256 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) 1257 if (SLJIT_UNLIKELY(!!compiler->verbose)) { 1258 fprintf(compiler->verbose, " %s%s.from%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE], 1259 (GET_OPCODE(op) == SLJIT_CONV_S32_FROM_F64) ? ".s32" : ".sw", 1260 (op & SLJIT_F32_OP) ? ".f32" : ".f64"); 1261 sljit_verbose_param(compiler, dst, dstw); 1262 fprintf(compiler->verbose, ", "); 1263 sljit_verbose_fparam(compiler, src, srcw); 1264 fprintf(compiler->verbose, "\n"); 1265 } 1266 #endif 1267 CHECK_RETURN_OK; 1268 } 1269 1270 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, 1271 sljit_s32 dst, sljit_sw dstw, 1272 sljit_s32 src, sljit_sw srcw) 1273 { 1274 if (SLJIT_UNLIKELY(compiler->skip_checks)) { 1275 compiler->skip_checks = 0; 1276 CHECK_RETURN_OK; 1277 } 1278 1279 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) 1280 CHECK_ARGUMENT(sljit_is_fpu_available()); 1281 CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_CONV_F64_FROM_SW && GET_OPCODE(op) <= SLJIT_CONV_F64_FROM_S32); 1282 FUNCTION_CHECK_FOP(); 1283 FUNCTION_CHECK_SRC(src, srcw); 1284 FUNCTION_FCHECK(dst, dstw); 1285 #endif 1286 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) 1287 if (SLJIT_UNLIKELY(!!compiler->verbose)) { 1288 fprintf(compiler->verbose, " %s%s.from%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE], 1289 (op & SLJIT_F32_OP) ? ".f32" : ".f64", 1290 (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) ? ".s32" : ".sw"); 1291 sljit_verbose_fparam(compiler, dst, dstw); 1292 fprintf(compiler->verbose, ", "); 1293 sljit_verbose_param(compiler, src, srcw); 1294 fprintf(compiler->verbose, "\n"); 1295 } 1296 #endif 1297 CHECK_RETURN_OK; 1298 } 1299 1300 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op, 1301 sljit_s32 dst, sljit_sw dstw, 1302 sljit_s32 src1, sljit_sw src1w, 1303 sljit_s32 src2, sljit_sw src2w) 1304 { 1305 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) 1306 CHECK_ARGUMENT(sljit_is_fpu_available()); 1307 CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_ADD_F64 && GET_OPCODE(op) <= SLJIT_DIV_F64); 1308 FUNCTION_CHECK_FOP(); 1309 FUNCTION_FCHECK(src1, src1w); 1310 FUNCTION_FCHECK(src2, src2w); 1311 FUNCTION_FCHECK(dst, dstw); 1312 #endif 1313 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) 1314 if (SLJIT_UNLIKELY(!!compiler->verbose)) { 1315 fprintf(compiler->verbose, " %s%s ", fop2_names[GET_OPCODE(op) - SLJIT_FOP2_BASE], (op & SLJIT_F32_OP) ? ".f32" : ".f64"); 1316 sljit_verbose_fparam(compiler, dst, dstw); 1317 fprintf(compiler->verbose, ", "); 1318 sljit_verbose_fparam(compiler, src1, src1w); 1319 fprintf(compiler->verbose, ", "); 1320 sljit_verbose_fparam(compiler, src2, src2w); 1321 fprintf(compiler->verbose, "\n"); 1322 } 1323 #endif 1324 CHECK_RETURN_OK; 1325 } 1326 1327 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_label(struct sljit_compiler *compiler) 1328 { 1329 SLJIT_UNUSED_ARG(compiler); 1330 1331 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) 1332 if (SLJIT_UNLIKELY(!!compiler->verbose)) 1333 fprintf(compiler->verbose, "label:\n"); 1334 #endif 1335 CHECK_RETURN_OK; 1336 } 1337 1338 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type) 1339 { 1340 if (SLJIT_UNLIKELY(compiler->skip_checks)) { 1341 compiler->skip_checks = 0; 1342 CHECK_RETURN_OK; 1343 } 1344 1345 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) 1346 CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_I32_OP))); 1347 CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_CALL3); 1348 CHECK_ARGUMENT((type & 0xff) < SLJIT_JUMP || !(type & SLJIT_I32_OP)); 1349 CHECK_ARGUMENT((type & 0xff) <= SLJIT_CALL0 || ((type & 0xff) - SLJIT_CALL0) <= compiler->scratches); 1350 #endif 1351 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) 1352 if (SLJIT_UNLIKELY(!!compiler->verbose)) 1353 fprintf(compiler->verbose, " jump%s %s%s\n", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", 1354 jump_names[type & 0xff], JUMP_POSTFIX(type)); 1355 #endif 1356 CHECK_RETURN_OK; 1357 } 1358 1359 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type, 1360 sljit_s32 src1, sljit_sw src1w, 1361 sljit_s32 src2, sljit_sw src2w) 1362 { 1363 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) 1364 CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_I32_OP))); 1365 CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_SIG_LESS_EQUAL); 1366 FUNCTION_CHECK_SRC(src1, src1w); 1367 FUNCTION_CHECK_SRC(src2, src2w); 1368 #endif 1369 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) 1370 if (SLJIT_UNLIKELY(!!compiler->verbose)) { 1371 fprintf(compiler->verbose, " cmp%s %s%s, ", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", 1372 jump_names[type & 0xff], (type & SLJIT_I32_OP) ? "32" : ""); 1373 sljit_verbose_param(compiler, src1, src1w); 1374 fprintf(compiler->verbose, ", "); 1375 sljit_verbose_param(compiler, src2, src2w); 1376 fprintf(compiler->verbose, "\n"); 1377 } 1378 #endif 1379 CHECK_RETURN_OK; 1380 } 1381 1382 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type, 1383 sljit_s32 src1, sljit_sw src1w, 1384 sljit_s32 src2, sljit_sw src2w) 1385 { 1386 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) 1387 CHECK_ARGUMENT(sljit_is_fpu_available()); 1388 CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_F32_OP))); 1389 CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL_F64 && (type & 0xff) <= SLJIT_ORDERED_F64); 1390 FUNCTION_FCHECK(src1, src1w); 1391 FUNCTION_FCHECK(src2, src2w); 1392 #endif 1393 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) 1394 if (SLJIT_UNLIKELY(!!compiler->verbose)) { 1395 fprintf(compiler->verbose, " fcmp%s %s%s, ", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", 1396 jump_names[type & 0xff], (type & SLJIT_F32_OP) ? ".f32" : ".f64"); 1397 sljit_verbose_fparam(compiler, src1, src1w); 1398 fprintf(compiler->verbose, ", "); 1399 sljit_verbose_fparam(compiler, src2, src2w); 1400 fprintf(compiler->verbose, "\n"); 1401 } 1402 #endif 1403 CHECK_RETURN_OK; 1404 } 1405 1406 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw) 1407 { 1408 if (SLJIT_UNLIKELY(compiler->skip_checks)) { 1409 compiler->skip_checks = 0; 1410 CHECK_RETURN_OK; 1411 } 1412 1413 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) 1414 CHECK_ARGUMENT(type >= SLJIT_JUMP && type <= SLJIT_CALL3); 1415 CHECK_ARGUMENT(type <= SLJIT_CALL0 || (type - SLJIT_CALL0) <= compiler->scratches); 1416 FUNCTION_CHECK_SRC(src, srcw); 1417 #endif 1418 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) 1419 if (SLJIT_UNLIKELY(!!compiler->verbose)) { 1420 fprintf(compiler->verbose, " ijump.%s ", jump_names[type]); 1421 sljit_verbose_param(compiler, src, srcw); 1422 fprintf(compiler->verbose, "\n"); 1423 } 1424 #endif 1425 CHECK_RETURN_OK; 1426 } 1427 1428 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op, 1429 sljit_s32 dst, sljit_sw dstw, 1430 sljit_s32 src, sljit_sw srcw, 1431 sljit_s32 type) 1432 { 1433 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) 1434 CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_I32_OP))); 1435 CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_ORDERED_F64); 1436 CHECK_ARGUMENT(op == SLJIT_MOV || GET_OPCODE(op) == SLJIT_MOV_U32 || GET_OPCODE(op) == SLJIT_MOV_S32 1437 || (GET_OPCODE(op) >= SLJIT_AND && GET_OPCODE(op) <= SLJIT_XOR)); 1438 CHECK_ARGUMENT((op & (SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C)) == 0); 1439 CHECK_ARGUMENT((op & (SLJIT_SET_E | SLJIT_KEEP_FLAGS)) != (SLJIT_SET_E | SLJIT_KEEP_FLAGS)); 1440 if (GET_OPCODE(op) < SLJIT_ADD) { 1441 CHECK_ARGUMENT(src == SLJIT_UNUSED && srcw == 0); 1442 } else { 1443 CHECK_ARGUMENT(src == dst && srcw == dstw); 1444 } 1445 FUNCTION_CHECK_DST(dst, dstw); 1446 #endif 1447 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) 1448 if (SLJIT_UNLIKELY(!!compiler->verbose)) { 1449 fprintf(compiler->verbose, " flags %s%s%s%s, ", 1450 !(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k", 1451 GET_OPCODE(op) < SLJIT_OP2_BASE ? "mov" : op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE], 1452 GET_OPCODE(op) < SLJIT_OP2_BASE ? op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE] : ((op & SLJIT_I32_OP) ? "32" : "")); 1453 sljit_verbose_param(compiler, dst, dstw); 1454 if (src != SLJIT_UNUSED) { 1455 fprintf(compiler->verbose, ", "); 1456 sljit_verbose_param(compiler, src, srcw); 1457 } 1458 fprintf(compiler->verbose, ", %s%s\n", jump_names[type & 0xff], JUMP_POSTFIX(type)); 1459 } 1460 #endif 1461 CHECK_RETURN_OK; 1462 } 1463 1464 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset) 1465 { 1466 SLJIT_UNUSED_ARG(offset); 1467 1468 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) 1469 FUNCTION_CHECK_DST(dst, dstw); 1470 #endif 1471 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) 1472 if (SLJIT_UNLIKELY(!!compiler->verbose)) { 1473 fprintf(compiler->verbose, " local_base "); 1474 sljit_verbose_param(compiler, dst, dstw); 1475 fprintf(compiler->verbose, ", #%" SLJIT_PRINT_D "d\n", offset); 1476 } 1477 #endif 1478 CHECK_RETURN_OK; 1479 } 1480 1481 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value) 1482 { 1483 SLJIT_UNUSED_ARG(init_value); 1484 1485 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) 1486 FUNCTION_CHECK_DST(dst, dstw); 1487 #endif 1488 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) 1489 if (SLJIT_UNLIKELY(!!compiler->verbose)) { 1490 fprintf(compiler->verbose, " const "); 1491 sljit_verbose_param(compiler, dst, dstw); 1492 fprintf(compiler->verbose, ", #%" SLJIT_PRINT_D "d\n", init_value); 1493 } 1494 #endif 1495 CHECK_RETURN_OK; 1496 } 1497 1498 #endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_VERBOSE */ 1499 1500 #define SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw) \ 1501 SLJIT_COMPILE_ASSERT(!(SLJIT_CONV_SW_FROM_F64 & 0x1) && !(SLJIT_CONV_F64_FROM_SW & 0x1), \ 1502 invalid_float_opcodes); \ 1503 if (GET_OPCODE(op) >= SLJIT_CONV_SW_FROM_F64 && GET_OPCODE(op) <= SLJIT_CMP_F64) { \ 1504 if (GET_OPCODE(op) == SLJIT_CMP_F64) { \ 1505 CHECK(check_sljit_emit_fop1_cmp(compiler, op, dst, dstw, src, srcw)); \ 1506 ADJUST_LOCAL_OFFSET(dst, dstw); \ 1507 ADJUST_LOCAL_OFFSET(src, srcw); \ 1508 return sljit_emit_fop1_cmp(compiler, op, dst, dstw, src, srcw); \ 1509 } \ 1510 if ((GET_OPCODE(op) | 0x1) == SLJIT_CONV_S32_FROM_F64) { \ 1511 CHECK(check_sljit_emit_fop1_conv_sw_from_f64(compiler, op, dst, dstw, src, srcw)); \ 1512 ADJUST_LOCAL_OFFSET(dst, dstw); \ 1513 ADJUST_LOCAL_OFFSET(src, srcw); \ 1514 return sljit_emit_fop1_conv_sw_from_f64(compiler, op, dst, dstw, src, srcw); \ 1515 } \ 1516 CHECK(check_sljit_emit_fop1_conv_f64_from_sw(compiler, op, dst, dstw, src, srcw)); \ 1517 ADJUST_LOCAL_OFFSET(dst, dstw); \ 1518 ADJUST_LOCAL_OFFSET(src, srcw); \ 1519 return sljit_emit_fop1_conv_f64_from_sw(compiler, op, dst, dstw, src, srcw); \ 1520 } \ 1521 CHECK(check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw)); \ 1522 ADJUST_LOCAL_OFFSET(dst, dstw); \ 1523 ADJUST_LOCAL_OFFSET(src, srcw); 1524 1525 static SLJIT_INLINE sljit_s32 emit_mov_before_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw) 1526 { 1527 /* Return if don't need to do anything. */ 1528 if (op == SLJIT_UNUSED) 1529 return SLJIT_SUCCESS; 1530 1531 #if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE) 1532 /* At the moment the pointer size is always equal to sljit_sw. May be changed in the future. */ 1533 if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_P)) 1534 return SLJIT_SUCCESS; 1535 #else 1536 if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_U32 || op == SLJIT_MOV_S32 || op == SLJIT_MOV_P)) 1537 return SLJIT_SUCCESS; 1538 #endif 1539 1540 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ 1541 || (defined SLJIT_VERBOSE && SLJIT_VERBOSE) 1542 compiler->skip_checks = 1; 1543 #endif 1544 return sljit_emit_op1(compiler, op, SLJIT_RETURN_REG, 0, src, srcw); 1545 } 1546 1547 /* CPU description section */ 1548 1549 #if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE) 1550 #define SLJIT_CPUINFO_PART1 " 32bit (" 1551 #elif (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE) 1552 #define SLJIT_CPUINFO_PART1 " 64bit (" 1553 #else 1554 #error "Internal error: CPU type info missing" 1555 #endif 1556 1557 #if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN) 1558 #define SLJIT_CPUINFO_PART2 "little endian + " 1559 #elif (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN) 1560 #define SLJIT_CPUINFO_PART2 "big endian + " 1561 #else 1562 #error "Internal error: CPU type info missing" 1563 #endif 1564 1565 #if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED) 1566 #define SLJIT_CPUINFO_PART3 "unaligned)" 1567 #else 1568 #define SLJIT_CPUINFO_PART3 "aligned)" 1569 #endif 1570 1571 #define SLJIT_CPUINFO SLJIT_CPUINFO_PART1 SLJIT_CPUINFO_PART2 SLJIT_CPUINFO_PART3 1572 1573 #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) 1574 # include "sljitNativeX86_common.c" 1575 #elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) 1576 # include "sljitNativeARM_32.c" 1577 #elif (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) 1578 # include "sljitNativeARM_32.c" 1579 #elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) 1580 # include "sljitNativeARM_T2_32.c" 1581 #elif (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) 1582 # include "sljitNativeARM_64.c" 1583 #elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) 1584 # include "sljitNativePPC_common.c" 1585 #elif (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) 1586 # include "sljitNativeMIPS_common.c" 1587 #elif (defined SLJIT_CONFIG_SPARC && SLJIT_CONFIG_SPARC) 1588 # include "sljitNativeSPARC_common.c" 1589 #elif (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) 1590 # include "sljitNativeTILEGX_64.c" 1591 #endif 1592 1593 #if !(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) 1594 1595 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type, 1596 sljit_s32 src1, sljit_sw src1w, 1597 sljit_s32 src2, sljit_sw src2w) 1598 { 1599 /* Default compare for most architectures. */ 1600 sljit_s32 flags, tmp_src, condition; 1601 sljit_sw tmp_srcw; 1602 1603 CHECK_ERROR_PTR(); 1604 CHECK_PTR(check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w)); 1605 1606 condition = type & 0xff; 1607 #if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) 1608 if ((condition == SLJIT_EQUAL || condition == SLJIT_NOT_EQUAL)) { 1609 if ((src1 & SLJIT_IMM) && !src1w) { 1610 src1 = src2; 1611 src1w = src2w; 1612 src2 = SLJIT_IMM; 1613 src2w = 0; 1614 } 1615 if ((src2 & SLJIT_IMM) && !src2w) 1616 return emit_cmp_to0(compiler, type, src1, src1w); 1617 } 1618 #endif 1619 1620 if (SLJIT_UNLIKELY((src1 & SLJIT_IMM) && !(src2 & SLJIT_IMM))) { 1621 /* Immediate is prefered as second argument by most architectures. */ 1622 switch (condition) { 1623 case SLJIT_LESS: 1624 condition = SLJIT_GREATER; 1625 break; 1626 case SLJIT_GREATER_EQUAL: 1627 condition = SLJIT_LESS_EQUAL; 1628 break; 1629 case SLJIT_GREATER: 1630 condition = SLJIT_LESS; 1631 break; 1632 case SLJIT_LESS_EQUAL: 1633 condition = SLJIT_GREATER_EQUAL; 1634 break; 1635 case SLJIT_SIG_LESS: 1636 condition = SLJIT_SIG_GREATER; 1637 break; 1638 case SLJIT_SIG_GREATER_EQUAL: 1639 condition = SLJIT_SIG_LESS_EQUAL; 1640 break; 1641 case SLJIT_SIG_GREATER: 1642 condition = SLJIT_SIG_LESS; 1643 break; 1644 case SLJIT_SIG_LESS_EQUAL: 1645 condition = SLJIT_SIG_GREATER_EQUAL; 1646 break; 1647 } 1648 type = condition | (type & (SLJIT_I32_OP | SLJIT_REWRITABLE_JUMP)); 1649 tmp_src = src1; 1650 src1 = src2; 1651 src2 = tmp_src; 1652 tmp_srcw = src1w; 1653 src1w = src2w; 1654 src2w = tmp_srcw; 1655 } 1656 1657 if (condition <= SLJIT_NOT_ZERO) 1658 flags = SLJIT_SET_E; 1659 else if (condition <= SLJIT_LESS_EQUAL) 1660 flags = SLJIT_SET_U; 1661 else 1662 flags = SLJIT_SET_S; 1663 1664 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ 1665 || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) 1666 compiler->skip_checks = 1; 1667 #endif 1668 PTR_FAIL_IF(sljit_emit_op2(compiler, SLJIT_SUB | flags | (type & SLJIT_I32_OP), 1669 SLJIT_UNUSED, 0, src1, src1w, src2, src2w)); 1670 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ 1671 || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) 1672 compiler->skip_checks = 1; 1673 #endif 1674 return sljit_emit_jump(compiler, condition | (type & SLJIT_REWRITABLE_JUMP)); 1675 } 1676 1677 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type, 1678 sljit_s32 src1, sljit_sw src1w, 1679 sljit_s32 src2, sljit_sw src2w) 1680 { 1681 sljit_s32 flags, condition; 1682 1683 CHECK_ERROR_PTR(); 1684 CHECK_PTR(check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w)); 1685 1686 condition = type & 0xff; 1687 flags = (condition <= SLJIT_NOT_EQUAL_F64) ? SLJIT_SET_E : SLJIT_SET_S; 1688 if (type & SLJIT_F32_OP) 1689 flags |= SLJIT_F32_OP; 1690 1691 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ 1692 || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) 1693 compiler->skip_checks = 1; 1694 #endif 1695 sljit_emit_fop1(compiler, SLJIT_CMP_F64 | flags, src1, src1w, src2, src2w); 1696 1697 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ 1698 || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) 1699 compiler->skip_checks = 1; 1700 #endif 1701 return sljit_emit_jump(compiler, condition | (type & SLJIT_REWRITABLE_JUMP)); 1702 } 1703 1704 #endif 1705 1706 #if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) 1707 1708 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset) 1709 { 1710 CHECK_ERROR(); 1711 CHECK(check_sljit_get_local_base(compiler, dst, dstw, offset)); 1712 1713 ADJUST_LOCAL_OFFSET(SLJIT_MEM1(SLJIT_SP), offset); 1714 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ 1715 || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) 1716 compiler->skip_checks = 1; 1717 #endif 1718 if (offset != 0) 1719 return sljit_emit_op2(compiler, SLJIT_ADD | SLJIT_KEEP_FLAGS, dst, dstw, SLJIT_SP, 0, SLJIT_IMM, offset); 1720 return sljit_emit_op1(compiler, SLJIT_MOV, dst, dstw, SLJIT_SP, 0); 1721 } 1722 1723 #endif 1724 1725 #else /* SLJIT_CONFIG_UNSUPPORTED */ 1726 1727 /* Empty function bodies for those machines, which are not (yet) supported. */ 1728 1729 SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void) 1730 { 1731 return "unsupported"; 1732 } 1733 1734 SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void) 1735 { 1736 SLJIT_ASSERT_STOP(); 1737 return NULL; 1738 } 1739 1740 SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler) 1741 { 1742 SLJIT_UNUSED_ARG(compiler); 1743 SLJIT_ASSERT_STOP(); 1744 } 1745 1746 SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_s32 size) 1747 { 1748 SLJIT_UNUSED_ARG(compiler); 1749 SLJIT_UNUSED_ARG(size); 1750 SLJIT_ASSERT_STOP(); 1751 return NULL; 1752 } 1753 1754 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) 1755 SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose) 1756 { 1757 SLJIT_UNUSED_ARG(compiler); 1758 SLJIT_UNUSED_ARG(verbose); 1759 SLJIT_ASSERT_STOP(); 1760 } 1761 #endif 1762 1763 SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) 1764 { 1765 SLJIT_UNUSED_ARG(compiler); 1766 SLJIT_ASSERT_STOP(); 1767 return NULL; 1768 } 1769 1770 SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code) 1771 { 1772 SLJIT_UNUSED_ARG(code); 1773 SLJIT_ASSERT_STOP(); 1774 } 1775 1776 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, 1777 sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, 1778 sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) 1779 { 1780 SLJIT_UNUSED_ARG(compiler); 1781 SLJIT_UNUSED_ARG(options); 1782 SLJIT_UNUSED_ARG(args); 1783 SLJIT_UNUSED_ARG(scratches); 1784 SLJIT_UNUSED_ARG(saveds); 1785 SLJIT_UNUSED_ARG(fscratches); 1786 SLJIT_UNUSED_ARG(fsaveds); 1787 SLJIT_UNUSED_ARG(local_size); 1788 SLJIT_ASSERT_STOP(); 1789 return SLJIT_ERR_UNSUPPORTED; 1790 } 1791 1792 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, 1793 sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, 1794 sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) 1795 { 1796 SLJIT_UNUSED_ARG(compiler); 1797 SLJIT_UNUSED_ARG(options); 1798 SLJIT_UNUSED_ARG(args); 1799 SLJIT_UNUSED_ARG(scratches); 1800 SLJIT_UNUSED_ARG(saveds); 1801 SLJIT_UNUSED_ARG(fscratches); 1802 SLJIT_UNUSED_ARG(fsaveds); 1803 SLJIT_UNUSED_ARG(local_size); 1804 SLJIT_ASSERT_STOP(); 1805 return SLJIT_ERR_UNSUPPORTED; 1806 } 1807 1808 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw) 1809 { 1810 SLJIT_UNUSED_ARG(compiler); 1811 SLJIT_UNUSED_ARG(op); 1812 SLJIT_UNUSED_ARG(src); 1813 SLJIT_UNUSED_ARG(srcw); 1814 SLJIT_ASSERT_STOP(); 1815 return SLJIT_ERR_UNSUPPORTED; 1816 } 1817 1818 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) 1819 { 1820 SLJIT_UNUSED_ARG(compiler); 1821 SLJIT_UNUSED_ARG(dst); 1822 SLJIT_UNUSED_ARG(dstw); 1823 SLJIT_ASSERT_STOP(); 1824 return SLJIT_ERR_UNSUPPORTED; 1825 } 1826 1827 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) 1828 { 1829 SLJIT_UNUSED_ARG(compiler); 1830 SLJIT_UNUSED_ARG(src); 1831 SLJIT_UNUSED_ARG(srcw); 1832 SLJIT_ASSERT_STOP(); 1833 return SLJIT_ERR_UNSUPPORTED; 1834 } 1835 1836 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) 1837 { 1838 SLJIT_UNUSED_ARG(compiler); 1839 SLJIT_UNUSED_ARG(op); 1840 SLJIT_ASSERT_STOP(); 1841 return SLJIT_ERR_UNSUPPORTED; 1842 } 1843 1844 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, 1845 sljit_s32 dst, sljit_sw dstw, 1846 sljit_s32 src, sljit_sw srcw) 1847 { 1848 SLJIT_UNUSED_ARG(compiler); 1849 SLJIT_UNUSED_ARG(op); 1850 SLJIT_UNUSED_ARG(dst); 1851 SLJIT_UNUSED_ARG(dstw); 1852 SLJIT_UNUSED_ARG(src); 1853 SLJIT_UNUSED_ARG(srcw); 1854 SLJIT_ASSERT_STOP(); 1855 return SLJIT_ERR_UNSUPPORTED; 1856 } 1857 1858 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, 1859 sljit_s32 dst, sljit_sw dstw, 1860 sljit_s32 src1, sljit_sw src1w, 1861 sljit_s32 src2, sljit_sw src2w) 1862 { 1863 SLJIT_UNUSED_ARG(compiler); 1864 SLJIT_UNUSED_ARG(op); 1865 SLJIT_UNUSED_ARG(dst); 1866 SLJIT_UNUSED_ARG(dstw); 1867 SLJIT_UNUSED_ARG(src1); 1868 SLJIT_UNUSED_ARG(src1w); 1869 SLJIT_UNUSED_ARG(src2); 1870 SLJIT_UNUSED_ARG(src2w); 1871 SLJIT_ASSERT_STOP(); 1872 return SLJIT_ERR_UNSUPPORTED; 1873 } 1874 1875 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) 1876 { 1877 SLJIT_ASSERT_STOP(); 1878 return reg; 1879 } 1880 1881 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, 1882 void *instruction, sljit_s32 size) 1883 { 1884 SLJIT_UNUSED_ARG(compiler); 1885 SLJIT_UNUSED_ARG(instruction); 1886 SLJIT_UNUSED_ARG(size); 1887 SLJIT_ASSERT_STOP(); 1888 return SLJIT_ERR_UNSUPPORTED; 1889 } 1890 1891 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void) 1892 { 1893 SLJIT_ASSERT_STOP(); 1894 return 0; 1895 } 1896 1897 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, 1898 sljit_s32 dst, sljit_sw dstw, 1899 sljit_s32 src, sljit_sw srcw) 1900 { 1901 SLJIT_UNUSED_ARG(compiler); 1902 SLJIT_UNUSED_ARG(op); 1903 SLJIT_UNUSED_ARG(dst); 1904 SLJIT_UNUSED_ARG(dstw); 1905 SLJIT_UNUSED_ARG(src); 1906 SLJIT_UNUSED_ARG(srcw); 1907 SLJIT_ASSERT_STOP(); 1908 return SLJIT_ERR_UNSUPPORTED; 1909 } 1910 1911 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op, 1912 sljit_s32 dst, sljit_sw dstw, 1913 sljit_s32 src1, sljit_sw src1w, 1914 sljit_s32 src2, sljit_sw src2w) 1915 { 1916 SLJIT_UNUSED_ARG(compiler); 1917 SLJIT_UNUSED_ARG(op); 1918 SLJIT_UNUSED_ARG(dst); 1919 SLJIT_UNUSED_ARG(dstw); 1920 SLJIT_UNUSED_ARG(src1); 1921 SLJIT_UNUSED_ARG(src1w); 1922 SLJIT_UNUSED_ARG(src2); 1923 SLJIT_UNUSED_ARG(src2w); 1924 SLJIT_ASSERT_STOP(); 1925 return SLJIT_ERR_UNSUPPORTED; 1926 } 1927 1928 SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler) 1929 { 1930 SLJIT_UNUSED_ARG(compiler); 1931 SLJIT_ASSERT_STOP(); 1932 return NULL; 1933 } 1934 1935 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type) 1936 { 1937 SLJIT_UNUSED_ARG(compiler); 1938 SLJIT_UNUSED_ARG(type); 1939 SLJIT_ASSERT_STOP(); 1940 return NULL; 1941 } 1942 1943 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type, 1944 sljit_s32 src1, sljit_sw src1w, 1945 sljit_s32 src2, sljit_sw src2w) 1946 { 1947 SLJIT_UNUSED_ARG(compiler); 1948 SLJIT_UNUSED_ARG(type); 1949 SLJIT_UNUSED_ARG(src1); 1950 SLJIT_UNUSED_ARG(src1w); 1951 SLJIT_UNUSED_ARG(src2); 1952 SLJIT_UNUSED_ARG(src2w); 1953 SLJIT_ASSERT_STOP(); 1954 return NULL; 1955 } 1956 1957 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type, 1958 sljit_s32 src1, sljit_sw src1w, 1959 sljit_s32 src2, sljit_sw src2w) 1960 { 1961 SLJIT_UNUSED_ARG(compiler); 1962 SLJIT_UNUSED_ARG(type); 1963 SLJIT_UNUSED_ARG(src1); 1964 SLJIT_UNUSED_ARG(src1w); 1965 SLJIT_UNUSED_ARG(src2); 1966 SLJIT_UNUSED_ARG(src2w); 1967 SLJIT_ASSERT_STOP(); 1968 return NULL; 1969 } 1970 1971 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label) 1972 { 1973 SLJIT_UNUSED_ARG(jump); 1974 SLJIT_UNUSED_ARG(label); 1975 SLJIT_ASSERT_STOP(); 1976 } 1977 1978 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target) 1979 { 1980 SLJIT_UNUSED_ARG(jump); 1981 SLJIT_UNUSED_ARG(target); 1982 SLJIT_ASSERT_STOP(); 1983 } 1984 1985 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw) 1986 { 1987 SLJIT_UNUSED_ARG(compiler); 1988 SLJIT_UNUSED_ARG(type); 1989 SLJIT_UNUSED_ARG(src); 1990 SLJIT_UNUSED_ARG(srcw); 1991 SLJIT_ASSERT_STOP(); 1992 return SLJIT_ERR_UNSUPPORTED; 1993 } 1994 1995 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op, 1996 sljit_s32 dst, sljit_sw dstw, 1997 sljit_s32 src, sljit_sw srcw, 1998 sljit_s32 type) 1999 { 2000 SLJIT_UNUSED_ARG(compiler); 2001 SLJIT_UNUSED_ARG(op); 2002 SLJIT_UNUSED_ARG(dst); 2003 SLJIT_UNUSED_ARG(dstw); 2004 SLJIT_UNUSED_ARG(src); 2005 SLJIT_UNUSED_ARG(srcw); 2006 SLJIT_UNUSED_ARG(type); 2007 SLJIT_ASSERT_STOP(); 2008 return SLJIT_ERR_UNSUPPORTED; 2009 } 2010 2011 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset) 2012 { 2013 SLJIT_UNUSED_ARG(compiler); 2014 SLJIT_UNUSED_ARG(dst); 2015 SLJIT_UNUSED_ARG(dstw); 2016 SLJIT_UNUSED_ARG(offset); 2017 SLJIT_ASSERT_STOP(); 2018 return SLJIT_ERR_UNSUPPORTED; 2019 } 2020 2021 SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw initval) 2022 { 2023 SLJIT_UNUSED_ARG(compiler); 2024 SLJIT_UNUSED_ARG(dst); 2025 SLJIT_UNUSED_ARG(dstw); 2026 SLJIT_UNUSED_ARG(initval); 2027 SLJIT_ASSERT_STOP(); 2028 return NULL; 2029 } 2030 2031 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) 2032 { 2033 SLJIT_UNUSED_ARG(addr); 2034 SLJIT_UNUSED_ARG(new_addr); 2035 SLJIT_ASSERT_STOP(); 2036 } 2037 2038 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) 2039 { 2040 SLJIT_UNUSED_ARG(addr); 2041 SLJIT_UNUSED_ARG(new_constant); 2042 SLJIT_ASSERT_STOP(); 2043 } 2044 2045 #endif 2046