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