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@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 351static sljit_s32 compiler_initialized = 0; 352/* A thread safe initialization. */ 353static void init_compiler(void); 354#endif 355 356SLJIT_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 441SLJIT_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 468SLJIT_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) 475SLJIT_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) 481SLJIT_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 488SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code) 489{ 490 SLJIT_FREE_EXEC(code); 491} 492#endif 493 494SLJIT_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 503SLJIT_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 512SLJIT_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 528static 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 547static 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 566SLJIT_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 582static 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 598static 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 615static 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 632static 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 643static 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 654static 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 750SLJIT_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 824static 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 829static 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 837static 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 843static 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 849static 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 857static 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 883static 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 903static 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 930static 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 955static 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 981static 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 997static 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 1013static 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 1035static 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 1114static 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 1186static 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 1195static 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 1204static 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 1238static 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 1272static 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 1310static 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 1340static 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 1370static 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 1397static 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 1412static 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 1442static 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 1466static 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 1491static 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 1517static 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 1560static 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 1577static 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 1621static 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 1691SLJIT_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 1774SLJIT_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 1796SLJIT_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 1817SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void) 1818{ 1819 return "unsupported"; 1820} 1821 1822SLJIT_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 1829SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler) 1830{ 1831 SLJIT_UNUSED_ARG(compiler); 1832 SLJIT_UNREACHABLE(); 1833} 1834 1835SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compiler *compiler) 1836{ 1837 SLJIT_UNUSED_ARG(compiler); 1838 SLJIT_UNREACHABLE(); 1839} 1840 1841SLJIT_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) 1850SLJIT_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 1858SLJIT_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 1865SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code) 1866{ 1867 SLJIT_UNUSED_ARG(code); 1868 SLJIT_UNREACHABLE(); 1869} 1870 1871SLJIT_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 1887SLJIT_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 1903SLJIT_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 1913SLJIT_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 1922SLJIT_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 1931SLJIT_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 1939SLJIT_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 1953SLJIT_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 1970SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) 1971{ 1972 SLJIT_UNREACHABLE(); 1973 return reg; 1974} 1975 1976SLJIT_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 1986SLJIT_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 1992SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void) 1993{ 1994 SLJIT_UNREACHABLE(); 1995 return 0; 1996} 1997 1998SLJIT_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 2012SLJIT_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 2029SLJIT_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 2036SLJIT_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 2044SLJIT_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 2058SLJIT_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 2072SLJIT_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 2079SLJIT_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 2086SLJIT_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 2096SLJIT_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 2112SLJIT_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 2122SLJIT_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 2132SLJIT_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 2140SLJIT_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