diff options
author | zherczeg <zherczeg@2f5784b3-3f2a-0410-8824-cb99058d5e15> | 2012-11-09 08:13:13 +0000 |
---|---|---|
committer | zherczeg <zherczeg@2f5784b3-3f2a-0410-8824-cb99058d5e15> | 2012-11-09 08:13:13 +0000 |
commit | d6d9c5b73c7a6d27127b1069daff6f7291b10788 (patch) | |
tree | 21d9a3218de640c76cde40d5daea03526bb89809 | |
parent | 234fdebdfcebbbdd1b00d2680a66c736585da759 (diff) | |
download | pcre-d6d9c5b73c7a6d27127b1069daff6f7291b10788.tar.gz |
Large JIT compiler update again.
git-svn-id: svn://vcs.exim.org/pcre/code/trunk@1215 2f5784b3-3f2a-0410-8824-cb99058d5e15
-rw-r--r-- | pcre_jit_compile.c | 94 | ||||
-rw-r--r-- | sljit/sljitConfigInternal.h | 20 | ||||
-rw-r--r-- | sljit/sljitLir.c | 165 | ||||
-rw-r--r-- | sljit/sljitLir.h | 54 | ||||
-rw-r--r-- | sljit/sljitNativeARM_Thumb2.c | 142 | ||||
-rw-r--r-- | sljit/sljitNativeARM_v5.c | 173 | ||||
-rw-r--r-- | sljit/sljitNativeMIPS_common.c | 131 | ||||
-rw-r--r-- | sljit/sljitNativePPC_common.c | 127 | ||||
-rw-r--r-- | sljit/sljitNativeSPARC_common.c | 118 | ||||
-rw-r--r-- | sljit/sljitNativeX86_32.c | 63 | ||||
-rw-r--r-- | sljit/sljitNativeX86_64.c | 74 | ||||
-rw-r--r-- | sljit/sljitNativeX86_common.c | 176 |
12 files changed, 728 insertions, 609 deletions
diff --git a/pcre_jit_compile.c b/pcre_jit_compile.c index a184a76..7b5b4ce 100644 --- a/pcre_jit_compile.c +++ b/pcre_jit_compile.c @@ -402,12 +402,12 @@ enum { /* Used for accessing the elements of the stack. */ #define STACK(i) ((-(i) - 1) * (int)sizeof(sljit_sw)) -#define TMP1 SLJIT_TEMPORARY_REG1 -#define TMP2 SLJIT_TEMPORARY_REG3 +#define TMP1 SLJIT_SCRATCH_REG1 +#define TMP2 SLJIT_SCRATCH_REG3 #define TMP3 SLJIT_TEMPORARY_EREG2 #define STR_PTR SLJIT_SAVED_REG1 #define STR_END SLJIT_SAVED_REG2 -#define STACK_TOP SLJIT_TEMPORARY_REG2 +#define STACK_TOP SLJIT_SCRATCH_REG2 #define STACK_LIMIT SLJIT_SAVED_REG3 #define ARGUMENTS SLJIT_SAVED_EREG1 #define CALL_COUNT SLJIT_SAVED_EREG2 @@ -1797,19 +1797,19 @@ struct sljit_label *loop; int i; /* At this point we can freely use all temporary registers. */ /* TMP1 returns with begin - 1. */ -OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1)); +OP2(SLJIT_SUB, SLJIT_SCRATCH_REG1, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1)); if (length < 8) { for (i = 0; i < length; i++) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_TEMPORARY_REG1, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_SCRATCH_REG1, 0); } else { - GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, OVECTOR_START - sizeof(sljit_sw)); - OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length); + GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, OVECTOR_START - sizeof(sljit_sw)); + OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, length); loop = LABEL(); - OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(sljit_sw), SLJIT_TEMPORARY_REG1, 0); - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1); + OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_SCRATCH_REG2), sizeof(sljit_sw), SLJIT_SCRATCH_REG1, 0); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 1); JUMPTO(SLJIT_C_NOT_ZERO, loop); } } @@ -1824,41 +1824,41 @@ struct sljit_jump *earlyexit; OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0); -OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0); +OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, ARGUMENTS, 0); if (common->mark_ptr != 0) - OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr); -OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount)); + OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr); +OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount)); if (common->mark_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_TEMPORARY_REG3, 0); -OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int)); -OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_SCRATCH_REG3, 0); +OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int)); +OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, begin)); GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START); /* Unlikely, but possible */ -earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0); +earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 0); loop = LABEL(); -OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_TEMPORARY_REG1, 0); +OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_SCRATCH_REG1, 0); OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_sw)); /* Copy the integer value to the output buffer */ #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, UCHAR_SHIFT); #endif -OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0); -OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1); +OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG3), sizeof(int), SLJIT_SAVED_REG2, 0); +OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG2, 0, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 1); JUMPTO(SLJIT_C_NOT_ZERO, loop); JUMPHERE(earlyexit); /* Calculate the return value, which is the maximum ovector value. */ if (topbracket > 1) { - GET_LOCAL_BASE(SLJIT_TEMPORARY_REG1, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_sw)); - OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1); + GET_LOCAL_BASE(SLJIT_SCRATCH_REG1, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_sw)); + OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, topbracket + 1); /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */ loop = LABEL(); - OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_sw)sizeof(sljit_sw))); - OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1); - CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG3, 0, loop); - OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0); + OP1(SLJIT_MOVU, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), -(2 * (sljit_sw)sizeof(sljit_sw))); + OP2(SLJIT_SUB, SLJIT_SCRATCH_REG2, 0, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 1); + CMPTO(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG3, 0, SLJIT_SAVED_REG3, 0, loop); + OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_SCRATCH_REG2, 0); } else OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1); @@ -1871,26 +1871,26 @@ DEFINE_COMPILER; SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2); SLJIT_ASSERT(common->start_used_ptr != 0 && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0)); -OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0); +OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, ARGUMENTS, 0); OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL); -OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount)); -CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, quit); +OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount)); +CMPTO(SLJIT_C_LESS, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 2, quit); /* Store match begin and end. */ -OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin)); -OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets)); -OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start); +OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, begin)); +OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, offsets)); +OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start); OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0); #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, UCHAR_SHIFT); #endif -OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0); +OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG2), sizeof(int), SLJIT_SAVED_REG2, 0); -OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0); +OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_SAVED_REG1, 0); #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 -OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, UCHAR_SHIFT); +OP2(SLJIT_ASHR, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, UCHAR_SHIFT); #endif -OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0); +OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG2), 0, SLJIT_SCRATCH_REG3, 0); JUMPTO(SLJIT_JUMP, quit); } @@ -4784,15 +4784,15 @@ if (withchecks && !common->jscript_compat) #if defined SUPPORT_UTF && defined SUPPORT_UCP if (common->utf && *cc == OP_REFI) { - SLJIT_ASSERT(TMP1 == SLJIT_TEMPORARY_REG1 && STACK_TOP == SLJIT_TEMPORARY_REG2 && TMP2 == SLJIT_TEMPORARY_REG3); + SLJIT_ASSERT(TMP1 == SLJIT_SCRATCH_REG1 && STACK_TOP == SLJIT_SCRATCH_REG2 && TMP2 == SLJIT_SCRATCH_REG3); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); if (withchecks) jump = CMP(SLJIT_C_EQUAL, TMP1, 0, TMP2, 0); /* Needed to save important temporary registers. */ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0); - OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, uchar_ptr), STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, uchar_ptr), STR_PTR, 0); sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp)); OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); if (common->mode == JIT_COMPILE) @@ -5765,12 +5765,12 @@ if (opcode == OP_COND || opcode == OP_SCOND) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size); - OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, (stacksize << 8) | (common->ovector_start / sizeof(sljit_sw))); - GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, 0); - OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table); + OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, SLJIT_IMM, (stacksize << 8) | (common->ovector_start / sizeof(sljit_sw))); + GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, 0); + OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, common->name_table); sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector)); OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1); - add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0)); + add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG1, 0, SLJIT_IMM, 0)); JUMPHERE(jump); matchingpath += 1 + IMM2_SIZE; @@ -5815,12 +5815,12 @@ if (opcode == OP_COND || opcode == OP_SCOND) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, GET2(common->start, common->currententry->start + 1 + LINK_SIZE)); - OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize); - GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, 0); - OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table); + OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, SLJIT_IMM, stacksize); + GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, 0); + OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, common->name_table); sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups)); OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1); - add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0)); + add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG1, 0, SLJIT_IMM, 0)); matchingpath += 1 + IMM2_SIZE; } } @@ -7949,7 +7949,7 @@ sljit_emit_enter(compiler, 1, 5, 5, private_data_size); /* Register init. */ reset_ovector(common, (re->top_bracket + 1) * 2); if (common->req_char_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr, SLJIT_TEMPORARY_REG1, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr, SLJIT_SCRATCH_REG1, 0); OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_SAVED_REG1, 0); OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1, 0); diff --git a/sljit/sljitConfigInternal.h b/sljit/sljitConfigInternal.h index cfff178..0b13203 100644 --- a/sljit/sljitConfigInternal.h +++ b/sljit/sljitConfigInternal.h @@ -413,17 +413,28 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr); #define SLJIT_FREE_EXEC(ptr) sljit_free_exec(ptr) #endif -#if (defined SLJIT_DEBUG && SLJIT_DEBUG) || (defined SLJIT_VERBOSE && SLJIT_VERBOSE) +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) #include <stdio.h> #endif #if (defined SLJIT_DEBUG && SLJIT_DEBUG) -/* Feel free to redefine these two macros. */ -#ifndef SLJIT_ASSERT +#if !defined(SLJIT_ASSERT) || !defined(SLJIT_ASSERT_STOP) + +/* SLJIT_HALT_PROCESS must halt the process. */ +#ifndef SLJIT_HALT_PROCESS +#include <stdlib.h> #define SLJIT_HALT_PROCESS() \ - *((sljit_si*)0) = 0 + abort(); +#endif /* !SLJIT_HALT_PROCESS */ + +#include <stdio.h> + +#endif /* !SLJIT_ASSERT || !SLJIT_ASSERT_STOP */ + +/* Feel free to redefine these two macros. */ +#ifndef SLJIT_ASSERT #define SLJIT_ASSERT(x) \ do { \ @@ -447,6 +458,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr); #else /* (defined SLJIT_DEBUG && SLJIT_DEBUG) */ +/* Forcing empty, but valid statements. */ #undef SLJIT_ASSERT #undef SLJIT_ASSERT_STOP diff --git a/sljit/sljitLir.c b/sljit/sljitLir.c index 24a469c..32af2fd 100644 --- a/sljit/sljitLir.c +++ b/sljit/sljitLir.c @@ -108,87 +108,87 @@ /* SLJIT_REWRITABLE_JUMP is 0x1000. */ #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - #define PATCH_MB 0x4 - #define PATCH_MW 0x8 +# define PATCH_MB 0x4 +# define PATCH_MW 0x8 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - #define PATCH_MD 0x10 +# define PATCH_MD 0x10 #endif #endif #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) - #define IS_BL 0x4 - #define PATCH_B 0x8 +# define IS_BL 0x4 +# define PATCH_B 0x8 #endif #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - #define CPOOL_SIZE 512 +# define CPOOL_SIZE 512 #endif #if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) - #define IS_COND 0x04 - #define IS_BL 0x08 +# define IS_COND 0x04 +# define IS_BL 0x08 /* cannot be encoded as branch */ - #define B_TYPE0 0x00 +# define B_TYPE0 0x00 /* conditional + imm8 */ - #define B_TYPE1 0x10 +# define B_TYPE1 0x10 /* conditional + imm20 */ - #define B_TYPE2 0x20 +# define B_TYPE2 0x20 /* IT + imm24 */ - #define B_TYPE3 0x30 +# define B_TYPE3 0x30 /* imm11 */ - #define B_TYPE4 0x40 +# define B_TYPE4 0x40 /* imm24 */ - #define B_TYPE5 0x50 +# define B_TYPE5 0x50 /* BL + imm24 */ - #define BL_TYPE6 0x60 +# define BL_TYPE6 0x60 /* 0xf00 cc code for branches */ #endif #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - #define UNCOND_B 0x04 - #define PATCH_B 0x08 - #define ABSOLUTE_B 0x10 +# define UNCOND_B 0x04 +# define PATCH_B 0x08 +# define ABSOLUTE_B 0x10 #endif #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) - #define IS_MOVABLE 0x04 - #define IS_JAL 0x08 - #define IS_BIT26_COND 0x10 - #define IS_BIT16_COND 0x20 +# define IS_MOVABLE 0x04 +# define IS_JAL 0x08 +# define IS_BIT26_COND 0x10 +# define IS_BIT16_COND 0x20 - #define IS_COND (IS_BIT26_COND | IS_BIT16_COND) +# define IS_COND (IS_BIT26_COND | IS_BIT16_COND) - #define PATCH_B 0x40 - #define PATCH_J 0x80 +# define PATCH_B 0x40 +# define PATCH_J 0x80 /* instruction types */ - #define MOVABLE_INS 0 +# define MOVABLE_INS 0 /* 1 - 31 last destination register */ /* no destination (i.e: store) */ - #define UNMOVABLE_INS 32 +# define UNMOVABLE_INS 32 /* FPU status register */ - #define FCSR_FCC 33 +# define FCSR_FCC 33 #endif #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) - #define IS_MOVABLE 0x04 - #define IS_COND 0x08 - #define IS_CALL 0x10 +# define IS_MOVABLE 0x04 +# define IS_COND 0x08 +# define IS_CALL 0x10 - #define PATCH_B 0x20 - #define PATCH_CALL 0x40 +# define PATCH_B 0x20 +# define PATCH_CALL 0x40 /* instruction types */ - #define MOVABLE_INS 0 +# define MOVABLE_INS 0 /* 1 - 31 last destination register */ /* no destination (i.e: store) */ - #define UNMOVABLE_INS 32 +# define UNMOVABLE_INS 32 - #define DST_INS_MASK 0xff +# define DST_INS_MASK 0xff /* ICC_SET is the same as SET_FLAGS. */ - #define ICC_IS_SET (1 << 23) - #define FCC_IS_SET (1 << 24) +# define ICC_IS_SET (1 << 23) +# define FCC_IS_SET (1 << 24) #endif #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) @@ -313,7 +313,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void) compiler->abuf->next = NULL; compiler->abuf->used_size = 0; - compiler->temporaries = -1; + compiler->scratches = -1; compiler->saveds = -1; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) @@ -577,11 +577,11 @@ static SLJIT_INLINE void set_const(struct sljit_const *const_, struct sljit_comp #define FUNCTION_CHECK_IS_REG(r) \ ((r) == SLJIT_UNUSED || \ - ((r) >= SLJIT_TEMPORARY_REG1 && (r) <= SLJIT_TEMPORARY_REG1 - 1 + compiler->temporaries) || \ + ((r) >= SLJIT_SCRATCH_REG1 && (r) <= SLJIT_SCRATCH_REG1 - 1 + compiler->scratches) || \ ((r) >= SLJIT_SAVED_REG1 && (r) <= SLJIT_SAVED_REG1 - 1 + compiler->saveds)) #define FUNCTION_CHECK_SRC(p, i) \ - SLJIT_ASSERT(compiler->temporaries != -1 && compiler->saveds != -1); \ + SLJIT_ASSERT(compiler->scratches != -1 && compiler->saveds != -1); \ if (FUNCTION_CHECK_IS_REG(p)) \ SLJIT_ASSERT((i) == 0 && (p) != SLJIT_UNUSED); \ else if ((p) == SLJIT_IMM) \ @@ -600,7 +600,7 @@ static SLJIT_INLINE void set_const(struct sljit_const *const_, struct sljit_comp SLJIT_ASSERT_STOP(); #define FUNCTION_CHECK_DST(p, i) \ - SLJIT_ASSERT(compiler->temporaries != -1 && compiler->saveds != -1); \ + SLJIT_ASSERT(compiler->scratches != -1 && compiler->saveds != -1); \ if (FUNCTION_CHECK_IS_REG(p)) \ SLJIT_ASSERT((i) == 0); \ else if ((p) == (SLJIT_MEM1(SLJIT_LOCALS_REG))) \ @@ -661,12 +661,12 @@ static char* freg_names[] = { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) #ifdef _WIN64 - #define SLJIT_PRINT_D "I64" +# define SLJIT_PRINT_D "I64" #else - #define SLJIT_PRINT_D "l" +# define SLJIT_PRINT_D "l" #endif #else - #define SLJIT_PRINT_D "" +# define SLJIT_PRINT_D "" #endif #define sljit_verbose_param(p, i) \ @@ -743,7 +743,7 @@ static char* jump_names[] = { (char*)"c_float_equal", (char*)"c_float_not_equal", (char*)"c_float_less", (char*)"c_float_greater_equal", (char*)"c_float_greater", (char*)"c_float_less_equal", - (char*)"c_float_nan", (char*)"c_float_not_nan", + (char*)"c_float_unordered", (char*)"c_float_ordered", (char*)"jump", (char*)"fast_call", (char*)"call0", (char*)"call1", (char*)"call2", (char*)"call3" }; @@ -773,32 +773,32 @@ static SLJIT_INLINE void check_sljit_generate_code(struct sljit_compiler *compil #endif } -static SLJIT_INLINE void check_sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si temporaries, sljit_si saveds, sljit_si local_size) +static SLJIT_INLINE void check_sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) { /* If debug and verbose are disabled, all arguments are unused. */ SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(args); - SLJIT_UNUSED_ARG(temporaries); + SLJIT_UNUSED_ARG(scratches); SLJIT_UNUSED_ARG(saveds); SLJIT_UNUSED_ARG(local_size); SLJIT_ASSERT(args >= 0 && args <= 3); - SLJIT_ASSERT(temporaries >= 0 && temporaries <= SLJIT_NO_TMP_REGISTERS); + SLJIT_ASSERT(scratches >= 0 && scratches <= SLJIT_NO_TMP_REGISTERS); SLJIT_ASSERT(saveds >= 0 && saveds <= SLJIT_NO_GEN_REGISTERS); SLJIT_ASSERT(args <= saveds); SLJIT_ASSERT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE); #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) - fprintf(compiler->verbose, " enter args=%d temporaries=%d saveds=%d local_size=%d\n", args, temporaries, saveds, local_size); + fprintf(compiler->verbose, " enter args=%d scratches=%d saveds=%d local_size=%d\n", args, scratches, saveds, local_size); #endif } -static SLJIT_INLINE void check_sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si temporaries, sljit_si saveds, sljit_si local_size) +static SLJIT_INLINE void check_sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) { /* If debug and verbose are disabled, all arguments are unused. */ SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(args); - SLJIT_UNUSED_ARG(temporaries); + SLJIT_UNUSED_ARG(scratches); SLJIT_UNUSED_ARG(saveds); SLJIT_UNUSED_ARG(local_size); @@ -810,13 +810,13 @@ static SLJIT_INLINE void check_sljit_set_context(struct sljit_compiler *compiler #endif SLJIT_ASSERT(args >= 0 && args <= 3); - SLJIT_ASSERT(temporaries >= 0 && temporaries <= SLJIT_NO_TMP_REGISTERS); + SLJIT_ASSERT(scratches >= 0 && scratches <= SLJIT_NO_TMP_REGISTERS); SLJIT_ASSERT(saveds >= 0 && saveds <= SLJIT_NO_GEN_REGISTERS); SLJIT_ASSERT(args <= saveds); SLJIT_ASSERT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE); #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) - fprintf(compiler->verbose, " set_context args=%d temporaries=%d saveds=%d local_size=%d\n", args, temporaries, saveds, local_size); + fprintf(compiler->verbose, " set_context args=%d scratches=%d saveds=%d local_size=%d\n", args, scratches, saveds, local_size); #endif } @@ -930,7 +930,8 @@ static SLJIT_INLINE void check_sljit_emit_op1(struct sljit_compiler *compiler, s #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s%s%s%s%s%s%s%s ", !(op & SLJIT_INT_OP) ? "" : "i", op_names[GET_OPCODE(op)], - !(op & SLJIT_SET_E) ? "" : "E", !(op & SLJIT_SET_S) ? "" : "S", !(op & SLJIT_SET_U) ? "" : "U", !(op & SLJIT_SET_O) ? "" : "O", !(op & SLJIT_SET_C) ? "" : "C", !(op & SLJIT_KEEP_FLAGS) ? "" : "K"); + !(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_SET_S) ? "" : ".s", !(op & SLJIT_SET_U) ? "" : ".u", + !(op & SLJIT_SET_O) ? "" : ".o", !(op & SLJIT_SET_C) ? "" : ".c", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k"); sljit_verbose_param(dst, dstw); fprintf(compiler->verbose, ", "); sljit_verbose_param(src, srcw); @@ -971,8 +972,8 @@ static SLJIT_INLINE void check_sljit_emit_op2(struct sljit_compiler *compiler, s #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s%s%s%s%s%s%s%s ", !(op & SLJIT_INT_OP) ? "" : "i", op_names[GET_OPCODE(op)], - !(op & SLJIT_SET_E) ? "" : "E", !(op & SLJIT_SET_S) ? "" : "S", !(op & SLJIT_SET_U) ? "" : "U", - !(op & SLJIT_SET_O) ? "" : "O", !(op & SLJIT_SET_C) ? "" : "C", !(op & SLJIT_KEEP_FLAGS) ? "" : "K"); + !(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_SET_S) ? "" : ".s", !(op & SLJIT_SET_U) ? "" : ".u", + !(op & SLJIT_SET_O) ? "" : ".o", !(op & SLJIT_SET_C) ? "" : ".c", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k"); sljit_verbose_param(dst, dstw); fprintf(compiler->verbose, ", "); sljit_verbose_param(src1, src1w); @@ -1027,7 +1028,7 @@ static SLJIT_INLINE void check_sljit_emit_fop1(struct sljit_compiler *compiler, #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s%s%s%s ", op_names[GET_OPCODE(op)], (op & SLJIT_SINGLE_OP) ? "s" : "d", - !(op & SLJIT_SET_E) ? "" : "E", !(op & SLJIT_SET_S) ? "" : "S"); + !(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_SET_S) ? "" : ".s"); sljit_verbose_fparam(dst, dstw); fprintf(compiler->verbose, ", "); sljit_verbose_fparam(src, srcw); @@ -1100,7 +1101,7 @@ static SLJIT_INLINE void check_sljit_emit_jump(struct sljit_compiler *compiler, SLJIT_ASSERT((type & 0xff) >= SLJIT_C_EQUAL && (type & 0xff) <= SLJIT_CALL3); #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) - fprintf(compiler->verbose, " jump%s <%s>\n", !(type & SLJIT_REWRITABLE_JUMP) ? "" : "R", jump_names[type & 0xff]); + fprintf(compiler->verbose, " jump%s<%s>\n", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", jump_names[type & 0xff]); #endif } @@ -1123,7 +1124,7 @@ static SLJIT_INLINE void check_sljit_emit_cmp(struct sljit_compiler *compiler, s #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " %scmp%s <%s> ", !(type & SLJIT_INT_OP) ? "" : "i", !(type & SLJIT_REWRITABLE_JUMP) ? "" : "R", jump_names[type & 0xff]); + fprintf(compiler->verbose, " %scmp%s<%s> ", !(type & SLJIT_INT_OP) ? "" : "i", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", jump_names[type & 0xff]); sljit_verbose_param(src1, src1w); fprintf(compiler->verbose, ", "); sljit_verbose_param(src2, src2w); @@ -1152,8 +1153,8 @@ static SLJIT_INLINE void check_sljit_emit_fcmp(struct sljit_compiler *compiler, #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " %scmpj%s <%s> ", (type & SLJIT_SINGLE_OP) ? "s" : "d", - !(type & SLJIT_REWRITABLE_JUMP) ? "" : "R", jump_names[type & 0xff]); + fprintf(compiler->verbose, " %scmp%s<%s> ", (type & SLJIT_SINGLE_OP) ? "s" : "d", + !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", jump_names[type & 0xff]); sljit_verbose_fparam(src1, src1w); fprintf(compiler->verbose, ", "); sljit_verbose_fparam(src2, src2w); @@ -1183,7 +1184,7 @@ static SLJIT_INLINE void check_sljit_emit_ijump(struct sljit_compiler *compiler, #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " ijump <%s> ", jump_names[type]); + fprintf(compiler->verbose, " ijump<%s> ", jump_names[type]); sljit_verbose_param(src, srcw); fprintf(compiler->verbose, "\n"); } @@ -1205,7 +1206,7 @@ static SLJIT_INLINE void check_sljit_emit_op_flags(struct sljit_compiler *compil SLJIT_UNUSED_ARG(type); SLJIT_ASSERT(type >= SLJIT_C_EQUAL && type < SLJIT_JUMP); - SLJIT_ASSERT(op == SLJIT_MOV || op == SLJIT_MOV_UI || op == SLJIT_MOV_SI + SLJIT_ASSERT(op == SLJIT_MOV || GET_OPCODE(op) == SLJIT_MOV_UI || GET_OPCODE(op) == SLJIT_MOV_SI || (GET_OPCODE(op) >= SLJIT_AND && GET_OPCODE(op) <= SLJIT_XOR)); SLJIT_ASSERT((op & (SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C)) == 0); SLJIT_ASSERT((op & (SLJIT_SET_E | SLJIT_KEEP_FLAGS)) != (SLJIT_SET_E | SLJIT_KEEP_FLAGS)); @@ -1219,8 +1220,8 @@ static SLJIT_INLINE void check_sljit_emit_op_flags(struct sljit_compiler *compil #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " %sop_flags%s%s <%s> ", !(op & SLJIT_INT_OP) ? "" : "i", - !(op & SLJIT_SET_E) ? "" : "E", !(op & SLJIT_KEEP_FLAGS) ? "" : "K", op_names[GET_OPCODE(op)]); + fprintf(compiler->verbose, " op_flags<%s%s%s%s> ", !(op & SLJIT_INT_OP) ? "" : "i", + op_names[GET_OPCODE(op)], !(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k"); sljit_verbose_param(dst, dstw); if (src != SLJIT_UNUSED) { fprintf(compiler->verbose, ", "); @@ -1318,23 +1319,23 @@ static SLJIT_INLINE sljit_si emit_mov_before_return(struct sljit_compiler *compi #define SLJIT_CPUINFO SLJIT_CPUINFO_PART1 SLJIT_CPUINFO_PART2 SLJIT_CPUINFO_PART3 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - #include "sljitNativeX86_common.c" +# include "sljitNativeX86_common.c" #elif (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - #include "sljitNativeX86_common.c" +# include "sljitNativeX86_common.c" #elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - #include "sljitNativeARM_v5.c" +# include "sljitNativeARM_v5.c" #elif (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) - #include "sljitNativeARM_v5.c" +# include "sljitNativeARM_v5.c" #elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) - #include "sljitNativeARM_Thumb2.c" +# include "sljitNativeARM_Thumb2.c" #elif (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) - #include "sljitNativePPC_common.c" +# include "sljitNativePPC_common.c" #elif (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - #include "sljitNativePPC_common.c" +# include "sljitNativePPC_common.c" #elif (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) - #include "sljitNativeMIPS_common.c" +# include "sljitNativeMIPS_common.c" #elif (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) - #include "sljitNativeSPARC_common.c" +# include "sljitNativeSPARC_common.c" #endif #if !(defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) @@ -1501,22 +1502,22 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code) SLJIT_ASSERT_STOP(); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si temporaries, sljit_si saveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(args); - SLJIT_UNUSED_ARG(temporaries); + SLJIT_UNUSED_ARG(scratches); SLJIT_UNUSED_ARG(saveds); SLJIT_UNUSED_ARG(local_size); SLJIT_ASSERT_STOP(); return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si temporaries, sljit_si saveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(args); - SLJIT_UNUSED_ARG(temporaries); + SLJIT_UNUSED_ARG(scratches); SLJIT_UNUSED_ARG(saveds); SLJIT_UNUSED_ARG(local_size); SLJIT_ASSERT_STOP(); @@ -1532,15 +1533,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_si args, sljit_si temporaries, sljit_si saveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(dst); SLJIT_UNUSED_ARG(dstw); - SLJIT_UNUSED_ARG(args); - SLJIT_UNUSED_ARG(temporaries); - SLJIT_UNUSED_ARG(saveds); - SLJIT_UNUSED_ARG(local_size); SLJIT_ASSERT_STOP(); return SLJIT_ERR_UNSUPPORTED; } diff --git a/sljit/sljitLir.h b/sljit/sljitLir.h index cc3a14f..87bfb6f 100644 --- a/sljit/sljitLir.h +++ b/sljit/sljitLir.h @@ -48,7 +48,7 @@ (including memory allocators). See sljitConfig.h Disadvantages: - Limited number of registers (only 6+4 integer registers, max 3+2 - temporary, max 3+2 saved and 4 floating point registers) + scratch, max 3+2 saved and 6 floating point registers) In practice: - This approach is very effective for interpreters - One of the saved registers typically points to a stack interface @@ -99,11 +99,11 @@ of sljitConfigInternal.h */ #define SLJIT_UNUSED 0 -/* Temporary (scratch) registers may not preserve their values across function calls. */ -#define SLJIT_TEMPORARY_REG1 1 -#define SLJIT_TEMPORARY_REG2 2 -#define SLJIT_TEMPORARY_REG3 3 -/* Note: Extra Registers cannot be used for memory addressing. */ +/* Scratch (temporary) registers may not preserve their values across function calls. */ +#define SLJIT_SCRATCH_REG1 1 +#define SLJIT_SCRATCH_REG2 2 +#define SLJIT_SCRATCH_REG3 3 +/* Note: extra registers cannot be used for memory addressing. */ /* Note: on x86-32, these registers are emulated (using stack loads & stores). */ #define SLJIT_TEMPORARY_EREG1 4 #define SLJIT_TEMPORARY_EREG2 5 @@ -112,7 +112,7 @@ of sljitConfigInternal.h */ #define SLJIT_SAVED_REG1 6 #define SLJIT_SAVED_REG2 7 #define SLJIT_SAVED_REG3 8 -/* Note: Extra Registers cannot be used for memory addressing. */ +/* Note: extra registers cannot be used for memory addressing. */ /* Note: on x86-32, these registers are emulated (using stack loads & stores). */ #define SLJIT_SAVED_EREG1 9 #define SLJIT_SAVED_EREG2 10 @@ -130,15 +130,15 @@ of sljitConfigInternal.h */ /* Return with machine word. */ -#define SLJIT_RETURN_REG SLJIT_TEMPORARY_REG1 +#define SLJIT_RETURN_REG SLJIT_SCRATCH_REG1 /* x86 prefers specific registers for special purposes. In case of shift - by register it supports only SLJIT_TEMPORARY_REG3 for shift argument + by register it supports only SLJIT_SCRATCH_REG3 for shift argument (which is the src2 argument of sljit_emit_op2). If another register is used, sljit must exchange data between registers which cause a minor slowdown. Other architectures has no such limitation. */ -#define SLJIT_PREF_SHIFT_REG SLJIT_TEMPORARY_REG3 +#define SLJIT_PREF_SHIFT_REG SLJIT_SCRATCH_REG3 /* --------------------------------------------------------------------- */ /* Floating point registers */ @@ -203,7 +203,7 @@ struct sljit_compiler { struct sljit_memory_fragment *abuf; /* Used local registers. */ - sljit_si temporaries; + sljit_si scratches; /* Used saved registers. */ sljit_si saveds; /* Local stack size. */ @@ -216,7 +216,7 @@ struct sljit_compiler { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) sljit_si args; sljit_si locals_offset; - sljit_si temporaries_start; + sljit_si scratches_start; sljit_si saveds_start; #endif @@ -335,8 +335,8 @@ static SLJIT_INLINE sljit_uw sljit_get_generated_code_size(struct sljit_compiler for the executable code and moves function arguments to the saved registers. The number of arguments are specified in the "args" parameter and the first argument goes to SLJIT_SAVED_REG1, the second - goes to SLJIT_SAVED_REG2 and so on. The number of temporary and - saved registers are passed in "temporaries" and "saveds" arguments + goes to SLJIT_SAVED_REG2 and so on. The number of scratch and + saved registers are passed in "scratches" and "saveds" arguments respectively. Since the saved registers contains the arguments, "args" must be less or equal than "saveds". The sljit_emit_enter is also capable of allocating a stack space for local variables. The @@ -353,7 +353,7 @@ static SLJIT_INLINE sljit_uw sljit_get_generated_code_size(struct sljit_compiler #define SLJIT_MAX_LOCAL_SIZE 65536 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, - sljit_si args, sljit_si temporaries, sljit_si saveds, sljit_si local_size); + sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size); /* The machine code has a context (which contains the local stack space size, number of used registers, etc.) which initialized by sljit_emit_enter. Several @@ -368,7 +368,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil /* Note: multiple calls of this function overwrites the previous call. */ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, - sljit_si args, sljit_si temporaries, sljit_si saveds, sljit_si local_size); + sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size); /* Return from machine code. The op argument can be SLJIT_UNUSED which means the function does not return with anything or any opcode between SLJIT_MOV and @@ -527,23 +527,23 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * it can even decrease the runtime in a few cases. */ #define SLJIT_NOP 1 /* Flags: - (may destroy flags) - Unsigned multiplication of SLJIT_TEMPORARY_REG1 and SLJIT_TEMPORARY_REG2. - Result goes to SLJIT_TEMPORARY_REG2:SLJIT_TEMPORARY_REG1 (high:low) word */ + Unsigned multiplication of SLJIT_SCRATCH_REG1 and SLJIT_SCRATCH_REG2. + Result goes to SLJIT_SCRATCH_REG2:SLJIT_SCRATCH_REG1 (high:low) word */ #define SLJIT_UMUL 2 /* Flags: - (may destroy flags) - Signed multiplication of SLJIT_TEMPORARY_REG1 and SLJIT_TEMPORARY_REG2. - Result goes to SLJIT_TEMPORARY_REG2:SLJIT_TEMPORARY_REG1 (high:low) word */ + Signed multiplication of SLJIT_SCRATCH_REG1 and SLJIT_SCRATCH_REG2. + Result goes to SLJIT_SCRATCH_REG2:SLJIT_SCRATCH_REG1 (high:low) word */ #define SLJIT_SMUL 3 /* Flags: I - (may destroy flags) - Unsigned divide of the value in SLJIT_TEMPORARY_REG1 by the value in SLJIT_TEMPORARY_REG2. - The result is placed in SLJIT_TEMPORARY_REG1 and the remainder goes to SLJIT_TEMPORARY_REG2. - Note: if SLJIT_TEMPORARY_REG2 contains 0, the behaviour is undefined. */ + Unsigned divide of the value in SLJIT_SCRATCH_REG1 by the value in SLJIT_SCRATCH_REG2. + The result is placed in SLJIT_SCRATCH_REG1 and the remainder goes to SLJIT_SCRATCH_REG2. + Note: if SLJIT_SCRATCH_REG2 contains 0, the behaviour is undefined. */ #define SLJIT_UDIV 4 #define SLJIT_IUDIV (SLJIT_UDIV | SLJIT_INT_OP) /* Flags: I - (may destroy flags) - Signed divide of the value in SLJIT_TEMPORARY_REG1 by the value in SLJIT_TEMPORARY_REG2. - The result is placed in SLJIT_TEMPORARY_REG1 and the remainder goes to SLJIT_TEMPORARY_REG2. - Note: if SLJIT_TEMPORARY_REG2 contains 0, the behaviour is undefined. */ + Signed divide of the value in SLJIT_SCRATCH_REG1 by the value in SLJIT_SCRATCH_REG2. + The result is placed in SLJIT_SCRATCH_REG1 and the remainder goes to SLJIT_SCRATCH_REG2. + Note: if SLJIT_SCRATCH_REG2 contains 0, the behaviour is undefined. */ #define SLJIT_SDIV 5 #define SLJIT_ISDIV (SLJIT_SDIV | SLJIT_INT_OP) @@ -678,7 +678,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler sljit_si src2, sljit_sw src2w); /* The following function is a helper function for sljit_emit_op_custom. - It returns with the real machine register index of any SLJIT_TEMPORARY + It returns with the real machine register index of any SLJIT_SCRATCH SLJIT_SAVED or SLJIT_LOCALS register. Note: it returns with -1 for virtual registers (all EREGs on x86-32). Note: register returned by SLJIT_LOCALS_REG is not necessary the real diff --git a/sljit/sljitNativeARM_Thumb2.c b/sljit/sljitNativeARM_Thumb2.c index f347fb0..0a60dc2 100644 --- a/sljit/sljitNativeARM_Thumb2.c +++ b/sljit/sljitNativeARM_Thumb2.c @@ -1124,19 +1124,26 @@ static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_ return getput_arg(compiler, flags, reg, arg, argw, 0, 0); } +static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) +{ + if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) + return compiler->error; + return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); +} + /* --------------------------------------------------------------------- */ /* Entry, exit */ /* --------------------------------------------------------------------- */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si temporaries, sljit_si saveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) { sljit_si size; sljit_ins push; CHECK_ERROR(); - check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size); + check_sljit_emit_enter(compiler, args, scratches, saveds, local_size); - compiler->temporaries = temporaries; + compiler->scratches = scratches; compiler->saveds = saveds; #if (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->logical_local_size = local_size; @@ -1153,7 +1160,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil push |= 1 << 7; if (saveds >= 1) push |= 1 << 6; - if (temporaries >= 5) + if (scratches >= 5) push |= 1 << 5; FAIL_IF(saveds >= 3 ? push_inst32(compiler, PUSH_W | (1 << 14) | push) @@ -1173,23 +1180,23 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil } if (args >= 1) - FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_SAVED_REG1, SLJIT_TEMPORARY_REG1))); + FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_SAVED_REG1, SLJIT_SCRATCH_REG1))); if (args >= 2) - FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_SAVED_REG2, SLJIT_TEMPORARY_REG2))); + FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_SAVED_REG2, SLJIT_SCRATCH_REG2))); if (args >= 3) - FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_SAVED_REG3, SLJIT_TEMPORARY_REG3))); + FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_SAVED_REG3, SLJIT_SCRATCH_REG3))); return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si temporaries, sljit_si saveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) { sljit_si size; CHECK_ERROR_VOID(); - check_sljit_set_context(compiler, args, temporaries, saveds, local_size); + check_sljit_set_context(compiler, args, scratches, saveds, local_size); - compiler->temporaries = temporaries; + compiler->scratches = scratches; compiler->saveds = saveds; #if (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->logical_local_size = local_size; @@ -1229,7 +1236,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi pop |= 1 << 7; if (compiler->saveds >= 1) pop |= 1 << 6; - if (compiler->temporaries >= 5) + if (compiler->scratches >= 5) pop |= 1 << 5; return compiler->saveds >= 3 ? push_inst32(compiler, POP_W | (1 << 15) | pop) @@ -1271,16 +1278,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler case SLJIT_UMUL: case SLJIT_SMUL: return push_inst32(compiler, (op == SLJIT_UMUL ? UMULL : SMULL) - | (reg_map[SLJIT_TEMPORARY_REG2] << 8) - | (reg_map[SLJIT_TEMPORARY_REG1] << 12) - | (reg_map[SLJIT_TEMPORARY_REG1] << 16) - | reg_map[SLJIT_TEMPORARY_REG2]); + | (reg_map[SLJIT_SCRATCH_REG2] << 8) + | (reg_map[SLJIT_SCRATCH_REG1] << 12) + | (reg_map[SLJIT_SCRATCH_REG1] << 16) + | reg_map[SLJIT_SCRATCH_REG2]); case SLJIT_UDIV: case SLJIT_SDIV: - if (compiler->temporaries >= 4) { + if (compiler->scratches >= 4) { FAIL_IF(push_inst32(compiler, 0xf84d2d04 /* str r2, [sp, #-4]! */)); FAIL_IF(push_inst32(compiler, 0xf84dcd04 /* str ip, [sp, #-4]! */)); - } else if (compiler->temporaries >= 3) + } else if (compiler->scratches >= 3) FAIL_IF(push_inst32(compiler, 0xf84d2d08 /* str r2, [sp, #-8]! */)); #if defined(__GNUC__) FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM, @@ -1288,10 +1295,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler #else #error "Software divmod functions are needed" #endif - if (compiler->temporaries >= 4) { + if (compiler->scratches >= 4) { FAIL_IF(push_inst32(compiler, 0xf85dcb04 /* ldr ip, [sp], #4 */)); return push_inst32(compiler, 0xf85d2b04 /* ldr r2, [sp], #4 */); - } else if (compiler->temporaries >= 3) + } else if (compiler->scratches >= 3) return push_inst32(compiler, 0xf85d2b08 /* ldr r2, [sp], #8 */); return SLJIT_SUCCESS; } @@ -1314,7 +1321,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler compiler->cache_arg = 0; compiler->cache_argw = 0; - dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG1; + dst_r = (dst >= SLJIT_SCRATCH_REG1 && dst <= TMP_REG3) ? dst : TMP_REG1; op = GET_OPCODE(op); if (op >= SLJIT_MOV && op <= SLJIT_MOVU_P) { @@ -1447,7 +1454,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler compiler->cache_arg = 0; compiler->cache_argw = 0; - dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG1; + dst_r = (dst >= SLJIT_SCRATCH_REG1 && dst <= TMP_REG3) ? dst : TMP_REG1; flags = (GET_FLAGS(op) ? SET_FLAGS : 0) | ((op & SLJIT_KEEP_FLAGS) ? KEEP_FLAGS : 0); if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, WORD_SIZE | STORE | ARG_TEST, TMP_REG1, dst, dstw)) @@ -1716,18 +1723,21 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c check_sljit_emit_fast_enter(compiler, dst, dstw); ADJUST_LOCAL_OFFSET(dst, dstw); - if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) + /* For UNUSED dst. Uncommon, but possible. */ + if (dst == SLJIT_UNUSED) + return SLJIT_SUCCESS; + + if (dst <= TMP_REG3) return push_inst16(compiler, MOV | SET_REGS44(dst, TMP_REG3)); - else if (dst & SLJIT_MEM) { - if (getput_arg_fast(compiler, WORD_SIZE | STORE, TMP_REG3, dst, dstw)) - return compiler->error; - FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG2, TMP_REG3))); - compiler->cache_arg = 0; - compiler->cache_argw = 0; - return getput_arg(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw, 0, 0); - } - return SLJIT_SUCCESS; + /* Memory. */ + if (getput_arg_fast(compiler, WORD_SIZE | STORE, TMP_REG3, dst, dstw)) + return compiler->error; + /* TMP_REG3 is used for caching. */ + FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG2, TMP_REG3))); + compiler->cache_arg = 0; + compiler->cache_argw = 0; + return getput_arg(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw, 0, 0); } SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) @@ -1736,7 +1746,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * check_sljit_emit_fast_return(compiler, src, srcw); ADJUST_LOCAL_OFFSET(src, srcw); - if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) + if (src <= TMP_REG3) FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG3, src))); else if (src & SLJIT_MEM) { if (getput_arg_fast(compiler, WORD_SIZE, TMP_REG3, src, srcw)) @@ -1880,7 +1890,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil FAIL_IF(push_inst16(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RN3(TMP_REG1))); } else { - if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) + if (src <= TMP_REG3) return push_inst16(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RN3(src)); FAIL_IF(emit_op_mem(compiler, WORD_SIZE, type <= SLJIT_JUMP ? TMP_PC : TMP_REG1, src, srcw)); @@ -1896,22 +1906,40 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com sljit_si type) { sljit_si dst_r, flags = GET_ALL_FLAGS(op); + sljit_ins ins; sljit_uw cc; CHECK_ERROR(); check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type); ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src, srcw); if (dst == SLJIT_UNUSED) return SLJIT_SUCCESS; op = GET_OPCODE(op); cc = get_cc(type); - if ((op >= SLJIT_AND && op <= SLJIT_XOR) && dst <= SLJIT_NO_REGISTERS) { + dst_r = (dst <= TMP_REG3) ? dst : TMP_REG2; + + if (op < SLJIT_ADD) { + FAIL_IF(push_inst16(compiler, IT | (cc << 4) | (((cc & 0x1) ^ 0x1) << 3) | 0x4)); + if (reg_map[dst_r] > 7) { + FAIL_IF(push_inst32(compiler, MOV_WI | RD4(dst_r) | 1)); + FAIL_IF(push_inst32(compiler, MOV_WI | RD4(dst_r) | 0)); + } else { + FAIL_IF(push_inst16(compiler, MOVSI | RDN3(dst_r) | 1)); + FAIL_IF(push_inst16(compiler, MOVSI | RDN3(dst_r) | 0)); + } + return dst_r == TMP_REG2 ? emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw) : SLJIT_SUCCESS; + } + + ins = (op == SLJIT_AND ? ANDI : (op == SLJIT_OR ? ORRI : EORI)); + if ((op == SLJIT_OR || op == SLJIT_XOR) && dst <= TMP_REG3 && dst == src) { + /* Does not change the other bits. */ FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8)); - FAIL_IF(push_inst32(compiler, (op == SLJIT_AND ? ANDI : (op == SLJIT_OR ? ORRI : EORI)) | RN4(dst) | RD4(dst) | 0x1)); + FAIL_IF(push_inst32(compiler, ins | RN4(src) | RD4(dst) | 1)); if (flags & SLJIT_SET_E) { - /* The condition must always be set, even if the AND/ORR is not executed above. */ + /* The condition must always be set, even if the ORRI/EORI is not executed above. */ if (reg_map[dst] <= 7) return push_inst16(compiler, MOVS | RD3(TMP_REG1) | RN3(dst)); return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(TMP_REG1) | RM4(dst)); @@ -1919,30 +1947,30 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com return SLJIT_SUCCESS; } - FAIL_IF(push_inst16(compiler, IT | (cc << 4) | (((cc & 0x1) ^ 0x1) << 3) | 0x4)); - dst_r = TMP_REG2; - if (op < SLJIT_ADD && dst <= SLJIT_NO_REGISTERS) { - if (reg_map[dst] > 7) { - FAIL_IF(push_inst32(compiler, MOV_WI | RD4(dst) | 1)); - return push_inst32(compiler, MOV_WI | RD4(dst) | 0); - } - dst_r = dst; + compiler->cache_arg = 0; + compiler->cache_argw = 0; + if (src & SLJIT_MEM) { + FAIL_IF(emit_op_mem2(compiler, WORD_SIZE, TMP_REG1, src, srcw, dst, dstw)); + src = TMP_REG1; + srcw = 0; + } else if (src & SLJIT_IMM) { + FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); + src = TMP_REG1; + srcw = 0; } - FAIL_IF(push_inst16(compiler, MOVSI | RDN3(dst_r) | 0x1)); - FAIL_IF(push_inst16(compiler, MOVSI | RDN3(dst_r) | 0x0)); + FAIL_IF(push_inst16(compiler, IT | (cc << 4) | (((cc & 0x1) ^ 0x1) << 3) | 0x4)); + FAIL_IF(push_inst32(compiler, ins | RN4(src) | RD4(dst_r) | 1)); + FAIL_IF(push_inst32(compiler, ins | RN4(src) | RD4(dst_r) | 0)); + if (dst_r == TMP_REG2) + FAIL_IF(emit_op_mem2(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw, 0, 0)); - if (dst_r == TMP_REG2) { - if (op >= SLJIT_AND && op <= SLJIT_XOR) { -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) - compiler->skip_checks = 1; -#endif - return sljit_emit_op2(compiler, op | flags, dst, dstw, dst, dstw, TMP_REG2, 0); - } - SLJIT_ASSERT(dst & SLJIT_MEM); - return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw); + if (flags & SLJIT_SET_E) { + /* The condition must always be set, even if the ORR/EORI is not executed above. */ + if (reg_map[dst_r] <= 7) + return push_inst16(compiler, MOVS | RD3(TMP_REG1) | RN3(dst_r)); + return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(TMP_REG1) | RM4(dst_r)); } - return SLJIT_SUCCESS; } @@ -1959,7 +1987,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi PTR_FAIL_IF(!const_); set_const(const_, compiler); - dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG1; + dst_r = (dst <= TMP_REG3) ? dst : TMP_REG1; PTR_FAIL_IF(emit_imm32_const(compiler, dst_r, init_value)); if (dst & SLJIT_MEM) diff --git a/sljit/sljitNativeARM_v5.c b/sljit/sljitNativeARM_v5.c index deb3af0..23a45a4 100644 --- a/sljit/sljitNativeARM_v5.c +++ b/sljit/sljitNativeARM_v5.c @@ -824,15 +824,15 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si i sljit_si src1, sljit_sw src1w, sljit_si src2, sljit_sw src2w); -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si temporaries, sljit_si saveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) { sljit_si size; sljit_uw push; CHECK_ERROR(); - check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size); + check_sljit_emit_enter(compiler, args, scratches, saveds, local_size); - compiler->temporaries = temporaries; + compiler->scratches = scratches; compiler->saveds = saveds; #if (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->logical_local_size = local_size; @@ -841,9 +841,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil /* Push saved registers, temporary registers stmdb sp!, {..., lr} */ push = PUSH | (1 << 14); - if (temporaries >= 5) + if (scratches >= 5) push |= 1 << 11; - if (temporaries >= 4) + if (scratches >= 4) push |= 1 << 10; if (saveds >= 5) push |= 1 << 8; @@ -859,8 +859,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil /* Stack must be aligned to 8 bytes: */ size = (1 + saveds) * sizeof(sljit_uw); - if (temporaries >= 4) - size += (temporaries - 3) * sizeof(sljit_uw); + if (scratches >= 4) + size += (scratches - 3) * sizeof(sljit_uw); local_size += size; local_size = (local_size + 7) & ~7; local_size -= size; @@ -869,31 +869,31 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil FAIL_IF(emit_op(compiler, SLJIT_SUB, ALLOW_IMM, SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, local_size)); if (args >= 1) - EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_SAVED_REG1, SLJIT_UNUSED, RM(SLJIT_TEMPORARY_REG1))); + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_SAVED_REG1, SLJIT_UNUSED, RM(SLJIT_SCRATCH_REG1))); if (args >= 2) - EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_SAVED_REG2, SLJIT_UNUSED, RM(SLJIT_TEMPORARY_REG2))); + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_SAVED_REG2, SLJIT_UNUSED, RM(SLJIT_SCRATCH_REG2))); if (args >= 3) - EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_SAVED_REG3, SLJIT_UNUSED, RM(SLJIT_TEMPORARY_REG3))); + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_SAVED_REG3, SLJIT_UNUSED, RM(SLJIT_SCRATCH_REG3))); return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si temporaries, sljit_si saveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) { sljit_si size; CHECK_ERROR_VOID(); - check_sljit_set_context(compiler, args, temporaries, saveds, local_size); + check_sljit_set_context(compiler, args, scratches, saveds, local_size); - compiler->temporaries = temporaries; + compiler->scratches = scratches; compiler->saveds = saveds; #if (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->logical_local_size = local_size; #endif size = (1 + saveds) * sizeof(sljit_uw); - if (temporaries >= 4) - size += (temporaries - 3) * sizeof(sljit_uw); + if (scratches >= 4) + size += (scratches - 3) * sizeof(sljit_uw); local_size += size; local_size = (local_size + 7) & ~7; local_size -= size; @@ -915,9 +915,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi pop = POP | (1 << 15); /* Push saved registers, temporary registers ldmia sp!, {..., pc} */ - if (compiler->temporaries >= 5) + if (compiler->scratches >= 5) pop |= 1 << 11; - if (compiler->temporaries >= 4) + if (compiler->scratches >= 4) pop |= 1 << 10; if (compiler->saveds >= 5) pop |= 1 << 8; @@ -1613,6 +1613,22 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags, return SLJIT_SUCCESS; } +static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +{ + if (getput_arg_fast(compiler, flags, reg, arg, argw)) + return compiler->error; + compiler->cache_arg = 0; + compiler->cache_argw = 0; + return getput_arg(compiler, flags, reg, arg, argw, 0, 0); +} + +static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) +{ + if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) + return compiler->error; + return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); +} + static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si inp_flags, sljit_si dst, sljit_sw dstw, sljit_si src1, sljit_sw src1w, @@ -1634,17 +1650,17 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si i compiler->cache_argw = 0; /* Destination check. */ - if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REG3) { + if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) + return SLJIT_SUCCESS; + dst_r = TMP_REG2; + } + else if (dst <= TMP_REG3) { dst_r = dst; flags |= REG_DEST; if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) sugg_src2_r = dst_r; } - else if (dst == SLJIT_UNUSED) { - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) - return SLJIT_SUCCESS; - dst_r = TMP_REG2; - } else { SLJIT_ASSERT(dst & SLJIT_MEM); if (getput_arg_fast(compiler, inp_flags | ARG_TEST, TMP_REG2, dst, dstw)) { @@ -1658,9 +1674,9 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si i } /* Source 1. */ - if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= TMP_REG3) + if (src1 <= TMP_REG3) src1_r = src1; - else if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= TMP_REG3) { + else if (src2 <= TMP_REG3) { flags |= ARGS_SWAPPED; src1_r = src2; src2 = src1; @@ -1706,7 +1722,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si i /* Source 2. */ if (src2_r == 0) { - if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= TMP_REG3) { + if (src2 <= TMP_REG3) { src2_r = src2; flags |= REG_SOURCE; if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) @@ -1835,21 +1851,21 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler case SLJIT_SMUL: #if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) return push_inst(compiler, (op == SLJIT_UMUL ? UMULL : SMULL) - | (reg_map[SLJIT_TEMPORARY_REG2] << 16) - | (reg_map[SLJIT_TEMPORARY_REG1] << 12) - | (reg_map[SLJIT_TEMPORARY_REG1] << 8) - | reg_map[SLJIT_TEMPORARY_REG2]); + | (reg_map[SLJIT_SCRATCH_REG2] << 16) + | (reg_map[SLJIT_SCRATCH_REG1] << 12) + | (reg_map[SLJIT_SCRATCH_REG1] << 8) + | reg_map[SLJIT_SCRATCH_REG2]); #else - EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG1, SLJIT_UNUSED, RM(SLJIT_TEMPORARY_REG2))); + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG1, SLJIT_UNUSED, RM(SLJIT_SCRATCH_REG2))); return push_inst(compiler, (op == SLJIT_UMUL ? UMULL : SMULL) - | (reg_map[SLJIT_TEMPORARY_REG2] << 16) - | (reg_map[SLJIT_TEMPORARY_REG1] << 12) - | (reg_map[SLJIT_TEMPORARY_REG1] << 8) + | (reg_map[SLJIT_SCRATCH_REG2] << 16) + | (reg_map[SLJIT_SCRATCH_REG1] << 12) + | (reg_map[SLJIT_SCRATCH_REG1] << 8) | reg_map[TMP_REG1]); #endif case SLJIT_UDIV: case SLJIT_SDIV: - if (compiler->temporaries >= 3) + if (compiler->scratches >= 3) EMIT_INSTRUCTION(0xe52d2008 /* str r2, [sp, #-8]! */); #if defined(__GNUC__) FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM, @@ -1857,7 +1873,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler #else #error "Software divmod functions are needed" #endif - if (compiler->temporaries >= 3) + if (compiler->scratches >= 3) return push_inst(compiler, 0xe49d2008 /* ldr r2, [sp], #8 */); return SLJIT_SUCCESS; } @@ -2214,18 +2230,21 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c check_sljit_emit_fast_enter(compiler, dst, dstw); ADJUST_LOCAL_OFFSET(dst, dstw); - if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) + /* For UNUSED dst. Uncommon, but possible. */ + if (dst == SLJIT_UNUSED) + return SLJIT_SUCCESS; + + if (dst <= TMP_REG3) return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, RM(TMP_REG3))); - else if (dst & SLJIT_MEM) { - if (getput_arg_fast(compiler, WORD_DATA, TMP_REG3, dst, dstw)) - return compiler->error; - EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG2, SLJIT_UNUSED, RM(TMP_REG3))); - compiler->cache_arg = 0; - compiler->cache_argw = 0; - return getput_arg(compiler, WORD_DATA, TMP_REG2, dst, dstw, 0, 0); - } - return SLJIT_SUCCESS; + /* Memory. */ + if (getput_arg_fast(compiler, WORD_DATA, TMP_REG3, dst, dstw)) + return compiler->error; + /* TMP_REG3 is used for caching. */ + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG2, SLJIT_UNUSED, RM(TMP_REG3))); + compiler->cache_arg = 0; + compiler->cache_argw = 0; + return getput_arg(compiler, WORD_DATA, TMP_REG2, dst, dstw, 0, 0); } SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) @@ -2234,7 +2253,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * check_sljit_emit_fast_return(compiler, src, srcw); ADJUST_LOCAL_OFFSET(src, srcw); - if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) + if (src <= TMP_REG3) EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG3, SLJIT_UNUSED, RM(src))); else if (src & SLJIT_MEM) { if (getput_arg_fast(compiler, WORD_DATA | LOAD_DATA, TMP_REG3, src, srcw)) @@ -2394,11 +2413,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil jump->addr = compiler->size; } else { - if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) + if (src <= TMP_REG3) return push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(src)); SLJIT_ASSERT(src & SLJIT_MEM); - FAIL_IF(emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM, TMP_REG2, 0, TMP_REG1, 0, src, srcw)); + FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG2, src, srcw)); return push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG2)); } @@ -2410,39 +2429,52 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com sljit_si src, sljit_sw srcw, sljit_si type) { - sljit_si reg; - sljit_uw cc; + sljit_si dst_r, flags = GET_ALL_FLAGS(op); + sljit_uw cc, ins; CHECK_ERROR(); check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type); ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src, srcw); if (dst == SLJIT_UNUSED) return SLJIT_SUCCESS; + op = GET_OPCODE(op); cc = get_cc(type); - if (GET_OPCODE(op) < SLJIT_ADD) { - reg = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2; - - EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, reg, SLJIT_UNUSED, SRC2_IMM | 0)); - EMIT_INSTRUCTION((EMIT_DATA_PROCESS_INS(MOV_DP, 0, reg, SLJIT_UNUSED, SRC2_IMM | 1) & ~COND_MASK) | cc); + dst_r = (dst <= TMP_REG3) ? dst : TMP_REG2; - return (reg == TMP_REG2) ? emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, TMP_REG2, 0) : SLJIT_SUCCESS; + if (op < SLJIT_ADD) { + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst_r, SLJIT_UNUSED, SRC2_IMM | 0)); + EMIT_INSTRUCTION((EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst_r, SLJIT_UNUSED, SRC2_IMM | 1) & ~COND_MASK) | cc); + return (dst_r == TMP_REG2) ? emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw) : SLJIT_SUCCESS; } - if (dst <= SLJIT_NO_REGISTERS) { - EMIT_INSTRUCTION((EMIT_DATA_PROCESS_INS(GET_OPCODE(op) == SLJIT_AND ? AND_DP : (GET_OPCODE(op) == SLJIT_OR ? ORR_DP : EOR_DP), - 0, dst, dst, SRC2_IMM | 1) & ~COND_MASK) | cc); - /* The condition must always be set, even if the AND/ORR is not executed above. */ - return (op & SLJIT_SET_E) ? push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, SET_FLAGS, TMP_REG1, SLJIT_UNUSED, RM(dst))) : SLJIT_SUCCESS; + ins = (op == SLJIT_AND ? AND_DP : (op == SLJIT_OR ? ORR_DP : EOR_DP)); + if ((op == SLJIT_OR || op == SLJIT_XOR) && dst <= TMP_REG3 && dst == src) { + EMIT_INSTRUCTION((EMIT_DATA_PROCESS_INS(ins, 0, dst, dst, SRC2_IMM | 1) & ~COND_MASK) | cc); + /* The condition must always be set, even if the ORR/EOR is not executed above. */ + return (flags & SLJIT_SET_E) ? push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, SET_FLAGS, TMP_REG1, SLJIT_UNUSED, RM(dst))) : SLJIT_SUCCESS; } - EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG1, SLJIT_UNUSED, SRC2_IMM | 0)); - EMIT_INSTRUCTION((EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG1, SLJIT_UNUSED, SRC2_IMM | 1) & ~COND_MASK) | cc); -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) - compiler->skip_checks = 1; -#endif - return emit_op(compiler, op, ALLOW_IMM, dst, dstw, TMP_REG1, 0, dst, dstw); + compiler->cache_arg = 0; + compiler->cache_argw = 0; + if (src & SLJIT_MEM) { + FAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw, dst, dstw)); + src = TMP_REG1; + srcw = 0; + } else if (src & SLJIT_IMM) { + FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); + src = TMP_REG1; + srcw = 0; + } + + EMIT_INSTRUCTION((EMIT_DATA_PROCESS_INS(ins, 0, dst_r, src, SRC2_IMM | 1) & ~COND_MASK) | cc); + EMIT_INSTRUCTION((EMIT_DATA_PROCESS_INS(ins, 0, dst_r, src, SRC2_IMM | 0) & ~COND_MASK) | (cc ^ 0x10000000)); + if (dst_r == TMP_REG2) + FAIL_IF(emit_op_mem2(compiler, WORD_DATA, TMP_REG2, dst, dstw, 0, 0)); + + return (flags & SLJIT_SET_E) ? push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, SET_FLAGS, TMP_REG1, SLJIT_UNUSED, RM(dst_r))) : SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) @@ -2457,7 +2489,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const)); PTR_FAIL_IF(!const_); - reg = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2; + reg = (dst <= TMP_REG3) ? dst : TMP_REG2; #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) PTR_FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_DATA | LOAD_DATA, 1, 0, reg, TMP_PC, 0), init_value)); @@ -2468,8 +2500,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi set_const(const_, compiler); if (reg == TMP_REG2 && dst != SLJIT_UNUSED) - if (emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, TMP_REG2, 0)) - return NULL; + PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw)); return const_; } diff --git a/sljit/sljitNativeMIPS_common.c b/sljit/sljitNativeMIPS_common.c index ea4ee0f..72b228e 100644 --- a/sljit/sljitNativeMIPS_common.c +++ b/sljit/sljitNativeMIPS_common.c @@ -423,18 +423,19 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil #define WRITE_BACK 0x00020 #define ARG_TEST 0x00040 -#define CUMULATIVE_OP 0x00080 -#define LOGICAL_OP 0x00100 -#define IMM_OP 0x00200 -#define SRC2_IMM 0x00400 - -#define UNUSED_DEST 0x00800 -#define REG_DEST 0x01000 -#define REG1_SOURCE 0x02000 -#define REG2_SOURCE 0x04000 -#define SLOW_SRC1 0x08000 -#define SLOW_SRC2 0x10000 -#define SLOW_DEST 0x20000 +#define ALT_KEEP_CACHE 0x00080 +#define CUMULATIVE_OP 0x00100 +#define LOGICAL_OP 0x00200 +#define IMM_OP 0x00400 +#define SRC2_IMM 0x00800 + +#define UNUSED_DEST 0x01000 +#define REG_DEST 0x02000 +#define REG1_SOURCE 0x04000 +#define REG2_SOURCE 0x08000 +#define SLOW_SRC1 0x10000 +#define SLOW_SRC2 0x20000 +#define SLOW_DEST 0x40000 /* Only these flags are set. UNUSED_DEST is not set when no flags should be set. */ #define CHECK_FLAGS(list) \ @@ -454,14 +455,14 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil #include "sljitNativeMIPS_64.c" #endif -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si temporaries, sljit_si saveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) { sljit_ins base; CHECK_ERROR(); - check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size); + check_sljit_emit_enter(compiler, args, scratches, saveds, local_size); - compiler->temporaries = temporaries; + compiler->scratches = scratches; compiler->saveds = saveds; #if (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->logical_local_size = local_size; @@ -506,12 +507,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si temporaries, sljit_si saveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) { CHECK_ERROR_VOID(); - check_sljit_set_context(compiler, args, temporaries, saveds, local_size); + check_sljit_set_context(compiler, args, scratches, saveds, local_size); - compiler->temporaries = temporaries; + compiler->scratches = scratches; compiler->saveds = saveds; #if (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->logical_local_size = local_size; @@ -607,7 +608,7 @@ static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, { SLJIT_ASSERT(arg & SLJIT_MEM); - if (!(flags & WRITE_BACK) && !(arg & 0xf0) && argw <= SIMM_MAX && argw >= SIMM_MIN) { + if ((!(flags & WRITE_BACK) || !(arg & 0xf)) && !(arg & 0xf0) && argw <= SIMM_MAX && argw >= SIMM_MIN) { /* Works for both absoulte and relative addresses. */ if (SLJIT_UNLIKELY(flags & ARG_TEST)) return 1; @@ -813,21 +814,23 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f sljit_sw src2_r = 0; sljit_si sugg_src2_r = TMP_REG2; - compiler->cache_arg = 0; - compiler->cache_argw = 0; - - if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REG3) { - dst_r = dst; - flags |= REG_DEST; - if (GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI) - sugg_src2_r = dst_r; + if (!(flags & ALT_KEEP_CACHE)) { + compiler->cache_arg = 0; + compiler->cache_argw = 0; } - else if (dst == SLJIT_UNUSED) { + + if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) return SLJIT_SUCCESS; if (GET_FLAGS(op)) flags |= UNUSED_DEST; } + else if (dst <= TMP_REG3) { + dst_r = dst; + flags |= REG_DEST; + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) + sugg_src2_r = dst_r; + } else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, DR(TMP_REG1), dst, dstw)) flags |= SLOW_DEST; @@ -855,7 +858,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f } /* Source 1. */ - if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= TMP_REG3) { + if (src1 <= TMP_REG3) { src1_r = src1; flags |= REG1_SOURCE; } @@ -876,20 +879,23 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f } /* Source 2. */ - if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= TMP_REG3) { + if (src2 <= TMP_REG3) { src2_r = src2; flags |= REG2_SOURCE; - if (!(flags & REG_DEST) && GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI) + if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) dst_r = src2_r; } else if (src2 & SLJIT_IMM) { if (!(flags & SRC2_IMM)) { - if (src2w || (GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI)) { + if (src2w) { FAIL_IF(load_immediate(compiler, DR(sugg_src2_r), src2w)); src2_r = sugg_src2_r; } - else + else { src2_r = 0; + if ((op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) && (dst & SLJIT_MEM)) + dst_r = 0; + } } } else { @@ -942,18 +948,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler return push_inst(compiler, NOP, UNMOVABLE_INS); case SLJIT_UMUL: case SLJIT_SMUL: - FAIL_IF(push_inst(compiler, (op == SLJIT_UMUL ? MULTU : MULT) | S(SLJIT_TEMPORARY_REG1) | T(SLJIT_TEMPORARY_REG2), MOVABLE_INS)); - FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_TEMPORARY_REG1), DR(SLJIT_TEMPORARY_REG1))); - return push_inst(compiler, MFHI | D(SLJIT_TEMPORARY_REG2), DR(SLJIT_TEMPORARY_REG2)); + FAIL_IF(push_inst(compiler, (op == SLJIT_UMUL ? MULTU : MULT) | S(SLJIT_SCRATCH_REG1) | T(SLJIT_SCRATCH_REG2), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_SCRATCH_REG1), DR(SLJIT_SCRATCH_REG1))); + return push_inst(compiler, MFHI | D(SLJIT_SCRATCH_REG2), DR(SLJIT_SCRATCH_REG2)); case SLJIT_UDIV: case SLJIT_SDIV: #if !(defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64) FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); #endif - FAIL_IF(push_inst(compiler, (op == SLJIT_UDIV ? DIVU : DIV) | S(SLJIT_TEMPORARY_REG1) | T(SLJIT_TEMPORARY_REG2), MOVABLE_INS)); - FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_TEMPORARY_REG1), DR(SLJIT_TEMPORARY_REG1))); - return push_inst(compiler, MFHI | D(SLJIT_TEMPORARY_REG2), DR(SLJIT_TEMPORARY_REG2)); + FAIL_IF(push_inst(compiler, (op == SLJIT_UDIV ? DIVU : DIV) | S(SLJIT_SCRATCH_REG1) | T(SLJIT_SCRATCH_REG2), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_SCRATCH_REG1), DR(SLJIT_SCRATCH_REG1))); + return push_inst(compiler, MFHI | D(SLJIT_SCRATCH_REG2), DR(SLJIT_SCRATCH_REG2)); } return SLJIT_SUCCESS; @@ -964,7 +970,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler sljit_si src, sljit_sw srcw) { #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) - #define flags 0 +# define flags 0 #endif CHECK_ERROR(); @@ -1029,7 +1035,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler return SLJIT_SUCCESS; #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) - #undef flags +# undef flags #endif } @@ -1039,7 +1045,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler sljit_si src2, sljit_sw src2w) { #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) - #define flags 0 +# define flags 0 #endif CHECK_ERROR(); @@ -1079,7 +1085,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler return SLJIT_SUCCESS; #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) - #undef flags +# undef flags #endif } @@ -1289,13 +1295,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c check_sljit_emit_fast_enter(compiler, dst, dstw); ADJUST_LOCAL_OFFSET(dst, dstw); - if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) + /* For UNUSED dst. Uncommon, but possible. */ + if (dst == SLJIT_UNUSED) + return SLJIT_SUCCESS; + + if (dst <= TMP_REG3) return push_inst(compiler, ADDU_W | SA(RETURN_ADDR_REG) | TA(0) | D(dst), DR(dst)); - else if (dst & SLJIT_MEM) - return emit_op_mem(compiler, WORD_DATA, RETURN_ADDR_REG, dst, dstw); - /* SLJIT_UNUSED is also possible, although highly unlikely. */ - return SLJIT_SUCCESS; + /* Memory. */ + return emit_op_mem(compiler, WORD_DATA, RETURN_ADDR_REG, dst, dstw); } SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) @@ -1304,7 +1312,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * check_sljit_emit_fast_return(compiler, src, srcw); ADJUST_LOCAL_OFFSET(src, srcw); - if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) + if (src <= TMP_REG3) FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | DA(RETURN_ADDR_REG), RETURN_ADDR_REG)); else if (src & SLJIT_MEM) FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RETURN_ADDR_REG, src, srcw)); @@ -1453,7 +1461,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile PTR_FAIL_IF(push_inst(compiler, JALR | S(TMP_REG2) | DA(RETURN_ADDR_REG), UNMOVABLE_INS)); jump->addr = compiler->size; /* A NOP if type < CALL1. */ - PTR_FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_TEMPORARY_REG1) | TA(0) | DA(4), UNMOVABLE_INS)); + PTR_FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_SCRATCH_REG1) | TA(0) | DA(4), UNMOVABLE_INS)); } return jump; } @@ -1696,7 +1704,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil check_sljit_emit_ijump(compiler, type, src, srcw); ADJUST_LOCAL_OFFSET(src, srcw); - if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) { + if (src <= TMP_REG3) { if (DR(src) != 4) src_r = src; else @@ -1714,12 +1722,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil } FAIL_IF(push_inst(compiler, JALR | S(PIC_ADDR_REG) | DA(RETURN_ADDR_REG), UNMOVABLE_INS)); /* We need an extra instruction in any case. */ - return push_inst(compiler, ADDU_W | S(SLJIT_TEMPORARY_REG1) | TA(0) | DA(4), UNMOVABLE_INS); + return push_inst(compiler, ADDU_W | S(SLJIT_SCRATCH_REG1) | TA(0) | DA(4), UNMOVABLE_INS); } /* Register input. */ if (type >= SLJIT_CALL1) - FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_TEMPORARY_REG1) | TA(0) | DA(4), 4)); + FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_SCRATCH_REG1) | TA(0) | DA(4), 4)); FAIL_IF(push_inst(compiler, JALR | S(src_r) | DA(RETURN_ADDR_REG), UNMOVABLE_INS)); return push_inst(compiler, ADDU_W | S(src_r) | TA(0) | D(PIC_ADDR_REG), UNMOVABLE_INS); } @@ -1761,7 +1769,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com return SLJIT_SUCCESS; op = GET_OPCODE(op); - sugg_dst_ar = DR((op < SLJIT_ADD && dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2); + sugg_dst_ar = DR((op < SLJIT_ADD && dst <= TMP_REG3) ? dst : TMP_REG2); + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + if (op >= SLJIT_ADD && (src & SLJIT_MEM)) { + ADJUST_LOCAL_OFFSET(src, srcw); + FAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, DR(TMP_REG1), src, srcw, dst, dstw)); + src = TMP_REG1; + srcw = 0; + } switch (type) { case SLJIT_C_EQUAL: @@ -1823,10 +1840,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com dst_ar = sugg_dst_ar; } - if (op >= SLJIT_AND && op <= SLJIT_XOR) { + if (op >= SLJIT_ADD) { if (DR(TMP_REG2) != dst_ar) FAIL_IF(push_inst(compiler, ADDU_W | SA(dst_ar) | TA(0) | D(TMP_REG2), DR(TMP_REG2))); - return emit_op(compiler, op | flags, CUMULATIVE_OP | LOGICAL_OP | IMM_OP, dst, dstw, dst, dstw, TMP_REG2, 0); + return emit_op(compiler, op | flags, CUMULATIVE_OP | LOGICAL_OP | IMM_OP | ALT_KEEP_CACHE, dst, dstw, src, srcw, TMP_REG2, 0); } if (dst & SLJIT_MEM) @@ -1850,7 +1867,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi PTR_FAIL_IF(!const_); set_const(const_, compiler); - reg = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2; + reg = (dst <= TMP_REG3) ? dst : TMP_REG2; PTR_FAIL_IF(emit_const(compiler, reg, init_value)); diff --git a/sljit/sljitNativePPC_common.c b/sljit/sljitNativePPC_common.c index 935210f..f7c75a7 100644 --- a/sljit/sljitNativePPC_common.c +++ b/sljit/sljitNativePPC_common.c @@ -449,6 +449,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil #define ALT_SIGN_EXT 0x000200 /* This flag affects the RC() and OERC() macros. */ #define ALT_SET_FLAGS 0x000400 +#define ALT_KEEP_CACHE 0x000800 #define ALT_FORM1 0x010000 #define ALT_FORM2 0x020000 #define ALT_FORM3 0x040000 @@ -485,12 +486,12 @@ ALT_FORM6 0x200000 */ #define STACK_LOAD LD #endif -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si temporaries, sljit_si saveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) { CHECK_ERROR(); - check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size); + check_sljit_emit_enter(compiler, args, scratches, saveds, local_size); - compiler->temporaries = temporaries; + compiler->scratches = scratches; compiler->saveds = saveds; #if (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->logical_local_size = local_size; @@ -512,11 +513,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil FAIL_IF(push_inst(compiler, ADDI | D(ZERO_REG) | A(0) | 0)); if (args >= 1) - FAIL_IF(push_inst(compiler, OR | S(SLJIT_TEMPORARY_REG1) | A(SLJIT_SAVED_REG1) | B(SLJIT_TEMPORARY_REG1))); + FAIL_IF(push_inst(compiler, OR | S(SLJIT_SCRATCH_REG1) | A(SLJIT_SAVED_REG1) | B(SLJIT_SCRATCH_REG1))); if (args >= 2) - FAIL_IF(push_inst(compiler, OR | S(SLJIT_TEMPORARY_REG2) | A(SLJIT_SAVED_REG2) | B(SLJIT_TEMPORARY_REG2))); + FAIL_IF(push_inst(compiler, OR | S(SLJIT_SCRATCH_REG2) | A(SLJIT_SAVED_REG2) | B(SLJIT_SCRATCH_REG2))); if (args >= 3) - FAIL_IF(push_inst(compiler, OR | S(SLJIT_TEMPORARY_REG3) | A(SLJIT_SAVED_REG3) | B(SLJIT_TEMPORARY_REG3))); + FAIL_IF(push_inst(compiler, OR | S(SLJIT_SCRATCH_REG3) | A(SLJIT_SAVED_REG3) | B(SLJIT_SCRATCH_REG3))); #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) compiler->local_size = (1 + saveds + 6 + 8) * sizeof(sljit_sw) + local_size; @@ -544,12 +545,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si temporaries, sljit_si saveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) { CHECK_ERROR_VOID(); - check_sljit_set_context(compiler, args, temporaries, saveds, local_size); + check_sljit_set_context(compiler, args, scratches, saveds, local_size); - compiler->temporaries = temporaries; + compiler->scratches = scratches; compiler->saveds = saveds; #if (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->logical_local_size = local_size; @@ -978,21 +979,23 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si i sljit_si sugg_src2_r = TMP_REG2; sljit_si flags = input_flags & (ALT_FORM1 | ALT_FORM2 | ALT_FORM3 | ALT_FORM4 | ALT_FORM5 | ALT_FORM6 | ALT_SIGN_EXT | ALT_SET_FLAGS); - compiler->cache_arg = 0; - compiler->cache_argw = 0; + if (!(input_flags & ALT_KEEP_CACHE)) { + compiler->cache_arg = 0; + compiler->cache_argw = 0; + } /* Destination check. */ - if (dst >= SLJIT_TEMPORARY_REG1 && dst <= ZERO_REG) { + if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) + return SLJIT_SUCCESS; + dst_r = TMP_REG2; + } + else if (dst <= ZERO_REG) { dst_r = dst; flags |= REG_DEST; if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) sugg_src2_r = dst_r; } - else if (dst == SLJIT_UNUSED) { - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) - return SLJIT_SUCCESS; - dst_r = TMP_REG2; - } else { SLJIT_ASSERT(dst & SLJIT_MEM); if (getput_arg_fast(compiler, input_flags | ARG_TEST, TMP_REG2, dst, dstw)) { @@ -1006,7 +1009,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si i } /* Source 1. */ - if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= ZERO_REG) { + if (src1 <= ZERO_REG) { src1_r = src1; flags |= REG1_SOURCE; } @@ -1022,7 +1025,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si i src1_r = 0; /* Source 2. */ - if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= ZERO_REG) { + if (src2 <= ZERO_REG) { src2_r = src2; flags |= REG2_SOURCE; if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) @@ -1102,30 +1105,30 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler break; case SLJIT_UMUL: case SLJIT_SMUL: - FAIL_IF(push_inst(compiler, OR | S(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG1))); + FAIL_IF(push_inst(compiler, OR | S(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG1))); #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2))); - return push_inst(compiler, (GET_OPCODE(op) == SLJIT_UMUL ? MULHDU : MULHD) | D(SLJIT_TEMPORARY_REG2) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2)); + FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2))); + return push_inst(compiler, (GET_OPCODE(op) == SLJIT_UMUL ? MULHDU : MULHD) | D(SLJIT_SCRATCH_REG2) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2)); #else - FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2))); - return push_inst(compiler, (GET_OPCODE(op) == SLJIT_UMUL ? MULHWU : MULHW) | D(SLJIT_TEMPORARY_REG2) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2)); + FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2))); + return push_inst(compiler, (GET_OPCODE(op) == SLJIT_UMUL ? MULHWU : MULHW) | D(SLJIT_SCRATCH_REG2) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2)); #endif case SLJIT_UDIV: case SLJIT_SDIV: - FAIL_IF(push_inst(compiler, OR | S(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG1))); + FAIL_IF(push_inst(compiler, OR | S(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG1))); #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) if (op & SLJIT_INT_OP) { - FAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_UDIV ? DIVWU : DIVW) | D(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2))); - FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_TEMPORARY_REG2) | A(SLJIT_TEMPORARY_REG1) | B(SLJIT_TEMPORARY_REG2))); - return push_inst(compiler, SUBF | D(SLJIT_TEMPORARY_REG2) | A(SLJIT_TEMPORARY_REG2) | B(TMP_REG1)); + FAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_UDIV ? DIVWU : DIVW) | D(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2))); + FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_SCRATCH_REG2) | A(SLJIT_SCRATCH_REG1) | B(SLJIT_SCRATCH_REG2))); + return push_inst(compiler, SUBF | D(SLJIT_SCRATCH_REG2) | A(SLJIT_SCRATCH_REG2) | B(TMP_REG1)); } - FAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_UDIV ? DIVDU : DIVD) | D(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2))); - FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_TEMPORARY_REG2) | A(SLJIT_TEMPORARY_REG1) | B(SLJIT_TEMPORARY_REG2))); - return push_inst(compiler, SUBF | D(SLJIT_TEMPORARY_REG2) | A(SLJIT_TEMPORARY_REG2) | B(TMP_REG1)); + FAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_UDIV ? DIVDU : DIVD) | D(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2))); + FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_SCRATCH_REG2) | A(SLJIT_SCRATCH_REG1) | B(SLJIT_SCRATCH_REG2))); + return push_inst(compiler, SUBF | D(SLJIT_SCRATCH_REG2) | A(SLJIT_SCRATCH_REG2) | B(TMP_REG1)); #else - FAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_UDIV ? DIVWU : DIVW) | D(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2))); - FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_TEMPORARY_REG2) | A(SLJIT_TEMPORARY_REG1) | B(SLJIT_TEMPORARY_REG2))); - return push_inst(compiler, SUBF | D(SLJIT_TEMPORARY_REG2) | A(SLJIT_TEMPORARY_REG2) | B(TMP_REG1)); + FAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_UDIV ? DIVWU : DIVW) | D(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2))); + FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_SCRATCH_REG2) | A(SLJIT_SCRATCH_REG1) | B(SLJIT_SCRATCH_REG2))); + return push_inst(compiler, SUBF | D(SLJIT_SCRATCH_REG2) | A(SLJIT_SCRATCH_REG2) | B(TMP_REG1)); #endif } @@ -1148,7 +1151,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler ADJUST_LOCAL_OFFSET(src, srcw); op = GET_OPCODE(op); - if ((src & SLJIT_IMM) && srcw == 0 && op >= SLJIT_NOT) + if ((src & SLJIT_IMM) && srcw == 0) src = ZERO_REG; if (op_flags & SLJIT_SET_O) @@ -1156,7 +1159,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler if (op_flags & SLJIT_INT_OP) { if (op >= SLJIT_MOV && op <= SLJIT_MOVU_P) { - if (src <= SLJIT_NO_REGISTERS && src == dst) { + if (src <= ZERO_REG && src == dst) { if (!TYPE_CAST_NEEDED(op)) return SLJIT_SUCCESS; } @@ -1322,6 +1325,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler #endif if (op & SLJIT_SET_O) FAIL_IF(push_inst(compiler, MTXER | S(ZERO_REG))); + if (src2 == TMP_REG2) + flags |= ALT_KEEP_CACHE; switch (GET_OPCODE(op)) { case SLJIT_ADD: @@ -1669,15 +1674,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c check_sljit_emit_fast_enter(compiler, dst, dstw); ADJUST_LOCAL_OFFSET(dst, dstw); - if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) + /* For UNUSED dst. Uncommon, but possible. */ + if (dst == SLJIT_UNUSED) + return SLJIT_SUCCESS; + + if (dst <= ZERO_REG) return push_inst(compiler, MFLR | D(dst)); - else if (dst & SLJIT_MEM) { - FAIL_IF(push_inst(compiler, MFLR | D(TMP_REG2))); - return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0); - } - /* SLJIT_UNUSED is also possible, although highly unlikely. */ - return SLJIT_SUCCESS; + /* Memory. */ + FAIL_IF(push_inst(compiler, MFLR | D(TMP_REG2))); + return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0); } SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) @@ -1686,7 +1692,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * check_sljit_emit_fast_return(compiler, src, srcw); ADJUST_LOCAL_OFFSET(src, srcw); - if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) + if (src <= ZERO_REG) FAIL_IF(push_inst(compiler, MTLR | S(src))); else { if (src & SLJIT_MEM) @@ -1818,7 +1824,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil check_sljit_emit_ijump(compiler, type, src, srcw); ADJUST_LOCAL_OFFSET(src, srcw); - if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) + if (src <= ZERO_REG) src_r = src; else if (src & SLJIT_IMM) { jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); @@ -1853,7 +1859,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com sljit_si src, sljit_sw srcw, sljit_si type) { - sljit_si reg, flags = GET_ALL_FLAGS(op); + sljit_si reg, input_flags; + sljit_si flags = GET_ALL_FLAGS(op); CHECK_ERROR(); check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type); @@ -1863,7 +1870,21 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com return SLJIT_SUCCESS; op = GET_OPCODE(op); - reg = (op < SLJIT_ADD && dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2; + reg = (op < SLJIT_ADD && dst <= ZERO_REG) ? dst : TMP_REG2; + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + if (op >= SLJIT_ADD && (src & SLJIT_MEM)) { + ADJUST_LOCAL_OFFSET(src, srcw); +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + input_flags = (flags & SLJIT_INT_OP) ? INT_DATA : WORD_DATA; +#else + input_flags = WORD_DATA; +#endif + FAIL_IF(emit_op_mem2(compiler, input_flags | LOAD_DATA, TMP_REG1, src, srcw, dst, dstw)); + src = TMP_REG1; + srcw = 0; + } switch (type) { case SLJIT_C_EQUAL: @@ -1952,22 +1973,22 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com if (op < SLJIT_ADD) { #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) if (op == SLJIT_MOV) - flags = WORD_DATA; + input_flags = WORD_DATA; else { op = SLJIT_MOV_UI; - flags = INT_DATA; + input_flags = INT_DATA; } #else op = SLJIT_MOV; - flags = WORD_DATA; + input_flags = WORD_DATA; #endif - return (reg == TMP_REG2) ? emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, TMP_REG2, 0) : SLJIT_SUCCESS; + return (reg == TMP_REG2) ? emit_op(compiler, op, input_flags, dst, dstw, TMP_REG1, 0, TMP_REG2, 0) : SLJIT_SUCCESS; } #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->skip_checks = 1; #endif - return sljit_emit_op2(compiler, op | flags, dst, dstw, dst, dstw, TMP_REG2, 0); + return sljit_emit_op2(compiler, op | flags, dst, dstw, src, srcw, TMP_REG2, 0); } SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) @@ -1983,7 +2004,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi PTR_FAIL_IF(!const_); set_const(const_, compiler); - reg = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2; + reg = (dst <= ZERO_REG) ? dst : TMP_REG2; PTR_FAIL_IF(emit_const(compiler, reg, init_value)); diff --git a/sljit/sljitNativeSPARC_common.c b/sljit/sljitNativeSPARC_common.c index 26431e3..aa8a744 100644 --- a/sljit/sljitNativeSPARC_common.c +++ b/sljit/sljitNativeSPARC_common.c @@ -367,15 +367,17 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil #define WRITE_BACK 0x00020 #define ARG_TEST 0x00040 -#define CUMULATIVE_OP 0x00080 -#define IMM_OP 0x00100 -#define SRC2_IMM 0x00200 - -#define REG_DEST 0x00400 -#define REG2_SOURCE 0x00800 -#define SLOW_SRC1 0x01000 -#define SLOW_SRC2 0x02000 -#define SLOW_DEST 0x04000 +#define ALT_KEEP_CACHE 0x00080 +#define CUMULATIVE_OP 0x00100 +#define IMM_OP 0x00200 +#define SRC2_IMM 0x00400 + +#define REG_DEST 0x00800 +#define REG2_SOURCE 0x01000 +#define SLOW_SRC1 0x02000 +#define SLOW_SRC2 0x04000 +#define SLOW_DEST 0x08000 + /* SET_FLAGS (0x10 << 19) also belong here! */ #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) @@ -384,12 +386,12 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil #include "sljitNativeSPARC_64.c" #endif -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si temporaries, sljit_si saveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) { CHECK_ERROR(); - check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size); + check_sljit_emit_enter(compiler, args, scratches, saveds, local_size); - compiler->temporaries = temporaries; + compiler->scratches = scratches; compiler->saveds = saveds; #if (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->logical_local_size = local_size; @@ -417,12 +419,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si temporaries, sljit_si saveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) { CHECK_ERROR_VOID(); - check_sljit_set_context(compiler, args, temporaries, saveds, local_size); + check_sljit_set_context(compiler, args, scratches, saveds, local_size); - compiler->temporaries = temporaries; + compiler->scratches = scratches; compiler->saveds = saveds; #if (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->logical_local_size = local_size; @@ -437,13 +439,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi CHECK_ERROR(); check_sljit_emit_return(compiler, op, src, srcw); - if (op != SLJIT_MOV || !(src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS)) { + if (op != SLJIT_MOV || !(src <= TMP_REG3)) { FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); - src = SLJIT_TEMPORARY_REG1; + src = SLJIT_SCRATCH_REG1; } FAIL_IF(push_inst(compiler, JMPL | D(0) | S1A(31) | IMM(8), UNMOVABLE_INS)); - return push_inst(compiler, RESTORE | D(SLJIT_TEMPORARY_REG1) | S1(src) | S2(0), UNMOVABLE_INS); + return push_inst(compiler, RESTORE | D(SLJIT_SCRATCH_REG1) | S1(src) | S2(0), UNMOVABLE_INS); } /* --------------------------------------------------------------------- */ @@ -488,7 +490,7 @@ static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, { SLJIT_ASSERT(arg & SLJIT_MEM); - if (!(flags & WRITE_BACK)) { + if (!(flags & WRITE_BACK) || !(arg & 0xf)) { if ((!(arg & 0xf0) && argw <= SIMM_MAX && argw >= SIMM_MIN) || ((arg & 0xf0) && (argw & 0x3) == 0)) { /* Works for both absoulte and relative addresses (immediate case). */ @@ -621,19 +623,21 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f sljit_sw src2_r = 0; sljit_si sugg_src2_r = TMP_REG2; - compiler->cache_arg = 0; - compiler->cache_argw = 0; + if (!(flags & ALT_KEEP_CACHE)) { + compiler->cache_arg = 0; + compiler->cache_argw = 0; + } - if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REG3) { + if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) + return SLJIT_SUCCESS; + } + else if (dst <= TMP_REG3) { dst_r = dst; flags |= REG_DEST; - if (GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI) + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) sugg_src2_r = dst_r; } - else if (dst == SLJIT_UNUSED) { - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) - return SLJIT_SUCCESS; - } else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, TMP_REG1, dst, dstw)) flags |= SLOW_DEST; @@ -659,7 +663,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f } /* Source 1. */ - if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= TMP_REG3) + if (src1 <= TMP_REG3) src1_r = src1; else if (src1 & SLJIT_IMM) { if (src1w) { @@ -678,20 +682,23 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f } /* Source 2. */ - if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= TMP_REG3) { + if (src2 <= TMP_REG3) { src2_r = src2; flags |= REG2_SOURCE; - if (!(flags & REG_DEST) && GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI) + if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) dst_r = src2_r; } else if (src2 & SLJIT_IMM) { if (!(flags & SRC2_IMM)) { - if (src2w || (GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI)) { + if (src2w) { FAIL_IF(load_immediate(compiler, sugg_src2_r, src2w)); src2_r = sugg_src2_r; } - else + else { src2_r = 0; + if ((op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) && (dst & SLJIT_MEM)) + dst_r = 0; + } } } else { @@ -745,8 +752,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler case SLJIT_UMUL: case SLJIT_SMUL: #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) - FAIL_IF(push_inst(compiler, (op == SLJIT_UMUL ? UMUL : SMUL) | D(SLJIT_TEMPORARY_REG1) | S1(SLJIT_TEMPORARY_REG1) | S2(SLJIT_TEMPORARY_REG2), DR(SLJIT_TEMPORARY_REG1))); - return push_inst(compiler, RDY | D(SLJIT_TEMPORARY_REG2), DR(SLJIT_TEMPORARY_REG2)); + FAIL_IF(push_inst(compiler, (op == SLJIT_UMUL ? UMUL : SMUL) | D(SLJIT_SCRATCH_REG1) | S1(SLJIT_SCRATCH_REG1) | S2(SLJIT_SCRATCH_REG2), DR(SLJIT_SCRATCH_REG1))); + return push_inst(compiler, RDY | D(SLJIT_SCRATCH_REG2), DR(SLJIT_SCRATCH_REG2)); #else #error "Implementation required" #endif @@ -756,13 +763,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler if (op == SLJIT_UDIV) FAIL_IF(push_inst(compiler, WRY | S1(0), MOVABLE_INS)); else { - FAIL_IF(push_inst(compiler, SRA | D(TMP_REG1) | S1(SLJIT_TEMPORARY_REG1) | IMM(31), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, SRA | D(TMP_REG1) | S1(SLJIT_SCRATCH_REG1) | IMM(31), DR(TMP_REG1))); FAIL_IF(push_inst(compiler, WRY | S1(TMP_REG1), MOVABLE_INS)); } - FAIL_IF(push_inst(compiler, OR | D(TMP_REG2) | S1(0) | S2(SLJIT_TEMPORARY_REG1), DR(TMP_REG2))); - FAIL_IF(push_inst(compiler, (op == SLJIT_UDIV ? UDIV : SDIV) | D(SLJIT_TEMPORARY_REG1) | S1(SLJIT_TEMPORARY_REG1) | S2(SLJIT_TEMPORARY_REG2), DR(SLJIT_TEMPORARY_REG1))); - FAIL_IF(push_inst(compiler, SMUL | D(SLJIT_TEMPORARY_REG2) | S1(SLJIT_TEMPORARY_REG1) | S2(SLJIT_TEMPORARY_REG2), DR(SLJIT_TEMPORARY_REG2))); - FAIL_IF(push_inst(compiler, SUB | D(SLJIT_TEMPORARY_REG2) | S1(TMP_REG2) | S2(SLJIT_TEMPORARY_REG2), DR(SLJIT_TEMPORARY_REG2))); + FAIL_IF(push_inst(compiler, OR | D(TMP_REG2) | S1(0) | S2(SLJIT_SCRATCH_REG1), DR(TMP_REG2))); + FAIL_IF(push_inst(compiler, (op == SLJIT_UDIV ? UDIV : SDIV) | D(SLJIT_SCRATCH_REG1) | S1(SLJIT_SCRATCH_REG1) | S2(SLJIT_SCRATCH_REG2), DR(SLJIT_SCRATCH_REG1))); + FAIL_IF(push_inst(compiler, SMUL | D(SLJIT_SCRATCH_REG2) | S1(SLJIT_SCRATCH_REG1) | S2(SLJIT_SCRATCH_REG2), DR(SLJIT_SCRATCH_REG2))); + FAIL_IF(push_inst(compiler, SUB | D(SLJIT_SCRATCH_REG2) | S1(TMP_REG2) | S2(SLJIT_SCRATCH_REG2), DR(SLJIT_SCRATCH_REG2))); return SLJIT_SUCCESS; #else #error "Implementation required" @@ -1071,13 +1078,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c check_sljit_emit_fast_enter(compiler, dst, dstw); ADJUST_LOCAL_OFFSET(dst, dstw); - if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) + /* For UNUSED dst. Uncommon, but possible. */ + if (dst == SLJIT_UNUSED) + return SLJIT_SUCCESS; + + if (dst <= TMP_REG3) return push_inst(compiler, OR | D(dst) | S1(0) | S2(LINK_REG), DR(dst)); - else if (dst & SLJIT_MEM) - return emit_op_mem(compiler, WORD_DATA, LINK_REG, dst, dstw); - /* SLJIT_UNUSED is also possible, although highly unlikely. */ - return SLJIT_SUCCESS; + /* Memory. */ + return emit_op_mem(compiler, WORD_DATA, LINK_REG, dst, dstw); } SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) @@ -1086,7 +1095,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * check_sljit_emit_fast_return(compiler, src, srcw); ADJUST_LOCAL_OFFSET(src, srcw); - if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) + if (src <= TMP_REG3) FAIL_IF(push_inst(compiler, OR | D(LINK_REG) | S1(0) | S2(src), DR(LINK_REG))); else if (src & SLJIT_MEM) FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, LINK_REG, src, srcw)); @@ -1244,7 +1253,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil check_sljit_emit_ijump(compiler, type, src, srcw); ADJUST_LOCAL_OFFSET(src, srcw); - if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) + if (src <= TMP_REG3) src_r = src; else if (src & SLJIT_IMM) { jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); @@ -1286,7 +1295,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) op = GET_OPCODE(op); - reg = (op < SLJIT_ADD && dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2; + reg = (op < SLJIT_ADD && dst <= TMP_REG3) ? dst : TMP_REG2; + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + if (op >= SLJIT_ADD && (src & SLJIT_MEM)) { + ADJUST_LOCAL_OFFSET(src, srcw); + FAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw, dst, dstw)); + src = TMP_REG1; + srcw = 0; + } if (type < SLJIT_C_FLOAT_EQUAL) FAIL_IF(push_inst(compiler, BICC | get_cc(type) | 3, UNMOVABLE_INS)); @@ -1296,8 +1314,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com FAIL_IF(push_inst(compiler, OR | D(reg) | S1(0) | IMM(1), UNMOVABLE_INS)); FAIL_IF(push_inst(compiler, OR | D(reg) | S1(0) | IMM(0), UNMOVABLE_INS)); - if (op >= SLJIT_AND && op <= SLJIT_XOR) - return emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP, dst, dstw, dst, dstw, TMP_REG2, 0); + if (op >= SLJIT_ADD) + return emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP | ALT_KEEP_CACHE, dst, dstw, src, srcw, TMP_REG2, 0); return (reg == TMP_REG2) ? emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw) : SLJIT_SUCCESS; #else @@ -1318,7 +1336,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi PTR_FAIL_IF(!const_); set_const(const_, compiler); - reg = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2; + reg = (dst <= TMP_REG3) ? dst : TMP_REG2; PTR_FAIL_IF(emit_const(compiler, reg, init_value)); diff --git a/sljit/sljitNativeX86_32.c b/sljit/sljitNativeX86_32.c index 2c8a8b0..96791a7 100644 --- a/sljit/sljitNativeX86_32.c +++ b/sljit/sljitNativeX86_32.c @@ -63,16 +63,16 @@ static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ return code_ptr; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si temporaries, sljit_si saveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) { sljit_si size; sljit_si locals_offset; sljit_ub *inst; CHECK_ERROR(); - check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size); + check_sljit_emit_enter(compiler, args, scratches, saveds, local_size); - compiler->temporaries = temporaries; + compiler->scratches = scratches; compiler->saveds = saveds; compiler->args = args; compiler->flags_saved = 0; @@ -106,11 +106,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) if (args > 0) { *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG1] << 3) | reg_map[SLJIT_TEMPORARY_REG3]; + *inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG1] << 3) | reg_map[SLJIT_SCRATCH_REG3]; } if (args > 1) { *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG2] << 3) | reg_map[SLJIT_TEMPORARY_REG2]; + *inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG2] << 3) | reg_map[SLJIT_SCRATCH_REG2]; } if (args > 2) { *inst++ = MOV_r_rm; @@ -137,9 +137,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil #endif locals_offset = 2 * sizeof(sljit_uw); - compiler->temporaries_start = locals_offset; - if (temporaries > 3) - locals_offset += (temporaries - 3) * sizeof(sljit_uw); + compiler->scratches_start = locals_offset; + if (scratches > 3) + locals_offset += (scratches - 3) * sizeof(sljit_uw); compiler->saveds_start = locals_offset; if (saveds > 3) locals_offset += (saveds - 3) * sizeof(sljit_uw); @@ -148,7 +148,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil #ifdef _WIN32 if (local_size > 1024) { - FAIL_IF(emit_do_imm(compiler, MOV_r_i32 + reg_map[SLJIT_TEMPORARY_REG1], local_size)); + FAIL_IF(emit_do_imm(compiler, MOV_r_i32 + reg_map[SLJIT_SCRATCH_REG1], local_size)); FAIL_IF(sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_grow_stack))); } #endif @@ -161,14 +161,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si temporaries, sljit_si saveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) { sljit_si locals_offset; CHECK_ERROR_VOID(); - check_sljit_set_context(compiler, args, temporaries, saveds, local_size); + check_sljit_set_context(compiler, args, scratches, saveds, local_size); - compiler->temporaries = temporaries; + compiler->scratches = scratches; compiler->saveds = saveds; compiler->args = args; #if (defined SLJIT_DEBUG && SLJIT_DEBUG) @@ -176,9 +176,9 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, #endif locals_offset = 2 * sizeof(sljit_uw); - compiler->temporaries_start = locals_offset; - if (temporaries > 3) - locals_offset += (temporaries - 3) * sizeof(sljit_uw); + compiler->scratches_start = locals_offset; + if (scratches > 3) + locals_offset += (scratches - 3) * sizeof(sljit_uw); compiler->saveds_start = locals_offset; if (saveds > 3) locals_offset += (saveds - 3) * sizeof(sljit_uw); @@ -434,18 +434,18 @@ static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, slj INC_SIZE(type >= SLJIT_CALL3 ? 2 + 1 : 2); if (type >= SLJIT_CALL3) - PUSH_REG(reg_map[SLJIT_TEMPORARY_REG3]); + PUSH_REG(reg_map[SLJIT_SCRATCH_REG3]); *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (reg_map[SLJIT_TEMPORARY_REG3] << 3) | reg_map[SLJIT_TEMPORARY_REG1]; + *inst++ = MOD_REG | (reg_map[SLJIT_SCRATCH_REG3] << 3) | reg_map[SLJIT_SCRATCH_REG1]; #else inst = (sljit_ub*)ensure_buf(compiler, type - SLJIT_CALL0 + 1); FAIL_IF(!inst); INC_SIZE(type - SLJIT_CALL0); if (type >= SLJIT_CALL3) - PUSH_REG(reg_map[SLJIT_TEMPORARY_REG3]); + PUSH_REG(reg_map[SLJIT_SCRATCH_REG3]); if (type >= SLJIT_CALL2) - PUSH_REG(reg_map[SLJIT_TEMPORARY_REG2]); - PUSH_REG(reg_map[SLJIT_TEMPORARY_REG1]); + PUSH_REG(reg_map[SLJIT_SCRATCH_REG2]); + PUSH_REG(reg_map[SLJIT_SCRATCH_REG1]); #endif return SLJIT_SUCCESS; } @@ -460,7 +460,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c CHECK_EXTRA_REGS(dst, dstw, (void)0); - if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { + /* For UNUSED dst. Uncommon, but possible. */ + if (dst == SLJIT_UNUSED) + dst = TMP_REGISTER; + + if (dst <= TMP_REGISTER) { + /* Unused dest is possible here. */ inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); FAIL_IF(!inst); @@ -468,19 +473,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c POP_REG(reg_map[dst]); return SLJIT_SUCCESS; } - else if (dst & SLJIT_MEM) { - inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); - FAIL_IF(!inst); - *inst++ = POP_rm; - return SLJIT_SUCCESS; - } - /* For UNUSED dst. Uncommon, but possible. */ - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + /* Memory. */ + inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); FAIL_IF(!inst); - - INC_SIZE(1); - POP_REG(reg_map[TMP_REGISTER]); + *inst++ = POP_rm; return SLJIT_SUCCESS; } @@ -494,7 +491,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * CHECK_EXTRA_REGS(src, srcw, (void)0); - if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) { + if (src <= TMP_REGISTER) { inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1); FAIL_IF(!inst); diff --git a/sljit/sljitNativeX86_64.c b/sljit/sljitNativeX86_64.c index 658a361..28f04fd 100644 --- a/sljit/sljitNativeX86_64.c +++ b/sljit/sljitNativeX86_64.c @@ -87,15 +87,15 @@ static sljit_ub* generate_fixed_jump(sljit_ub *code_ptr, sljit_sw addr, sljit_si return code_ptr; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si temporaries, sljit_si saveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) { sljit_si size, pushed_size; sljit_ub *inst; CHECK_ERROR(); - check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size); + check_sljit_emit_enter(compiler, args, scratches, saveds, local_size); - compiler->temporaries = temporaries; + compiler->scratches = scratches; compiler->saveds = saveds; compiler->flags_saved = 0; #if (defined SLJIT_DEBUG && SLJIT_DEBUG) @@ -111,7 +111,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil #else if (saveds >= 4) size += saveds - 3; - if (temporaries >= 5) { + if (scratches >= 5) { size += (5 - 4) * 2; pushed_size += sizeof(sljit_sw); } @@ -155,7 +155,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil PUSH_REG(reg_lmap[SLJIT_SAVED_REG1]); } #ifdef _WIN64 - if (temporaries >= 5) { + if (scratches >= 5) { SLJIT_COMPILE_ASSERT(reg_map[SLJIT_TEMPORARY_EREG2] >= 8, temporary_ereg2_is_hireg); *inst++ = REX_B; PUSH_REG(reg_lmap[SLJIT_TEMPORARY_EREG2]); @@ -218,10 +218,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil local_size -= 4 * sizeof(sljit_sw); } /* Second instruction */ - SLJIT_COMPILE_ASSERT(reg_map[SLJIT_TEMPORARY_REG1] < 8, temporary_reg1_is_loreg); + SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SCRATCH_REG1] < 8, temporary_reg1_is_loreg); *inst++ = REX_W; *inst++ = MOV_rm_i32; - *inst++ = MOD_REG | reg_lmap[SLJIT_TEMPORARY_REG1]; + *inst++ = MOD_REG | reg_lmap[SLJIT_SCRATCH_REG1]; *(sljit_si*)inst = local_size; #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->skip_checks = 1; @@ -261,14 +261,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si temporaries, sljit_si saveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) { sljit_si pushed_size; CHECK_ERROR_VOID(); - check_sljit_set_context(compiler, args, temporaries, saveds, local_size); + check_sljit_set_context(compiler, args, scratches, saveds, local_size); - compiler->temporaries = temporaries; + compiler->scratches = scratches; compiler->saveds = saveds; #if (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->logical_local_size = local_size; @@ -277,7 +277,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, /* Including the return address saved by the call instruction. */ pushed_size = (saveds + 1) * sizeof(sljit_sw); #ifdef _WIN64 - if (temporaries >= 5) + if (scratches >= 5) pushed_size += sizeof(sljit_sw); #endif compiler->local_size = ((local_size + FIXED_LOCALS_OFFSET + pushed_size + 16 - 1) & ~(16 - 1)) - pushed_size; @@ -329,7 +329,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi #else if (compiler->saveds >= 4) size += compiler->saveds - 3; - if (compiler->temporaries >= 5) + if (compiler->scratches >= 5) size += (5 - 4) * 2; #endif inst = (sljit_ub*)ensure_buf(compiler, 1 + size); @@ -338,7 +338,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi INC_SIZE(size); #ifdef _WIN64 - if (compiler->temporaries >= 5) { + if (compiler->scratches >= 5) { *inst++ = REX_B; POP_REG(reg_lmap[SLJIT_TEMPORARY_EREG2]); } @@ -621,7 +621,7 @@ static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, slj sljit_ub *inst; #ifndef _WIN64 - SLJIT_COMPILE_ASSERT(reg_map[SLJIT_TEMPORARY_REG2] == 6 && reg_map[SLJIT_TEMPORARY_REG1] < 8 && reg_map[SLJIT_TEMPORARY_REG3] < 8, args_registers); + SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SCRATCH_REG2] == 6 && reg_map[SLJIT_SCRATCH_REG1] < 8 && reg_map[SLJIT_SCRATCH_REG3] < 8, args_registers); inst = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6)); FAIL_IF(!inst); @@ -629,13 +629,13 @@ static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, slj if (type >= SLJIT_CALL3) { *inst++ = REX_W; *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (0x2 /* rdx */ << 3) | reg_lmap[SLJIT_TEMPORARY_REG3]; + *inst++ = MOD_REG | (0x2 /* rdx */ << 3) | reg_lmap[SLJIT_SCRATCH_REG3]; } *inst++ = REX_W; *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (0x7 /* rdi */ << 3) | reg_lmap[SLJIT_TEMPORARY_REG1]; + *inst++ = MOD_REG | (0x7 /* rdi */ << 3) | reg_lmap[SLJIT_SCRATCH_REG1]; #else - SLJIT_COMPILE_ASSERT(reg_map[SLJIT_TEMPORARY_REG2] == 2 && reg_map[SLJIT_TEMPORARY_REG1] < 8 && reg_map[SLJIT_TEMPORARY_REG3] < 8, args_registers); + SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SCRATCH_REG2] == 2 && reg_map[SLJIT_SCRATCH_REG1] < 8 && reg_map[SLJIT_SCRATCH_REG3] < 8, args_registers); inst = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6)); FAIL_IF(!inst); @@ -643,11 +643,11 @@ static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, slj if (type >= SLJIT_CALL3) { *inst++ = REX_W | REX_R; *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (0x0 /* r8 */ << 3) | reg_lmap[SLJIT_TEMPORARY_REG3]; + *inst++ = MOD_REG | (0x0 /* r8 */ << 3) | reg_lmap[SLJIT_SCRATCH_REG3]; } *inst++ = REX_W; *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (0x1 /* rcx */ << 3) | reg_lmap[SLJIT_TEMPORARY_REG1]; + *inst++ = MOD_REG | (0x1 /* rcx */ << 3) | reg_lmap[SLJIT_SCRATCH_REG1]; #endif return SLJIT_SUCCESS; } @@ -664,30 +664,28 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c if (dst == SLJIT_UNUSED) dst = TMP_REGISTER; - if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) { + if (dst <= TMP_REGISTER) { if (reg_map[dst] < 8) { inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); FAIL_IF(!inst); - INC_SIZE(1); POP_REG(reg_lmap[dst]); + return SLJIT_SUCCESS; } - else { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 2); - FAIL_IF(!inst); - INC_SIZE(2); - *inst++ = REX_B; - POP_REG(reg_lmap[dst]); - } - } - else if (dst & SLJIT_MEM) { - /* REX_W is not necessary (src is not immediate). */ - compiler->mode32 = 1; - inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); + inst = (sljit_ub*)ensure_buf(compiler, 1 + 2); FAIL_IF(!inst); - *inst++ = POP_rm; + INC_SIZE(2); + *inst++ = REX_B; + POP_REG(reg_lmap[dst]); + return SLJIT_SUCCESS; } + + /* REX_W is not necessary (src is not immediate). */ + compiler->mode32 = 1; + inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); + FAIL_IF(!inst); + *inst++ = POP_rm; return SLJIT_SUCCESS; } @@ -704,7 +702,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * src = TMP_REGISTER; } - if (src >= SLJIT_TEMPORARY_REG1 && src <= TMP_REGISTER) { + if (src <= TMP_REGISTER) { if (reg_map[src] < 8) { inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1); FAIL_IF(!inst); @@ -767,7 +765,7 @@ static sljit_si emit_mov_int(struct sljit_compiler *compiler, sljit_si sign, return SLJIT_SUCCESS; /* Empty instruction. */ if (src & SLJIT_IMM) { - if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { + if (dst <= TMP_REGISTER) { if (sign || ((sljit_uw)srcw <= 0x7fffffff)) { inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_si)srcw, dst, dstw); FAIL_IF(!inst); @@ -784,9 +782,9 @@ static sljit_si emit_mov_int(struct sljit_compiler *compiler, sljit_si sign, return SLJIT_SUCCESS; } - dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_SAVED_REG3) ? dst : TMP_REGISTER; + dst_r = (dst <= TMP_REGISTER) ? dst : TMP_REGISTER; - if ((dst & SLJIT_MEM) && (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_SAVED_REG3)) + if ((dst & SLJIT_MEM) && (src <= TMP_REGISTER)) dst_r = src; else { if (sign) { diff --git a/sljit/sljitNativeX86_common.c b/sljit/sljitNativeX86_common.c index d975c06..1cd6acd 100644 --- a/sljit/sljitNativeX86_common.c +++ b/sljit/sljitNativeX86_common.c @@ -72,7 +72,7 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 2] = { #define CHECK_EXTRA_REGS(p, w, do) \ if (p >= SLJIT_TEMPORARY_EREG1 && p <= SLJIT_TEMPORARY_EREG2) { \ - w = compiler->temporaries_start + (p - SLJIT_TEMPORARY_EREG1) * sizeof(sljit_sw); \ + w = compiler->scratches_start + (p - SLJIT_TEMPORARY_EREG1) * sizeof(sljit_sw); \ p = SLJIT_MEM1(SLJIT_LOCALS_REG); \ do; \ } \ @@ -277,7 +277,7 @@ static void get_cpu_features(void) #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) -#ifdef __GNUC__ +#if defined(__GNUC__) || defined(__SUNPRO_C) /* AT&T syntax. */ asm ( "pushl %%ebx\n" @@ -299,12 +299,12 @@ static void get_cpu_features(void) mov features, edx } #else - #error "SLJIT_DETECT_SSE2 is not implemented for this C compiler" +# error "SLJIT_DETECT_SSE2 is not implemented for this C compiler" #endif #else /* SLJIT_CONFIG_X86_32 */ -#ifdef __GNUC__ +#if defined(__GNUC__) || defined(__SUNPRO_C) /* AT&T syntax. */ asm ( "pushq %%rbx\n" @@ -322,7 +322,7 @@ static void get_cpu_features(void) __cpuid(CPUInfo, 1); features = (sljit_ui)CPUInfo[3]; #else - #error "SLJIT_DETECT_SSE2 is not implemented for this C compiler" +# error "SLJIT_DETECT_SSE2 is not implemented for this C compiler" #endif #endif /* SLJIT_CONFIG_X86_32 */ @@ -668,14 +668,14 @@ static sljit_si emit_mov(struct sljit_compiler *compiler, } return SLJIT_SUCCESS; } - if (src >= SLJIT_TEMPORARY_REG1 && src <= TMP_REGISTER) { + if (src <= TMP_REGISTER) { inst = emit_x86_instruction(compiler, 1, src, 0, dst, dstw); FAIL_IF(!inst); *inst = MOV_rm_r; return SLJIT_SUCCESS; } if (src & SLJIT_IMM) { - if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) { + if (dst <= TMP_REGISTER) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) return emit_do_imm(compiler, MOV_r_i32 + reg_map[dst], srcw); #else @@ -701,7 +701,7 @@ static sljit_si emit_mov(struct sljit_compiler *compiler, *inst = MOV_rm_i32; return SLJIT_SUCCESS; } - if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) { + if (dst <= TMP_REGISTER) { inst = emit_x86_instruction(compiler, 1, dst, 0, src, srcw); FAIL_IF(!inst); *inst = MOV_r_rm; @@ -752,14 +752,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) #ifdef _WIN64 SLJIT_COMPILE_ASSERT( - reg_map[SLJIT_TEMPORARY_REG1] == 0 - && reg_map[SLJIT_TEMPORARY_REG2] == 2 + reg_map[SLJIT_SCRATCH_REG1] == 0 + && reg_map[SLJIT_SCRATCH_REG2] == 2 && reg_map[TMP_REGISTER] > 7, invalid_register_assignment_for_div_mul); #else SLJIT_COMPILE_ASSERT( - reg_map[SLJIT_TEMPORARY_REG1] == 0 - && reg_map[SLJIT_TEMPORARY_REG2] < 7 + reg_map[SLJIT_SCRATCH_REG1] == 0 + && reg_map[SLJIT_SCRATCH_REG2] < 7 && reg_map[TMP_REGISTER] == 2, invalid_register_assignment_for_div_mul); #endif @@ -769,8 +769,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler op = GET_OPCODE(op); if (op == SLJIT_UDIV) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64) - EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG2, 0); - inst = emit_x86_instruction(compiler, 1, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0); + EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_SCRATCH_REG2, 0); + inst = emit_x86_instruction(compiler, 1, SLJIT_SCRATCH_REG2, 0, SLJIT_SCRATCH_REG2, 0); #else inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, TMP_REGISTER, 0); #endif @@ -780,7 +780,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler if (op == SLJIT_SDIV) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64) - EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG2, 0); + EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_SCRATCH_REG2, 0); #endif #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) @@ -809,7 +809,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler FAIL_IF(!inst); INC_SIZE(2); *inst++ = GROUP_F7; - *inst = MOD_REG | ((op >= SLJIT_UDIV) ? reg_map[TMP_REGISTER] : reg_map[SLJIT_TEMPORARY_REG2]); + *inst = MOD_REG | ((op >= SLJIT_UDIV) ? reg_map[TMP_REGISTER] : reg_map[SLJIT_SCRATCH_REG2]); #else #ifdef _WIN64 size = (!compiler->mode32 || op >= SLJIT_UDIV) ? 3 : 2; @@ -825,12 +825,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler else if (op >= SLJIT_UDIV) *inst++ = REX_B; *inst++ = GROUP_F7; - *inst = MOD_REG | ((op >= SLJIT_UDIV) ? reg_lmap[TMP_REGISTER] : reg_lmap[SLJIT_TEMPORARY_REG2]); + *inst = MOD_REG | ((op >= SLJIT_UDIV) ? reg_lmap[TMP_REGISTER] : reg_lmap[SLJIT_SCRATCH_REG2]); #else if (!compiler->mode32) *inst++ = REX_W; *inst++ = GROUP_F7; - *inst = MOD_REG | reg_map[SLJIT_TEMPORARY_REG2]; + *inst = MOD_REG | reg_map[SLJIT_SCRATCH_REG2]; #endif #endif switch (op) { @@ -848,7 +848,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler break; } #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && !defined(_WIN64) - EMIT_MOV(compiler, SLJIT_TEMPORARY_REG2, 0, TMP_REGISTER, 0); + EMIT_MOV(compiler, SLJIT_SCRATCH_REG2, 0, TMP_REGISTER, 0); #endif break; } @@ -882,7 +882,7 @@ static sljit_si emit_mov_byte(struct sljit_compiler *compiler, sljit_si sign, return SLJIT_SUCCESS; /* Empty instruction. */ if (src & SLJIT_IMM) { - if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) { + if (dst <= TMP_REGISTER) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) return emit_do_imm(compiler, MOV_r_i32 + reg_map[dst], srcw); #else @@ -898,9 +898,9 @@ static sljit_si emit_mov_byte(struct sljit_compiler *compiler, sljit_si sign, return SLJIT_SUCCESS; } - dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) ? dst : TMP_REGISTER; + dst_r = (dst <= TMP_REGISTER) ? dst : TMP_REGISTER; - if ((dst & SLJIT_MEM) && src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) { + if ((dst & SLJIT_MEM) && src <= TMP_REGISTER) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) if (reg_map[src] >= 4) { SLJIT_ASSERT(dst_r == TMP_REGISTER); @@ -912,9 +912,9 @@ static sljit_si emit_mov_byte(struct sljit_compiler *compiler, sljit_si sign, #endif } #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - else if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS && reg_map[src] >= 4) { + else if (src <= TMP_REGISTER && reg_map[src] >= 4) { /* src, dst are registers. */ - SLJIT_ASSERT(dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER); + SLJIT_ASSERT(dst >= SLJIT_SCRATCH_REG1 && dst <= TMP_REGISTER); if (reg_map[dst] < 4) { if (dst != src) EMIT_MOV(compiler, dst, 0, src, 0); @@ -957,22 +957,22 @@ static sljit_si emit_mov_byte(struct sljit_compiler *compiler, sljit_si sign, #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) if (dst_r == TMP_REGISTER) { /* Find a non-used register, whose reg_map[src] < 4. */ - if ((dst & 0xf) == SLJIT_TEMPORARY_REG1) { - if ((dst & 0xf0) == (SLJIT_TEMPORARY_REG2 << 4)) - work_r = SLJIT_TEMPORARY_REG3; + if ((dst & 0xf) == SLJIT_SCRATCH_REG1) { + if ((dst & 0xf0) == (SLJIT_SCRATCH_REG2 << 4)) + work_r = SLJIT_SCRATCH_REG3; else - work_r = SLJIT_TEMPORARY_REG2; + work_r = SLJIT_SCRATCH_REG2; } else { - if ((dst & 0xf0) != (SLJIT_TEMPORARY_REG1 << 4)) - work_r = SLJIT_TEMPORARY_REG1; - else if ((dst & 0xf) == SLJIT_TEMPORARY_REG2) - work_r = SLJIT_TEMPORARY_REG3; + if ((dst & 0xf0) != (SLJIT_SCRATCH_REG1 << 4)) + work_r = SLJIT_SCRATCH_REG1; + else if ((dst & 0xf) == SLJIT_SCRATCH_REG2) + work_r = SLJIT_SCRATCH_REG3; else - work_r = SLJIT_TEMPORARY_REG2; + work_r = SLJIT_SCRATCH_REG2; } - if (work_r == SLJIT_TEMPORARY_REG1) { + if (work_r == SLJIT_SCRATCH_REG1) { ENCODE_PREFIX(XCHG_EAX_r + reg_map[TMP_REGISTER]); } else { @@ -985,7 +985,7 @@ static sljit_si emit_mov_byte(struct sljit_compiler *compiler, sljit_si sign, FAIL_IF(!inst); *inst = MOV_rm8_r8; - if (work_r == SLJIT_TEMPORARY_REG1) { + if (work_r == SLJIT_SCRATCH_REG1) { ENCODE_PREFIX(XCHG_EAX_r + reg_map[TMP_REGISTER]); } else { @@ -1024,7 +1024,7 @@ static sljit_si emit_mov_half(struct sljit_compiler *compiler, sljit_si sign, return SLJIT_SUCCESS; /* Empty instruction. */ if (src & SLJIT_IMM) { - if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) { + if (dst <= TMP_REGISTER) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) return emit_do_imm(compiler, MOV_r_i32 + reg_map[dst], srcw); #else @@ -1040,9 +1040,9 @@ static sljit_si emit_mov_half(struct sljit_compiler *compiler, sljit_si sign, return SLJIT_SUCCESS; } - dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) ? dst : TMP_REGISTER; + dst_r = (dst <= TMP_REGISTER) ? dst : TMP_REGISTER; - if ((dst & SLJIT_MEM) && (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS)) + if ((dst & SLJIT_MEM) && src <= TMP_REGISTER) dst_r = src; else { inst = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw); @@ -1082,7 +1082,7 @@ static sljit_si emit_unary(struct sljit_compiler *compiler, sljit_ub opcode, *inst |= opcode; return SLJIT_SUCCESS; } - if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { + if (dst <= TMP_REGISTER) { EMIT_MOV(compiler, dst, 0, src, srcw); inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); FAIL_IF(!inst); @@ -1116,7 +1116,7 @@ static sljit_si emit_not_with_flags(struct sljit_compiler *compiler, *inst = OR_r_rm; return SLJIT_SUCCESS; } - if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { + if (dst <= TMP_REGISTER) { EMIT_MOV(compiler, dst, 0, src, srcw); inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); FAIL_IF(!inst); @@ -1176,21 +1176,21 @@ static sljit_si emit_clz(struct sljit_compiler *compiler, sljit_si op_flags, *inst = BSR_r_rm; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) + if (dst <= TMP_REGISTER) dst_r = dst; else { /* Find an unused temporary register. */ - if ((dst & 0xf) != SLJIT_TEMPORARY_REG1 && (dst & 0xf0) != (SLJIT_TEMPORARY_REG1 << 4)) - dst_r = SLJIT_TEMPORARY_REG1; - else if ((dst & 0xf) != SLJIT_TEMPORARY_REG2 && (dst & 0xf0) != (SLJIT_TEMPORARY_REG2 << 4)) - dst_r = SLJIT_TEMPORARY_REG2; + if ((dst & 0xf) != SLJIT_SCRATCH_REG1 && (dst & 0xf0) != (SLJIT_SCRATCH_REG1 << 4)) + dst_r = SLJIT_SCRATCH_REG1; + else if ((dst & 0xf) != SLJIT_SCRATCH_REG2 && (dst & 0xf0) != (SLJIT_SCRATCH_REG2 << 4)) + dst_r = SLJIT_SCRATCH_REG2; else - dst_r = SLJIT_TEMPORARY_REG3; + dst_r = SLJIT_SCRATCH_REG3; EMIT_MOV(compiler, dst, dstw, dst_r, 0); } EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, 32 + 31); #else - dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) ? dst : TMP_REG2; + dst_r = (dst <= TMP_REGISTER) ? dst : TMP_REG2; compiler->mode32 = 0; EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, !(op_flags & SLJIT_INT_OP) ? 64 + 63 : 32 + 31); compiler->mode32 = op_flags & SLJIT_INT_OP; @@ -1259,7 +1259,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler sljit_si dst_is_ereg = 0; sljit_si src_is_ereg = 0; #else - #define src_is_ereg 0 +# define src_is_ereg 0 #endif CHECK_ERROR(); @@ -1280,7 +1280,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler #endif if (op_flags & SLJIT_INT_OP) { - if (src <= SLJIT_NO_REGISTERS && src == dst) { + if (src <= TMP_REGISTER && src == dst) { if (!TYPE_CAST_NEEDED(op)) return SLJIT_SUCCESS; } @@ -1413,7 +1413,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler return SLJIT_SUCCESS; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - #undef src_is_ereg +# undef src_is_ereg #endif } @@ -1471,9 +1471,9 @@ static sljit_si emit_cum_binary(struct sljit_compiler *compiler, if (dst == src1 && dstw == src1w) { if (src2 & SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if ((dst == SLJIT_TEMPORARY_REG1) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { + if ((dst == SLJIT_SCRATCH_REG1) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { #else - if ((dst == SLJIT_TEMPORARY_REG1) && (src2w > 127 || src2w < -128)) { + if ((dst == SLJIT_SCRATCH_REG1) && (src2w > 127 || src2w < -128)) { #endif BINARY_EAX_IMM(op_eax_imm, src2w); } @@ -1481,12 +1481,12 @@ static sljit_si emit_cum_binary(struct sljit_compiler *compiler, BINARY_IMM(op_imm, op_mr, src2w, dst, dstw); } } - else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { + else if (dst <= TMP_REGISTER) { inst = emit_x86_instruction(compiler, 1, dst, dstw, src2, src2w); FAIL_IF(!inst); *inst = op_rm; } - else if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= TMP_REGISTER) { + else if (src2 <= TMP_REGISTER) { /* Special exception for sljit_emit_op_flags. */ inst = emit_x86_instruction(compiler, 1, src2, src2w, dst, dstw); FAIL_IF(!inst); @@ -1505,9 +1505,9 @@ static sljit_si emit_cum_binary(struct sljit_compiler *compiler, if (dst == src2 && dstw == src2w) { if (src1 & SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if ((dst == SLJIT_TEMPORARY_REG1) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) { + if ((dst == SLJIT_SCRATCH_REG1) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) { #else - if ((dst == SLJIT_TEMPORARY_REG1) && (src1w > 127 || src1w < -128)) { + if ((dst == SLJIT_SCRATCH_REG1) && (src1w > 127 || src1w < -128)) { #endif BINARY_EAX_IMM(op_eax_imm, src1w); } @@ -1515,12 +1515,12 @@ static sljit_si emit_cum_binary(struct sljit_compiler *compiler, BINARY_IMM(op_imm, op_mr, src1w, dst, dstw); } } - else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { + else if (dst <= TMP_REGISTER) { inst = emit_x86_instruction(compiler, 1, dst, dstw, src1, src1w); FAIL_IF(!inst); *inst = op_rm; } - else if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) { + else if (src1 <= TMP_REGISTER) { inst = emit_x86_instruction(compiler, 1, src1, src1w, dst, dstw); FAIL_IF(!inst); *inst = op_mr; @@ -1535,7 +1535,7 @@ static sljit_si emit_cum_binary(struct sljit_compiler *compiler, } /* General version. */ - if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { + if (dst <= TMP_REGISTER) { EMIT_MOV(compiler, dst, 0, src1, src1w); if (src2 & SLJIT_IMM) { BINARY_IMM(op_imm, op_mr, src2w, dst, 0); @@ -1587,9 +1587,9 @@ static sljit_si emit_non_cum_binary(struct sljit_compiler *compiler, if (dst == src1 && dstw == src1w) { if (src2 & SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if ((dst == SLJIT_TEMPORARY_REG1) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { + if ((dst == SLJIT_SCRATCH_REG1) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { #else - if ((dst == SLJIT_TEMPORARY_REG1) && (src2w > 127 || src2w < -128)) { + if ((dst == SLJIT_SCRATCH_REG1) && (src2w > 127 || src2w < -128)) { #endif BINARY_EAX_IMM(op_eax_imm, src2w); } @@ -1597,12 +1597,12 @@ static sljit_si emit_non_cum_binary(struct sljit_compiler *compiler, BINARY_IMM(op_imm, op_mr, src2w, dst, dstw); } } - else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { + else if (dst <= TMP_REGISTER) { inst = emit_x86_instruction(compiler, 1, dst, dstw, src2, src2w); FAIL_IF(!inst); *inst = op_rm; } - else if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) { + else if (src2 <= TMP_REGISTER) { inst = emit_x86_instruction(compiler, 1, src2, src2w, dst, dstw); FAIL_IF(!inst); *inst = op_mr; @@ -1617,7 +1617,7 @@ static sljit_si emit_non_cum_binary(struct sljit_compiler *compiler, } /* General version. */ - if ((dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) && dst != src2) { + if (dst <= TMP_REGISTER && dst != src2) { EMIT_MOV(compiler, dst, 0, src1, src1w); if (src2 & SLJIT_IMM) { BINARY_IMM(op_imm, op_mr, src2w, dst, 0); @@ -1653,7 +1653,7 @@ static sljit_si emit_mul(struct sljit_compiler *compiler, sljit_ub* inst; sljit_si dst_r; - dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER; + dst_r = (dst <= TMP_REGISTER) ? dst : TMP_REGISTER; /* Register destination. */ if (dst_r == src1 && !(src2 & SLJIT_IMM)) { @@ -1789,10 +1789,10 @@ static sljit_si emit_lea_binary(struct sljit_compiler *compiler, if (dst == src2 && dstw == src2w) return SLJIT_ERR_UNSUPPORTED; - dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER; + dst_r = (dst <= TMP_REGISTER) ? dst : TMP_REGISTER; - if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) { - if ((src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) || src2 == TMP_REGISTER) { + if (src1 <= TMP_REGISTER) { + if (src2 <= TMP_REGISTER || src2 == TMP_REGISTER) { inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM2(src1, src2), 0); FAIL_IF(!inst); *inst = LEA_r_m; @@ -1810,7 +1810,7 @@ static sljit_si emit_lea_binary(struct sljit_compiler *compiler, done = 1; } } - else if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) { + else if (src2 <= TMP_REGISTER) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if ((src1 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src1w))) { inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), (sljit_si)src1w); @@ -1839,15 +1839,15 @@ static sljit_si emit_cmp_binary(struct sljit_compiler *compiler, sljit_ub* inst; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (src1 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { + if (src1 == SLJIT_SCRATCH_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { #else - if (src1 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) { + if (src1 == SLJIT_SCRATCH_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) { #endif BINARY_EAX_IMM(CMP_EAX_i32, src2w); return SLJIT_SUCCESS; } - if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) { + if (src1 <= TMP_REGISTER) { if (src2 & SLJIT_IMM) { BINARY_IMM(CMP, CMP_rm_r, src2w, src1, 0); } @@ -1859,7 +1859,7 @@ static sljit_si emit_cmp_binary(struct sljit_compiler *compiler, return SLJIT_SUCCESS; } - if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS && !(src1 & SLJIT_IMM)) { + if (src2 <= TMP_REGISTER && !(src1 & SLJIT_IMM)) { inst = emit_x86_instruction(compiler, 1, src2, 0, src1, src1w); FAIL_IF(!inst); *inst = CMP_rm_r; @@ -1890,24 +1890,24 @@ static sljit_si emit_test_binary(struct sljit_compiler *compiler, sljit_ub* inst; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (src1 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { + if (src1 == SLJIT_SCRATCH_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { #else - if (src1 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) { + if (src1 == SLJIT_SCRATCH_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) { #endif BINARY_EAX_IMM(TEST_EAX_i32, src2w); return SLJIT_SUCCESS; } #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (src2 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) { + if (src2 == SLJIT_SCRATCH_REG1 && (src2 & SLJIT_IMM) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) { #else - if (src2 == SLJIT_TEMPORARY_REG1 && (src1 & SLJIT_IMM) && (src1w > 127 || src1w < -128)) { + if (src2 == SLJIT_SCRATCH_REG1 && (src1 & SLJIT_IMM) && (src1w > 127 || src1w < -128)) { #endif BINARY_EAX_IMM(TEST_EAX_i32, src1w); return SLJIT_SUCCESS; } - if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) { + if (src1 <= TMP_REGISTER) { if (src2 & SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (IS_HALFWORD(src2w) || compiler->mode32) { @@ -1935,7 +1935,7 @@ static sljit_si emit_test_binary(struct sljit_compiler *compiler, return SLJIT_SUCCESS; } - if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) { + if (src2 <= TMP_REGISTER) { if (src1 & SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (IS_HALFWORD(src1w) || compiler->mode32) { @@ -2021,7 +2021,7 @@ static sljit_si emit_shift(struct sljit_compiler *compiler, EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0); return SLJIT_SUCCESS; } - if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { + if (dst <= TMP_REGISTER) { EMIT_MOV(compiler, dst, 0, src1, src1w); inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, dst, 0); FAIL_IF(!inst); @@ -2045,7 +2045,7 @@ static sljit_si emit_shift(struct sljit_compiler *compiler, *inst |= mode; EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0); } - else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS && dst != src2 && !ADDRESSING_DEPENDS_ON(src2, dst)) { + else if (dst <= TMP_REGISTER && dst != src2 && !ADDRESSING_DEPENDS_ON(src2, dst)) { if (src1 != dst) EMIT_MOV(compiler, dst, 0, src1, src1w); EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_PREF_SHIFT_REG, 0); @@ -2105,12 +2105,12 @@ static sljit_si emit_shift_with_flags(struct sljit_compiler *compiler, if (!set_flags) return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w); - if (!(dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS)) + if (!(dst <= TMP_REGISTER)) FAIL_IF(emit_cmp_binary(compiler, src1, src1w, SLJIT_IMM, 0)); FAIL_IF(emit_shift(compiler,mode, dst, dstw, src1, src1w, src2, src2w)); - if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) + if (dst <= TMP_REGISTER) return emit_cmp_binary(compiler, dst, dstw, SLJIT_IMM, 0); return SLJIT_SUCCESS; } @@ -2548,7 +2548,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil if (type >= SLJIT_CALL1) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) - if (src == SLJIT_TEMPORARY_REG3) { + if (src == SLJIT_SCRATCH_REG3) { EMIT_MOV(compiler, TMP_REGISTER, 0, src, 0); src = TMP_REGISTER; } @@ -2560,7 +2560,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil #endif #endif #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && defined(_WIN64) - if (src == SLJIT_TEMPORARY_REG3) { + if (src == SLJIT_SCRATCH_REG3) { EMIT_MOV(compiler, TMP_REGISTER, 0, src, 0); src = TMP_REGISTER; } @@ -2630,7 +2630,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com cond_set = get_jump_code(type) + 0x10; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - reg = (op == SLJIT_MOV && dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER; + reg = (op == SLJIT_MOV && dst <= TMP_REGISTER) ? dst : TMP_REGISTER; inst = (sljit_ub*)ensure_buf(compiler, 1 + 4 + 4); FAIL_IF(!inst); @@ -2657,7 +2657,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com #endif return sljit_emit_op2(compiler, op, dst, dstw, dst, dstw, TMP_REGISTER, 0); #else /* SLJIT_CONFIG_X86_64 */ - if (GET_OPCODE(op) < SLJIT_ADD && dst <= SLJIT_NO_REGISTERS) { + if (GET_OPCODE(op) < SLJIT_ADD && dst <= TMP_REGISTER) { if (reg_map[dst] <= 4) { /* Low byte is accessible. */ inst = (sljit_ub*)ensure_buf(compiler, 1 + 3 + 3); @@ -2787,7 +2787,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = 0; - reg = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER; + reg = (dst <= TMP_REGISTER) ? dst : TMP_REGISTER; if (emit_load_imm64(compiler, reg, init_value)) return NULL; |