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