diff --git a/API_CHANGES b/API_CHANGES index f4c5a560..6afa9750 100644 --- a/API_CHANGES +++ b/API_CHANGES @@ -1,14 +1,19 @@ This file is the short summary of the API changes: +21.02.2024 - Non-backward compatible + The sljit_set_put_label() function is renamed + to sljit_emit_mov_addr() and sljit_put_label + is merged into sljit_jump and removed. + 01.11.2023 - Non-backward compatible The SLJIT_ARG_TYPE_VOID definition is changed to SLJIT_ARG_TYPE_RET_VOID to improve Windows compatibility. -05.9.2023 - Non-backward compatible +05.09.2023 - Non-backward compatible Turn SLJIT_IMM from a flag to a single value. -10.8.2023 - Non-backward compatible +10.08.2023 - Non-backward compatible Rename SLJIT_INT_REGISTER to SLJIT_GP_REGISTER. 01.08.2023 - Non-backward compatible diff --git a/sljit_src/sljitLir.c b/sljit_src/sljitLir.c index b3785b9e..69abda6f 100644 --- a/sljit_src/sljitLir.c +++ b/sljit_src/sljitLir.c @@ -153,6 +153,7 @@ /* Jump flags. */ #define JUMP_ADDR 0x1 +#define JUMP_MOV_ADDR 0x2 /* SLJIT_REWRITABLE_JUMP is 0x1000. */ #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) @@ -200,6 +201,8 @@ # define PATCH_TYPE4 0x40 /* BL + imm24 */ # define PATCH_TYPE5 0x50 + /* addwi/subwi */ +# define PATCH_TYPE6 0x60 /* 0xf00 cc code for branches */ # define JUMP_SIZE_SHIFT 26 # define JUMP_MAX_SIZE ((sljit_uw)5) @@ -602,12 +605,6 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw } } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_put_label(struct sljit_put_label *put_label, struct sljit_label *label) -{ - if (SLJIT_LIKELY(!!put_label)) - put_label->label = label; -} - #define SLJIT_CURRENT_FLAGS_ALL \ (SLJIT_CURRENT_FLAGS_32 | SLJIT_CURRENT_FLAGS_ADD | SLJIT_CURRENT_FLAGS_SUB | SLJIT_CURRENT_FLAGS_COMPARE) @@ -712,29 +709,22 @@ static SLJIT_INLINE void reverse_buf(struct sljit_compiler *compiler) #define SLJIT_NEXT_DEFINE_TYPES \ sljit_uw next_label_size; \ sljit_uw next_jump_addr; \ - sljit_uw next_put_label_addr; \ sljit_uw next_const_addr; \ sljit_uw next_min_addr #define SLJIT_NEXT_INIT_TYPES() \ next_label_size = SLJIT_GET_NEXT_SIZE(label); \ next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump); \ - next_put_label_addr = SLJIT_GET_NEXT_ADDRESS(put_label); \ next_const_addr = SLJIT_GET_NEXT_ADDRESS(const_); #define SLJIT_GET_NEXT_MIN() \ - next_min_addr = sljit_get_next_min(next_label_size, next_jump_addr, next_put_label_addr, next_const_addr); + next_min_addr = sljit_get_next_min(next_label_size, next_jump_addr, next_const_addr); -static SLJIT_INLINE sljit_uw sljit_get_next_min(sljit_uw next_label_size, sljit_uw next_jump_addr, - sljit_uw next_put_label_addr, sljit_uw next_const_addr) +static SLJIT_INLINE sljit_uw sljit_get_next_min(sljit_uw next_label_size, + sljit_uw next_jump_addr, sljit_uw next_const_addr) { sljit_uw result = next_jump_addr; - SLJIT_ASSERT(result == SLJIT_MAX_ADDRESS || result != next_put_label_addr); - - if (next_put_label_addr < result) - result = next_put_label_addr; - SLJIT_ASSERT(result == SLJIT_MAX_ADDRESS || result != next_const_addr); if (next_const_addr < result) @@ -808,17 +798,17 @@ static SLJIT_INLINE void set_jump(struct sljit_jump *jump, struct sljit_compiler compiler->last_jump = jump; } -static SLJIT_INLINE void set_put_label(struct sljit_put_label *put_label, struct sljit_compiler *compiler, sljit_uw offset) +static SLJIT_INLINE void set_mov_addr(struct sljit_jump *jump, struct sljit_compiler *compiler, sljit_uw offset) { - put_label->next = NULL; - put_label->label = NULL; - put_label->addr = compiler->size - offset; - put_label->flags = 0; - if (compiler->last_put_label != NULL) - compiler->last_put_label->next = put_label; + jump->next = NULL; + jump->addr = compiler->size - offset; + jump->flags = JUMP_MOV_ADDR; + jump->u.label = NULL; + if (compiler->last_jump != NULL) + compiler->last_jump->next = jump; else - compiler->put_labels = put_label; - compiler->last_put_label = put_label; + compiler->jumps = jump; + compiler->last_jump = jump; } static SLJIT_INLINE void set_const(struct sljit_const *const_, struct sljit_compiler *compiler) @@ -2970,14 +2960,14 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_const(struct sljit_compil CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_mov_addr(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) FUNCTION_CHECK_DST(dst, dstw); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " put_label "); + fprintf(compiler->verbose, " mov_addr "); sljit_verbose_param(compiler, dst, dstw); fprintf(compiler->verbose, "\n"); } diff --git a/sljit_src/sljitLir.h b/sljit_src/sljitLir.h index 48d73445..0974056d 100644 --- a/sljit_src/sljitLir.h +++ b/sljit_src/sljitLir.h @@ -446,13 +446,6 @@ struct sljit_jump { } u; }; -struct sljit_put_label { - struct sljit_put_label *next; - struct sljit_label *label; - sljit_uw addr; - sljit_uw flags; -}; - struct sljit_const { struct sljit_const *next; sljit_uw addr; @@ -464,11 +457,9 @@ struct sljit_compiler { struct sljit_label *labels; struct sljit_jump *jumps; - struct sljit_put_label *put_labels; struct sljit_const *consts; struct sljit_label *last_label; struct sljit_jump *last_jump; - struct sljit_put_label *last_put_label; struct sljit_const *last_const; void *allocator_data; @@ -2156,12 +2147,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *c Flags: - (does not modify flags) */ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value); -/* Store the value of a label (see: sljit_set_put_label) +/* Store the value of a label (see: sljit_set_label / sljit_set_target) Flags: - (does not modify flags) */ -SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw); - -/* Set the value stored by put_label to this label. */ -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_put_label(struct sljit_put_label *put_label, struct sljit_label *label); +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_mov_addr(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw); /* Provides the address of label, jump and const instructions after sljit_generate_code is called. The returned value is unspecified before the sljit_generate_code call. @@ -2244,20 +2232,18 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_current_flags(struct sljit_compiler *com /* Serialization functions */ /* --------------------------------------------------------------------- */ -/* Label/jump/const/put_label enumeration functions. The items in each - group are enumerated in creation order. Serialization / deserialization - preserves this order for each group. For example the fifth label after - deserialization refers to the same machine code location as the fifth - label before the serialization. */ +/* Label/jump/const enumeration functions. The items in each group + are enumerated in creation order. Serialization / deserialization + preserves this order for each group. For example the fifth label + after deserialization refers to the same machine code location as + the fifth label before the serialization. */ static SLJIT_INLINE struct sljit_label *sljit_get_first_label(struct sljit_compiler *compiler) { return compiler->labels; } static SLJIT_INLINE struct sljit_jump *sljit_get_first_jump(struct sljit_compiler *compiler) { return compiler->jumps; } static SLJIT_INLINE struct sljit_const *sljit_get_first_const(struct sljit_compiler *compiler) { return compiler->consts; } -static SLJIT_INLINE struct sljit_put_label *sljit_get_first_put_label(struct sljit_compiler *compiler) { return compiler->put_labels; } static SLJIT_INLINE struct sljit_label *sljit_get_next_label(struct sljit_label *label) { return label->next; } static SLJIT_INLINE struct sljit_jump *sljit_get_next_jump(struct sljit_jump *jump) { return jump->next; } static SLJIT_INLINE struct sljit_const *sljit_get_next_const(struct sljit_const *const_) { return const_->next; } -static SLJIT_INLINE struct sljit_put_label *sljit_get_next_put_label(struct sljit_put_label *put_label) { return put_label->next; } /* A number starting from 0 is assigned to each label, which represents its creation index. The first label created by the @@ -2274,6 +2260,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_jump_has_label(struct sljit_jump *jump) static SLJIT_INLINE struct sljit_label *sljit_jump_get_label(struct sljit_jump *jump) { return jump->u.label; } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_jump_has_target(struct sljit_jump *jump); static SLJIT_INLINE sljit_uw sljit_jump_get_target(struct sljit_jump *jump) { return jump->u.target; } +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_jump_is_mov_addr(struct sljit_jump *jump); /* Option bits for sljit_serialize_compiler. */ @@ -2318,11 +2305,11 @@ compiler instance is returned. Otherwise the returned value is NULL. specific data similar to sljit_create_compiler() Notes: - - Labels assigned to jumps or put_labels are restored with - their corresponding label in the label set created by - the deserializer. Target addresses assigned to jumps are - also restored. Uninitialized jumps and put_labels remain - uninitialized. + - Labels assigned to jumps are restored with their + corresponding label in the label set created by + the deserializer. Target addresses assigned to + jumps are also restored. Uninitialized jumps + remain uninitialized. - After the deserialization, sljit_generate_code() does not need to be the next operation on the returned compiler, the code generation can be continued. diff --git a/sljit_src/sljitNativeARM_32.c b/sljit_src/sljitNativeARM_32.c index 56c86751..a5d8a4c6 100644 --- a/sljit_src/sljitNativeARM_32.c +++ b/sljit_src/sljitNativeARM_32.c @@ -710,16 +710,15 @@ static void set_const_value(sljit_uw addr, sljit_sw executable_offset, sljit_uw #endif /* SLJIT_CONFIG_ARM_V6 */ } -static SLJIT_INLINE sljit_sw put_label_get_length(struct sljit_put_label *put_label) +static SLJIT_INLINE sljit_sw mov_addr_get_length(struct sljit_jump *jump) { - sljit_sw diff = (sljit_sw)put_label->label->size - (sljit_sw)put_label->addr; + sljit_sw diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr; if (diff <= 0xff + 2 && diff >= -0xff + 2) { - put_label->flags = 0; + jump->flags |= PATCH_B; return 0; } - put_label->flags = 1; #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) return 0; #else /* !SLJIT_CONFIG_ARM_V6 */ @@ -734,7 +733,6 @@ static void reduce_code_size(struct sljit_compiler *compiler) struct sljit_label *label; struct sljit_jump *jump; struct sljit_const *const_; - struct sljit_put_label *put_label; SLJIT_NEXT_DEFINE_TYPES; sljit_uw total_size; sljit_uw size_reduce = 0; @@ -743,7 +741,6 @@ static void reduce_code_size(struct sljit_compiler *compiler) label = compiler->labels; jump = compiler->jumps; const_ = compiler->consts; - put_label = compiler->put_labels; SLJIT_NEXT_INIT_TYPES(); while (1) { @@ -759,8 +756,18 @@ static void reduce_code_size(struct sljit_compiler *compiler) next_label_size = SLJIT_GET_NEXT_SIZE(label); } - if (next_min_addr == next_jump_addr) { - jump->addr -= size_reduce; + if (next_min_addr == next_const_addr) { + const_->addr -= size_reduce; + const_ = const_->next; + next_const_addr = SLJIT_GET_NEXT_ADDRESS(const_); + continue; + } + + if (next_min_addr != next_jump_addr) + continue; + + jump->addr -= size_reduce; + if (!(jump->flags & JUMP_MOV_ADDR)) { total_size = JUMP_MAX_SIZE - 1; if (!(jump->flags & (SLJIT_REWRITABLE_JUMP | JUMP_ADDR))) { @@ -772,28 +779,20 @@ static void reduce_code_size(struct sljit_compiler *compiler) } size_reduce += JUMP_MAX_SIZE - 1 - total_size; - jump->flags |= total_size << JUMP_SIZE_SHIFT; - jump = jump->next; - next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump); - } else if (next_min_addr == next_put_label_addr) { - put_label->addr -= size_reduce; - + } else { /* Real size minus 1. Unit size: instruction. */ total_size = 1; - diff = (sljit_sw)put_label->label->size - (sljit_sw)put_label->addr; + diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr; if (diff <= 0xff + 2 && diff >= -0xff + 2) total_size = 0; size_reduce += 1 - total_size; - put_label->flags = total_size; - put_label = put_label->next; - next_put_label_addr = SLJIT_GET_NEXT_ADDRESS(put_label); - } else if (next_min_addr == next_const_addr) { - const_->addr -= size_reduce; - const_ = const_->next; - next_const_addr = SLJIT_GET_NEXT_ADDRESS(const_); } + + jump->flags |= total_size << JUMP_SIZE_SHIFT; + jump = jump->next; + next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump); } compiler->size -= size_reduce; @@ -825,7 +824,6 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil struct sljit_label *label; struct sljit_jump *jump; struct sljit_const *const_; - struct sljit_put_label *put_label; CHECK_ERROR_PTR(); CHECK_PTR(check_sljit_generate_code(compiler)); @@ -860,8 +858,6 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil label = compiler->labels; jump = compiler->jumps; const_ = compiler->consts; - put_label = compiler->put_labels; - SLJIT_NEXT_INIT_TYPES(); SLJIT_GET_NEXT_MIN(); @@ -893,10 +889,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_ASSERT(!label || label->size >= word_count); SLJIT_ASSERT(!jump || jump->addr >= word_count); SLJIT_ASSERT(!const_ || const_->addr >= word_count); - SLJIT_ASSERT(!put_label || put_label->addr >= word_count); if (next_min_addr == next_label_size) { - /* The word_count may be modified by jumps or put_label constructs. */ label->u.addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); label->size = (sljit_uw)(code_ptr - code); label = label->next; @@ -905,34 +899,34 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil /* These structures are ordered by their address. */ if (next_min_addr == next_jump_addr) { + if (!(jump->flags & JUMP_MOV_ADDR)) { #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) - if (detect_jump_type(jump, code_ptr, code, executable_offset)) - code_ptr--; - jump->addr = (sljit_uw)code_ptr; + if (detect_jump_type(jump, code_ptr, code, executable_offset)) + code_ptr--; + jump->addr = (sljit_uw)code_ptr; #else /* !SLJIT_CONFIG_ARM_V6 */ - word_count += jump->flags >> JUMP_SIZE_SHIFT; - jump->addr = (sljit_uw)code_ptr; - if (!detect_jump_type(jump, code_ptr, code, executable_offset)) { - code_ptr[2] = code_ptr[0]; - addr = ((code_ptr[0] & 0xf) << 12); - code_ptr[0] = MOVW | addr; - code_ptr[1] = MOVT | addr; - code_ptr += 2; - } - SLJIT_ASSERT((sljit_uw)code_ptr - jump->addr <= (jump->flags >> JUMP_SIZE_SHIFT) * sizeof(sljit_ins)); + word_count += jump->flags >> JUMP_SIZE_SHIFT; + jump->addr = (sljit_uw)code_ptr; + if (!detect_jump_type(jump, code_ptr, code, executable_offset)) { + code_ptr[2] = code_ptr[0]; + addr = ((code_ptr[0] & 0xf) << 12); + code_ptr[0] = MOVW | addr; + code_ptr[1] = MOVT | addr; + code_ptr += 2; + } + SLJIT_ASSERT((sljit_uw)code_ptr - jump->addr <= (jump->flags >> JUMP_SIZE_SHIFT) * sizeof(sljit_ins)); #endif /* SLJIT_CONFIG_ARM_V6 */ - jump = jump->next; - next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump); - } else if (next_min_addr == next_put_label_addr) { - SLJIT_ASSERT(put_label->label); + } else { + SLJIT_ASSERT(jump->u.label); #if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) - word_count += put_label->flags; + word_count += jump->flags >> JUMP_SIZE_SHIFT; #endif /* SLJIT_CONFIG_ARM_V7 */ - addr = (sljit_uw)code_ptr; - code_ptr += put_label_get_length(put_label); - put_label->addr = addr; - put_label = put_label->next; - next_put_label_addr = SLJIT_GET_NEXT_ADDRESS(put_label); + addr = (sljit_uw)code_ptr; + code_ptr += mov_addr_get_length(jump); + jump->addr = addr; + } + jump = jump->next; + next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump); } else if (next_min_addr == next_const_addr) { const_->addr = (sljit_uw)code_ptr; const_ = const_->next; @@ -973,7 +967,6 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_ASSERT(!label); SLJIT_ASSERT(!jump); SLJIT_ASSERT(!const_); - SLJIT_ASSERT(!put_label); #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) SLJIT_ASSERT(cpool_size == 0); @@ -1001,44 +994,63 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil jump = compiler->jumps; while (jump) { + addr = (jump->flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr; buf_ptr = (sljit_ins*)jump->addr; - if (jump->flags & PATCH_B) { - addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr + 2, executable_offset); - if (!(jump->flags & JUMP_ADDR)) { - SLJIT_ASSERT(jump->u.label != NULL); - SLJIT_ASSERT((sljit_sw)(jump->u.label->u.addr - addr) <= 0x01ffffff && (sljit_sw)(jump->u.label->u.addr - addr) >= -0x02000000); - *buf_ptr |= ((jump->u.label->u.addr - addr) >> 2) & 0x00ffffff; - } - else { - SLJIT_ASSERT((sljit_sw)(jump->u.target - addr) <= 0x01ffffff && (sljit_sw)(jump->u.target - addr) >= -0x02000000); - *buf_ptr |= ((jump->u.target - addr) >> 2) & 0x00ffffff; - } - } else if (jump->flags & SLJIT_REWRITABLE_JUMP) { + if (jump->flags & JUMP_MOV_ADDR) { #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) - if (jump->flags & IS_BL) - buf_ptr--; - jump->addr = (sljit_uw)code_ptr; - code_ptr[0] = (sljit_ins)buf_ptr; - code_ptr[1] = *buf_ptr; - set_jump_addr((sljit_uw)code_ptr, executable_offset, (jump->flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr, 0); - code_ptr += 2; + SLJIT_ASSERT((buf_ptr[0] & (sljit_ins)0xffff0000) == 0xe59f0000); #else /* !SLJIT_CONFIG_ARM_V6 */ - set_jump_addr((sljit_uw)buf_ptr, executable_offset, (jump->flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr, 0); + SLJIT_ASSERT((buf_ptr[0] & ~(sljit_ins)0xf000) == 0); #endif /* SLJIT_CONFIG_ARM_V6 */ + + if (jump->flags & PATCH_B) { + diff = ((sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr + 2, executable_offset)) >> 2; + + SLJIT_ASSERT(diff <= 0xff && diff >= -0xff); + + addr = ADD; + if (diff < 0) { + diff = -diff; + addr = SUB; + } + + buf_ptr[0] = addr | (buf_ptr[0] & 0xf000) | RN(TMP_PC) | (1 << 25) | (0xf << 8) | (sljit_ins)(diff & 0xff); + } else { +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) + buf_ptr[((buf_ptr[0] & 0xfff) >> 2) + 2] = addr; +#else /* !SLJIT_CONFIG_ARM_V6 */ + buf_ptr[1] = MOVT | buf_ptr[0] | ((addr >> 12) & 0xf0000) | ((addr >> 16) & 0xfff); + buf_ptr[0] = MOVW | buf_ptr[0] | ((addr << 4) & 0xf0000) | (addr & 0xfff); +#endif /* SLJIT_CONFIG_ARM_V6 */ + } + } else if (jump->flags & PATCH_B) { + diff = (sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr + 2, executable_offset); + SLJIT_ASSERT(diff <= 0x01ffffff && diff >= -0x02000000); + *buf_ptr |= (diff >> 2) & 0x00ffffff; } else { #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) if (jump->flags & IS_BL) buf_ptr--; - if (*buf_ptr & (1 << 23)) - buf_ptr += ((*buf_ptr & 0xfff) >> 2) + 2; - else - buf_ptr += 1; - *buf_ptr = (jump->flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr; + + if (jump->flags & SLJIT_REWRITABLE_JUMP) { + jump->addr = (sljit_uw)code_ptr; + code_ptr[0] = (sljit_ins)buf_ptr; + code_ptr[1] = *buf_ptr; + set_jump_addr((sljit_uw)code_ptr, executable_offset, addr, 0); + code_ptr += 2; + } else { + if (*buf_ptr & (1 << 23)) + buf_ptr += ((*buf_ptr & 0xfff) >> 2) + 2; + else + buf_ptr += 1; + *buf_ptr = addr; + } #else /* !SLJIT_CONFIG_ARM_V6 */ - set_jump_addr((sljit_uw)buf_ptr, executable_offset, (jump->flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr, 0); + set_jump_addr((sljit_uw)buf_ptr, executable_offset, addr, 0); #endif /* SLJIT_CONFIG_ARM_V6 */ } + jump = jump->next; } @@ -1062,40 +1074,6 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil } #endif /* SLJIT_CONFIG_ARM_V6 */ - put_label = compiler->put_labels; - while (put_label) { - addr = put_label->label->u.addr; - buf_ptr = (sljit_ins*)put_label->addr; - -#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) - SLJIT_ASSERT((buf_ptr[0] & (sljit_ins)0xffff0000) == 0xe59f0000); -#else /* !SLJIT_CONFIG_ARM_V6 */ - SLJIT_ASSERT((buf_ptr[0] & ~(sljit_ins)0xf000) == 0); -#endif /* SLJIT_CONFIG_ARM_V6 */ - - if (put_label->flags == 0) { - diff = ((sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr + 2, executable_offset)) >> 2; - - SLJIT_ASSERT(diff <= 0xff && diff >= -0xff); - - addr = ADD; - if (diff < 0) { - diff = -diff; - addr = SUB; - } - - buf_ptr[0] = addr | (buf_ptr[0] & 0xf000) | RN(TMP_PC) | (1 << 25) | (0xf << 8) | (sljit_ins)(diff & 0xff); - } else { -#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) - buf_ptr[((buf_ptr[0] & 0xfff) >> 2) + 2] = addr; -#else /* !SLJIT_CONFIG_ARM_V6 */ - buf_ptr[1] = MOVT | buf_ptr[0] | ((addr >> 12) & 0xf0000) | ((addr >> 16) & 0xfff); - buf_ptr[0] = MOVW | buf_ptr[0] | ((addr << 4) & 0xf0000) | (addr & 0xfff); -#endif /* SLJIT_CONFIG_ARM_V6 */ - } - put_label = put_label->next; - } - SLJIT_ASSERT(code_ptr - code <= (sljit_s32)compiler->size); compiler->error = SLJIT_ERR_COMPILED; @@ -4570,13 +4548,13 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi return const_; } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_mov_addr(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) { - struct sljit_put_label *put_label; + struct sljit_jump *jump; sljit_s32 dst_r; CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw)); + CHECK_PTR(check_sljit_emit_mov_addr(compiler, dst, dstw)); ADJUST_LOCAL_OFFSET(dst, dstw); dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2; @@ -4588,9 +4566,9 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct slj PTR_FAIL_IF(push_inst(compiler, RD(dst_r))); #endif /* SLJIT_CONFIG_ARM_V6 */ - put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label)); - PTR_FAIL_IF(!put_label); - set_put_label(put_label, compiler, 1); + jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); + PTR_FAIL_IF(!jump); + set_mov_addr(jump, compiler, 1); #if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) compiler->size += 1; @@ -4598,7 +4576,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct slj if (dst & SLJIT_MEM) PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, dst, dstw, TMP_REG1)); - return put_label; + return jump; } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset) diff --git a/sljit_src/sljitNativeARM_64.c b/sljit_src/sljitNativeARM_64.c index 5659788a..1cac4380 100644 --- a/sljit_src/sljitNativeARM_64.c +++ b/sljit_src/sljitNativeARM_64.c @@ -268,42 +268,102 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i return code_ptr + 4; } -static SLJIT_INLINE sljit_sw put_label_get_length(struct sljit_put_label *put_label, sljit_uw addr) +static SLJIT_INLINE sljit_sw mov_addr_get_length(struct sljit_jump *mov_addr, sljit_uw addr) { - sljit_sw diff = (sljit_sw)put_label->label->size - (sljit_sw)put_label->addr; + sljit_sw diff = (sljit_sw)mov_addr->u.label->size - (sljit_sw)mov_addr->addr; if (diff <= (0xfffff / SSIZE_OF(ins)) && diff >= (-0x100000 / SSIZE_OF(ins))) { - put_label->flags = 0; + mov_addr->flags |= PATCH_B; return 0; } if (diff <= (0xfffff000l / SSIZE_OF(ins)) && diff >= (-0x100000000l / SSIZE_OF(ins))) { - put_label->flags = 1; + mov_addr->flags |= PATCH_B32; return 1; } - addr += put_label->label->size; + addr += mov_addr->u.label->size; if (addr < (0x100000000l / sizeof(sljit_ins))) { - put_label->flags = 2; return 1; } if (addr < (0x1000000000000l / sizeof(sljit_ins))) { - put_label->flags = 3; + mov_addr->flags |= PATCH_ABS48; return 2; } - put_label->flags = 4; + mov_addr->flags |= PATCH_ABS64; return 3; } +static SLJIT_INLINE void generate_jump_or_mov_addr(struct sljit_jump *jump, sljit_sw executable_offset) +{ + sljit_sw addr = (sljit_sw)((jump->flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr); + sljit_ins* buf_ptr = (sljit_ins*)jump->addr; + sljit_u32 dst; + SLJIT_UNUSED_ARG(executable_offset); + + if (!(jump->flags & JUMP_MOV_ADDR)) { + if (jump->flags & PATCH_COND) { + addr = (addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) >> 2; + SLJIT_ASSERT(addr <= 0x3ffff && addr >= -0x40000); + buf_ptr[0] = (buf_ptr[0] & ~(sljit_ins)0xffffe0) | (sljit_ins)((addr & 0x7ffff) << 5); + return; + } + + if (jump->flags & PATCH_B) { + addr = (addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) >> 2; + SLJIT_ASSERT(addr <= 0x1ffffff && addr >= -0x2000000); + buf_ptr[0] = ((jump->flags & IS_BL) ? BL : B) | (sljit_ins)(addr & 0x3ffffff); + return; + } + + dst = (buf_ptr[0] >> 5) & 0x1f; + + if (jump->flags & PATCH_B32) { + addr -= (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset) & ~(sljit_sw)0xfff; + SLJIT_ASSERT(addr <= 0xfffff000l && addr >= -0x100000000l); + buf_ptr[0] = ADRP | (((sljit_ins)(addr >> 12) & 0x3) << 29) | (((sljit_ins)(addr >> 14) & 0x7ffff) << 5) | dst; + buf_ptr[1] = ADDI | dst | (dst << 5) | ((sljit_ins)(addr & 0xfff) << 10); + return; + } + } else { + dst = *buf_ptr; + + if (jump->flags & PATCH_B) { + addr -= (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset); + SLJIT_ASSERT(addr <= 0xfffff && addr >= -0x100000); + buf_ptr[0] = ADR | (((sljit_ins)addr & 0x3) << 29) | (((sljit_ins)(addr >> 2) & 0x7ffff) << 5) | dst; + return; + } + + if (jump->flags & PATCH_B32) { + addr -= ((sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) & ~(sljit_sw)0xfff; + SLJIT_ASSERT(addr <= 0xffffffffl && addr >= -0x100000000l); + buf_ptr[0] = ADRP | (((sljit_ins)(addr >> 12) & 0x3) << 29) | (((sljit_ins)(addr >> 14) & 0x7ffff) << 5) | dst; + buf_ptr[1] = ADDI | dst | (dst << 5) | ((sljit_ins)(addr & 0xfff) << 10); + return; + } + } + + SLJIT_ASSERT((jump->flags & (PATCH_ABS48 | PATCH_ABS64)) || (sljit_uw)addr <= (sljit_uw)0xffffffff); + SLJIT_ASSERT((jump->flags & PATCH_ABS64) || (sljit_uw)addr <= (sljit_uw)0xffffffffffff); + + buf_ptr[0] = MOVZ | (((sljit_ins)addr & 0xffff) << 5) | dst; + buf_ptr[1] = MOVK | (((sljit_ins)(addr >> 16) & 0xffff) << 5) | (1 << 21) | dst; + if (jump->flags & (PATCH_ABS48 | PATCH_ABS64)) + buf_ptr[2] = MOVK | (((sljit_ins)(addr >> 32) & 0xffff) << 5) | (2 << 21) | dst; + + if (jump->flags & PATCH_ABS64) + buf_ptr[3] = MOVK | ((sljit_ins)(addr >> 48) << 5) | (3 << 21) | dst; +} + static void reduce_code_size(struct sljit_compiler *compiler) { struct sljit_label *label; struct sljit_jump *jump; struct sljit_const *const_; - struct sljit_put_label *put_label; SLJIT_NEXT_DEFINE_TYPES; sljit_uw total_size; sljit_uw size_reduce = 0; @@ -312,7 +372,6 @@ static void reduce_code_size(struct sljit_compiler *compiler) label = compiler->labels; jump = compiler->jumps; const_ = compiler->consts; - put_label = compiler->put_labels; SLJIT_NEXT_INIT_TYPES(); while (1) { @@ -328,8 +387,18 @@ static void reduce_code_size(struct sljit_compiler *compiler) next_label_size = SLJIT_GET_NEXT_SIZE(label); } - if (next_min_addr == next_jump_addr) { - jump->addr -= size_reduce; + if (next_min_addr == next_const_addr) { + const_->addr -= size_reduce; + const_ = const_->next; + next_const_addr = SLJIT_GET_NEXT_ADDRESS(const_); + continue; + } + + if (next_min_addr != next_jump_addr) + continue; + + jump->addr -= size_reduce; + if (!(jump->flags & JUMP_MOV_ADDR)) { total_size = JUMP_MAX_SIZE; if (!(jump->flags & SLJIT_REWRITABLE_JUMP)) { @@ -352,15 +421,10 @@ static void reduce_code_size(struct sljit_compiler *compiler) } size_reduce += JUMP_MAX_SIZE - total_size; - jump->flags |= total_size << JUMP_SIZE_SHIFT; - jump = jump->next; - next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump); - } else if (next_min_addr == next_put_label_addr) { - put_label->addr -= size_reduce; - + } else { /* Real size minus 1. Unit size: instruction. */ total_size = 3; - diff = (sljit_sw)put_label->label->size - (sljit_sw)put_label->addr; + diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr; if (diff <= (0xfffff / SSIZE_OF(ins)) && diff >= (-0x100000 / SSIZE_OF(ins))) total_size = 0; @@ -368,14 +432,11 @@ static void reduce_code_size(struct sljit_compiler *compiler) total_size = 1; size_reduce += 3 - total_size; - put_label->flags = total_size; - put_label = put_label->next; - next_put_label_addr = SLJIT_GET_NEXT_ADDRESS(put_label); - } else if (next_min_addr == next_const_addr) { - const_->addr -= size_reduce; - const_ = const_->next; - next_const_addr = SLJIT_GET_NEXT_ADDRESS(const_); } + + jump->flags |= total_size << JUMP_SIZE_SHIFT; + jump = jump->next; + next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump); } compiler->size -= size_reduce; @@ -392,12 +453,10 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_NEXT_DEFINE_TYPES; sljit_sw executable_offset; sljit_sw addr; - sljit_u32 dst; struct sljit_label *label; struct sljit_jump *jump; struct sljit_const *const_; - struct sljit_put_label *put_label; CHECK_ERROR_PTR(); CHECK_PTR(check_sljit_generate_code(compiler)); @@ -417,7 +476,6 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil label = compiler->labels; jump = compiler->jumps; const_ = compiler->consts; - put_label = compiler->put_labels; SLJIT_NEXT_INIT_TYPES(); SLJIT_GET_NEXT_MIN(); @@ -430,7 +488,6 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_ASSERT(!label || label->size >= word_count); SLJIT_ASSERT(!jump || jump->addr >= word_count); SLJIT_ASSERT(!const_ || const_->addr >= word_count); - SLJIT_ASSERT(!put_label || put_label->addr >= word_count); /* These structures are ordered by their address. */ if (next_min_addr == next_label_size) { @@ -441,20 +498,21 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil } if (next_min_addr == next_jump_addr) { - word_count = word_count - 1 + (jump->flags >> JUMP_SIZE_SHIFT); - jump->addr = (sljit_uw)code_ptr; - code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset); - SLJIT_ASSERT((jump->flags & PATCH_COND) || ((sljit_uw)code_ptr - jump->addr < (jump->flags >> JUMP_SIZE_SHIFT) * sizeof(sljit_ins))); + if (!(jump->flags & JUMP_MOV_ADDR)) { + word_count = word_count - 1 + (jump->flags >> JUMP_SIZE_SHIFT); + jump->addr = (sljit_uw)code_ptr; + code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset); + SLJIT_ASSERT((jump->flags & PATCH_COND) || ((sljit_uw)code_ptr - jump->addr < (jump->flags >> JUMP_SIZE_SHIFT) * sizeof(sljit_ins))); + } else { + SLJIT_ASSERT(jump->u.label); + word_count += jump->flags >> JUMP_SIZE_SHIFT; + addr = (sljit_sw)code_ptr; + code_ptr += mov_addr_get_length(jump, (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code, executable_offset)); + jump->addr = (sljit_uw)addr; + } + jump = jump->next; next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump); - } else if (next_min_addr == next_put_label_addr) { - SLJIT_ASSERT(put_label->label); - word_count += put_label->flags; - addr = (sljit_sw)code_ptr; - code_ptr += put_label_get_length(put_label, (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code, executable_offset)); - put_label->addr = (sljit_uw)addr; - put_label = put_label->next; - next_put_label_addr = SLJIT_GET_NEXT_ADDRESS(put_label); } else if (next_min_addr == next_const_addr) { const_->addr = (sljit_uw)code_ptr; const_ = const_->next; @@ -479,81 +537,14 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_ASSERT(!label); SLJIT_ASSERT(!jump); SLJIT_ASSERT(!const_); - SLJIT_ASSERT(!put_label); SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size); jump = compiler->jumps; while (jump) { - do { - addr = (sljit_sw)((jump->flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr); - buf_ptr = (sljit_ins *)jump->addr; - - if (jump->flags & PATCH_COND) { - addr = (addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) >> 2; - SLJIT_ASSERT(addr <= 0x3ffff && addr >= -0x40000); - buf_ptr[0] = (buf_ptr[0] & ~(sljit_ins)0xffffe0) | (sljit_ins)((addr & 0x7ffff) << 5); - break; - } - - if (jump->flags & PATCH_B) { - addr = (addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) >> 2; - SLJIT_ASSERT(addr <= 0x1ffffff && addr >= -0x2000000); - buf_ptr[0] = ((jump->flags & IS_BL) ? BL : B) | (sljit_ins)(addr & 0x3ffffff); - break; - } - - dst = (buf_ptr[0] >> 5) & 0x1f; - - if (jump->flags & PATCH_B32) { - addr -= (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset) & ~(sljit_sw)0xfff; - SLJIT_ASSERT(addr <= 0xfffff000l && addr >= -0x100000000l); - buf_ptr[0] = ADRP | (((sljit_ins)(addr >> 12) & 0x3) << 29) | (((sljit_ins)(addr >> 14) & 0x7ffff) << 5) | dst; - buf_ptr[1] = ADDI | dst | (dst << 5) | ((sljit_ins)(addr & 0xfff) << 10); - break; - } - - SLJIT_ASSERT((jump->flags & (PATCH_ABS48 | PATCH_ABS64)) || (sljit_uw)addr <= (sljit_uw)0xffffffff); - SLJIT_ASSERT((jump->flags & PATCH_ABS64) || (sljit_uw)addr <= (sljit_uw)0xffffffffffff); - - buf_ptr[0] = MOVZ | dst | (((sljit_ins)addr & 0xffff) << 5); - buf_ptr[1] = MOVK | dst | (((sljit_ins)(addr >> 16) & 0xffff) << 5) | (1 << 21); - if (jump->flags & (PATCH_ABS48 | PATCH_ABS64)) - buf_ptr[2] = MOVK | dst | (((sljit_ins)(addr >> 32) & 0xffff) << 5) | (2 << 21); - if (jump->flags & PATCH_ABS64) - buf_ptr[3] = MOVK | dst | ((sljit_ins)(addr >> 48) << 5) | (3 << 21); - } while (0); + generate_jump_or_mov_addr(jump, executable_offset); jump = jump->next; } - put_label = compiler->put_labels; - while (put_label) { - addr = (sljit_sw)put_label->label->u.addr; - buf_ptr = (sljit_ins*)put_label->addr; - dst = *buf_ptr; - - if (put_label->flags == 0) { - addr -= (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset); - SLJIT_ASSERT(addr <= 0xfffff && addr >= -0x100000); - buf_ptr[0] = ADR | (((sljit_ins)addr & 0x3) << 29) | (((sljit_ins)(addr >> 2) & 0x7ffff) << 5) | dst; - } else if (put_label->flags == 1) { - addr -= ((sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) & ~(sljit_sw)0xfff; - SLJIT_ASSERT(addr <= 0xffffffffl && addr >= -0x100000000l); - buf_ptr[0] = ADRP | (((sljit_ins)(addr >> 12) & 0x3) << 29) | (((sljit_ins)(addr >> 14) & 0x7ffff) << 5) | dst; - buf_ptr[1] = ADDI | dst | (dst << 5) | ((sljit_ins)(addr & 0xfff) << 10); - } else { - buf_ptr[0] = MOVZ | (((sljit_ins)addr & 0xffff) << 5) | dst; - buf_ptr[1] = MOVK | (((sljit_ins)(addr >> 16) & 0xffff) << 5) | (1 << 21) | dst; - - if (put_label->flags >= 3) - buf_ptr[2] = MOVK | (((sljit_ins)(addr >> 32) & 0xffff) << 5) | (2 << 21) | dst; - - if (put_label->flags >= 4) - buf_ptr[3] = MOVK | ((sljit_ins)(addr >> 48) << 5) | (3 << 21) | dst; - } - - put_label = put_label->next; - } - compiler->error = SLJIT_ERR_COMPILED; compiler->executable_offset = executable_offset; compiler->executable_size = (sljit_uw)(code_ptr - code) * sizeof(sljit_ins); @@ -3408,28 +3399,28 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi return const_; } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_mov_addr(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) { - struct sljit_put_label *put_label; + struct sljit_jump *jump; sljit_s32 dst_r; CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw)); + CHECK_PTR(check_sljit_emit_mov_addr(compiler, dst, dstw)); ADJUST_LOCAL_OFFSET(dst, dstw); dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; PTR_FAIL_IF(push_inst(compiler, RD(dst_r))); - put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label)); - PTR_FAIL_IF(!put_label); - set_put_label(put_label, compiler, 1); + jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); + PTR_FAIL_IF(!jump); + set_mov_addr(jump, compiler, 1); compiler->size += 3; if (dst & SLJIT_MEM) PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw, TMP_REG2)); - return put_label; + return jump; } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset) diff --git a/sljit_src/sljitNativeARM_T2_32.c b/sljit_src/sljitNativeARM_T2_32.c index 3ea542d5..a07ecb4e 100644 --- a/sljit_src/sljitNativeARM_T2_32.c +++ b/sljit_src/sljitNativeARM_T2_32.c @@ -376,25 +376,54 @@ static SLJIT_INLINE sljit_u16* detect_jump_type(struct sljit_jump *jump, sljit_u return code_ptr + 4; } -static SLJIT_INLINE void set_jump_instruction(struct sljit_jump *jump, sljit_sw executable_offset) +static SLJIT_INLINE sljit_sw mov_addr_get_length(struct sljit_jump *jump) +{ + sljit_sw diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr; + + /* Note: ADR with imm8 does not set the last bit (Thumb2 flag). */ + + if (diff <= (0xffd / SSIZE_OF(u16)) && diff >= (-0xfff / SSIZE_OF(u16))) { + jump->flags |= PATCH_TYPE6; + return 1; + } + + return 3; +} + +static SLJIT_INLINE void generate_jump_or_mov_addr(struct sljit_jump *jump, sljit_sw executable_offset) { sljit_s32 type = (jump->flags >> 4) & 0xf; + sljit_u16 *jump_inst = (sljit_u16*)jump->addr; sljit_sw diff; - sljit_u16 *jump_inst; + sljit_ins ins; + + diff = (sljit_sw)((jump->flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr); if (SLJIT_UNLIKELY(type == 0)) { - set_imm32_const((sljit_u16*)jump->addr, RDN3(TMP_REG1), (jump->flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr); + ins = (jump->flags & JUMP_MOV_ADDR) ? *jump_inst : RDN3(TMP_REG1); + set_imm32_const((sljit_u16*)jump->addr, ins, (sljit_uw)diff); return; } - if (jump->flags & JUMP_ADDR) { - SLJIT_ASSERT(jump->u.target & 0x1); - diff = ((sljit_sw)jump->u.target - (sljit_sw)(jump->addr + sizeof(sljit_u32)) - executable_offset) >> 1; - } else { - SLJIT_ASSERT(jump->u.label->u.addr & 0x1); - diff = ((sljit_sw)(jump->u.label->u.addr) - (sljit_sw)(jump->addr + sizeof(sljit_u32)) - executable_offset) >> 1; + if (SLJIT_UNLIKELY(type == 6)) { + SLJIT_ASSERT(jump->flags & JUMP_MOV_ADDR); + diff -= ((sljit_sw)SLJIT_ADD_EXEC_OFFSET(jump_inst, executable_offset) + (2 * SSIZE_OF(u16))) & ~(sljit_sw)0x3; + + SLJIT_ASSERT(diff <= 0xfff && diff >= -0xfff); + + ins = ADDWI >> 16; + if (diff <= 0) { + diff = -diff; + ins = SUBWI >> 16; + } + + jump_inst[1] = (sljit_u16)(jump_inst[0] | COPY_BITS(diff, 8, 12, 3) | (diff & 0xff)); + jump_inst[0] = (sljit_u16)(ins | 0xf | COPY_BITS(diff, 11, 10, 1)); + return; } - jump_inst = (sljit_u16*)jump->addr; + + SLJIT_ASSERT((diff & 0x1) != 0 && !(jump->flags & JUMP_MOV_ADDR)); + diff = (diff - (sljit_sw)(jump->addr + sizeof(sljit_u32)) - executable_offset) >> 1; switch (type) { case 1: @@ -432,27 +461,11 @@ static SLJIT_INLINE void set_jump_instruction(struct sljit_jump *jump, sljit_sw jump_inst[1] |= 0xd000; } -static SLJIT_INLINE sljit_sw put_label_get_length(struct sljit_put_label *put_label) -{ - sljit_sw diff = (sljit_sw)put_label->label->size - (sljit_sw)put_label->addr; - - /* Note: ADR with imm8 does not set the last bit (Thumb2 flag). */ - - if (diff <= (0xffd / SSIZE_OF(u16)) && diff >= (-0xfff / SSIZE_OF(u16))) { - put_label->flags = 0; - return 1; - } - - put_label->flags = 1; - return 3; -} - static void reduce_code_size(struct sljit_compiler *compiler) { struct sljit_label *label; struct sljit_jump *jump; struct sljit_const *const_; - struct sljit_put_label *put_label; SLJIT_NEXT_DEFINE_TYPES; sljit_uw total_size; sljit_uw size_reduce = 0; @@ -461,7 +474,6 @@ static void reduce_code_size(struct sljit_compiler *compiler) label = compiler->labels; jump = compiler->jumps; const_ = compiler->consts; - put_label = compiler->put_labels; SLJIT_NEXT_INIT_TYPES(); while (1) { @@ -477,8 +489,18 @@ static void reduce_code_size(struct sljit_compiler *compiler) next_label_size = SLJIT_GET_NEXT_SIZE(label); } - if (next_min_addr == next_jump_addr) { - jump->addr -= size_reduce; + if (next_min_addr == next_const_addr) { + const_->addr -= size_reduce; + const_ = const_->next; + next_const_addr = SLJIT_GET_NEXT_ADDRESS(const_); + continue; + } + + if (next_min_addr != next_jump_addr) + continue; + + jump->addr -= size_reduce; + if (!(jump->flags & JUMP_MOV_ADDR)) { total_size = JUMP_MAX_SIZE; if (!(jump->flags & (SLJIT_REWRITABLE_JUMP | JUMP_ADDR))) { @@ -501,28 +523,20 @@ static void reduce_code_size(struct sljit_compiler *compiler) } size_reduce += JUMP_MAX_SIZE - total_size; - jump->flags |= total_size << JUMP_SIZE_SHIFT; - jump = jump->next; - next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump); - } else if (next_min_addr == next_put_label_addr) { - put_label->addr -= size_reduce; - + } else { /* Real size minus 1. Unit size: instruction. */ total_size = 3; - diff = (sljit_sw)put_label->label->size - (sljit_sw)put_label->addr; + diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr; if (diff <= (0xffd / SSIZE_OF(u16)) && diff >= (-0xfff / SSIZE_OF(u16))) total_size = 1; size_reduce += 3 - total_size; - put_label->flags = total_size; - put_label = put_label->next; - next_put_label_addr = SLJIT_GET_NEXT_ADDRESS(put_label); - } else if (next_min_addr == next_const_addr) { - const_->addr -= size_reduce; - const_ = const_->next; - next_const_addr = SLJIT_GET_NEXT_ADDRESS(const_); } + + jump->flags |= total_size << JUMP_SIZE_SHIFT; + jump = jump->next; + next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump); } compiler->size -= size_reduce; @@ -537,14 +551,12 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil sljit_u16 *buf_end; sljit_uw half_count; SLJIT_NEXT_DEFINE_TYPES; - sljit_ins ins; sljit_sw addr; sljit_sw executable_offset; struct sljit_label *label; struct sljit_jump *jump; struct sljit_const *const_; - struct sljit_put_label *put_label; CHECK_ERROR_PTR(); CHECK_PTR(check_sljit_generate_code(compiler)); @@ -564,7 +576,6 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil label = compiler->labels; jump = compiler->jumps; const_ = compiler->consts; - put_label = compiler->put_labels; SLJIT_NEXT_INIT_TYPES(); SLJIT_GET_NEXT_MIN(); @@ -577,7 +588,6 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_ASSERT(!label || label->size >= half_count); SLJIT_ASSERT(!jump || jump->addr >= half_count); SLJIT_ASSERT(!const_ || const_->addr >= half_count); - SLJIT_ASSERT(!put_label || put_label->addr >= half_count); /* These structures are ordered by their address. */ if (next_min_addr == next_label_size) { @@ -588,21 +598,22 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil } if (next_min_addr == next_jump_addr) { + if (!(jump->flags & JUMP_MOV_ADDR)) { half_count = half_count - 1 + (jump->flags >> JUMP_SIZE_SHIFT); jump->addr = (sljit_uw)code_ptr; code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset); SLJIT_ASSERT((sljit_uw)code_ptr - jump->addr < ((jump->flags >> JUMP_SIZE_SHIFT) + ((jump->flags & 0xf0) <= PATCH_TYPE2)) * sizeof(sljit_u16)); - jump = jump->next; - next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump); - } else if (next_min_addr == next_put_label_addr) { - SLJIT_ASSERT(put_label->label); - half_count += put_label->flags; - addr = (sljit_sw)code_ptr; - code_ptr += put_label_get_length(put_label); - put_label->addr = (sljit_uw)addr; - put_label = put_label->next; - next_put_label_addr = SLJIT_GET_NEXT_ADDRESS(put_label); + } else { + SLJIT_ASSERT(jump->u.label); + half_count += jump->flags >> JUMP_SIZE_SHIFT; + addr = (sljit_sw)code_ptr; + code_ptr += mov_addr_get_length(jump); + jump->addr = (sljit_uw)addr; + } + + jump = jump->next; + next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump); } else if (next_min_addr == next_const_addr) { const_->addr = (sljit_uw)code_ptr; const_ = const_->next; @@ -627,39 +638,14 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_ASSERT(!label); SLJIT_ASSERT(!jump); SLJIT_ASSERT(!const_); - SLJIT_ASSERT(!put_label); SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size); jump = compiler->jumps; while (jump) { - set_jump_instruction(jump, executable_offset); + generate_jump_or_mov_addr(jump, executable_offset); jump = jump->next; } - put_label = compiler->put_labels; - while (put_label) { - buf_ptr = (sljit_u16 *)put_label->addr; - - if (put_label->flags == 0) { - addr = ((sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset) + (2 * SSIZE_OF(u16))) & ~(sljit_sw)0x3; - addr = (sljit_sw)put_label->label->u.addr - addr; - - SLJIT_ASSERT(addr <= 0xfff && addr >= -0xfff); - - ins = ADDWI >> 16; - if (addr <= 0) { - addr = -addr; - ins = SUBWI >> 16; - } - - buf_ptr[1] = (sljit_u16)(buf_ptr[0] | COPY_BITS(addr, 8, 12, 3) | (addr & 0xff)); - buf_ptr[0] = (sljit_u16)(ins | 0xf | COPY_BITS(addr, 11, 10, 1)); - } else - set_imm32_const(buf_ptr, *buf_ptr, put_label->label->u.addr); - - put_label = put_label->next; - } - compiler->error = SLJIT_ERR_COMPILED; compiler->executable_offset = executable_offset; compiler->executable_size = (sljit_uw)(code_ptr - code) * sizeof(sljit_u16); @@ -4244,18 +4230,18 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi return const_; } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_mov_addr(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) { - struct sljit_put_label *put_label; + struct sljit_jump *jump; sljit_s32 dst_r; CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw)); + CHECK_PTR(check_sljit_emit_mov_addr(compiler, dst, dstw)); ADJUST_LOCAL_OFFSET(dst, dstw); - put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label)); - PTR_FAIL_IF(!put_label); - set_put_label(put_label, compiler, 0); + jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); + PTR_FAIL_IF(!jump); + set_mov_addr(jump, compiler, 0); dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; PTR_FAIL_IF(push_inst16(compiler, RDN3(dst_r))); @@ -4263,7 +4249,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct slj if (dst & SLJIT_MEM) PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw, TMP_REG2)); - return put_label; + return jump; } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset) diff --git a/sljit_src/sljitNativeMIPS_common.c b/sljit_src/sljitNativeMIPS_common.c index fa123548..c6ae4f0c 100644 --- a/sljit_src/sljitNativeMIPS_common.c +++ b/sljit_src/sljitNativeMIPS_common.c @@ -635,72 +635,55 @@ static __attribute__ ((noinline)) void sljit_cache_flush(void* code, void* code_ #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) -static SLJIT_INLINE sljit_sw put_label_get_length(struct sljit_put_label *put_label, sljit_uw max_label) +static SLJIT_INLINE sljit_sw mov_addr_get_length(struct sljit_jump *jump, sljit_uw max_label) { if (max_label < 0x80000000l) { - put_label->flags = PATCH_ABS32; + jump->flags |= PATCH_ABS32; return 1; } if (max_label < 0x800000000000l) { - put_label->flags = PATCH_ABS48; + jump->flags |= PATCH_ABS48; return 3; } - put_label->flags = 0; return 5; } #endif /* SLJIT_CONFIG_MIPS_64 */ -static SLJIT_INLINE void load_addr_to_reg(void *dst, sljit_u32 reg) +static SLJIT_INLINE void load_addr_to_reg(struct sljit_jump *jump) { - struct sljit_jump *jump; - struct sljit_put_label *put_label; - sljit_uw flags; - sljit_ins *inst; - sljit_uw addr; - - if (reg != 0) { - jump = (struct sljit_jump*)dst; - flags = jump->flags; - inst = (sljit_ins*)jump->addr; - addr = (flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr; - } else { - put_label = (struct sljit_put_label*)dst; -#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) - flags = put_label->flags; -#endif - inst = (sljit_ins*)put_label->addr; - addr = put_label->label->u.addr; - reg = *inst; - } + sljit_uw flags = jump->flags; + sljit_ins *ins = (sljit_ins*)jump->addr; + sljit_uw addr = (flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr; + sljit_u32 reg = (flags & JUMP_MOV_ADDR) ? *ins : PIC_ADDR_REG; #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) - inst[0] = LUI | T(reg) | IMM(addr >> 16); + ins[0] = LUI | T(reg) | IMM(addr >> 16); #else /* !SLJIT_CONFIG_MIPS_32 */ if (flags & PATCH_ABS32) { SLJIT_ASSERT(addr < 0x80000000l); - inst[0] = LUI | T(reg) | IMM(addr >> 16); + ins[0] = LUI | T(reg) | IMM(addr >> 16); } else if (flags & PATCH_ABS48) { SLJIT_ASSERT(addr < 0x800000000000l); - inst[0] = LUI | T(reg) | IMM(addr >> 32); - inst[1] = ORI | S(reg) | T(reg) | IMM((addr >> 16) & 0xffff); - inst[2] = DSLL | T(reg) | D(reg) | SH_IMM(16); - inst += 2; + ins[0] = LUI | T(reg) | IMM(addr >> 32); + ins[1] = ORI | S(reg) | T(reg) | IMM((addr >> 16) & 0xffff); + ins[2] = DSLL | T(reg) | D(reg) | SH_IMM(16); + ins += 2; } else { - inst[0] = LUI | T(reg) | IMM(addr >> 48); - inst[1] = ORI | S(reg) | T(reg) | IMM((addr >> 32) & 0xffff); - inst[2] = DSLL | T(reg) | D(reg) | SH_IMM(16); - inst[3] = ORI | S(reg) | T(reg) | IMM((addr >> 16) & 0xffff); - inst[4] = DSLL | T(reg) | D(reg) | SH_IMM(16); - inst += 4; + ins[0] = LUI | T(reg) | IMM(addr >> 48); + ins[1] = ORI | S(reg) | T(reg) | IMM((addr >> 32) & 0xffff); + ins[2] = DSLL | T(reg) | D(reg) | SH_IMM(16); + ins[3] = ORI | S(reg) | T(reg) | IMM((addr >> 16) & 0xffff); + ins[4] = DSLL | T(reg) | D(reg) | SH_IMM(16); + ins += 4; } #endif /* SLJIT_CONFIG_MIPS_32 */ - inst[1] = ORI | S(reg) | T(reg) | IMM(addr & 0xffff); + ins[1] = ORI | S(reg) | T(reg) | IMM(addr & 0xffff); } SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) @@ -714,11 +697,9 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_NEXT_DEFINE_TYPES; sljit_sw executable_offset; sljit_uw addr; - struct sljit_label *label; struct sljit_jump *jump; struct sljit_const *const_; - struct sljit_put_label *put_label; CHECK_ERROR_PTR(); CHECK_PTR(check_sljit_generate_code(compiler)); @@ -735,7 +716,6 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil label = compiler->labels; jump = compiler->jumps; const_ = compiler->consts; - put_label = compiler->put_labels; SLJIT_NEXT_INIT_TYPES(); SLJIT_GET_NEXT_MIN(); @@ -748,7 +728,6 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_ASSERT(!label || label->size >= word_count); SLJIT_ASSERT(!jump || jump->addr >= word_count); SLJIT_ASSERT(!const_ || const_->addr >= word_count); - SLJIT_ASSERT(!put_label || put_label->addr >= word_count); /* These structures are ordered by their address. */ if (next_min_addr == next_label_size) { @@ -759,27 +738,28 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil } if (next_min_addr == next_jump_addr) { + if (!(jump->flags & JUMP_MOV_ADDR)) { #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) - word_count += 2; -#else - word_count += 6; -#endif - jump->addr = (sljit_uw)(code_ptr - 1); - code_ptr = detect_jump_type(jump, code, executable_offset); + word_count += 2; +#else /* !SLJIT_CONFIG_MIPS_32 */ + word_count += 6; +#endif /* SLJIT_CONFIG_MIPS_32 */ + jump->addr = (sljit_uw)(code_ptr - 1); + code_ptr = detect_jump_type(jump, code, executable_offset); + } else { + SLJIT_ASSERT(jump->u.label); + jump->addr = (sljit_uw)code_ptr; +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) + code_ptr += 1; + word_count += 1; +#else /* !SLJIT_CONFIG_MIPS_32 */ + code_ptr += mov_addr_get_length(jump, (sljit_uw)(SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + jump->u.label->size)); + word_count += 5; +#endif /* SLJIT_CONFIG_MIPS_32 */ + } + jump = jump->next; next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump); - } else if (next_min_addr == next_put_label_addr) { - SLJIT_ASSERT(put_label->label); - put_label->addr = (sljit_uw)code_ptr; -#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) - code_ptr += 1; - word_count += 1; -#else - code_ptr += put_label_get_length(put_label, (sljit_uw)(SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + put_label->label->size)); - word_count += 5; -#endif - put_label = put_label->next; - next_put_label_addr = SLJIT_GET_NEXT_ADDRESS(put_label); } else if (next_min_addr == next_const_addr) { const_->addr = (sljit_uw)code_ptr; const_ = const_->next; @@ -804,7 +784,6 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_ASSERT(!label); SLJIT_ASSERT(!jump); SLJIT_ASSERT(!const_); - SLJIT_ASSERT(!put_label); SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size); jump = compiler->jumps; @@ -826,15 +805,10 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil break; } - load_addr_to_reg(jump, PIC_ADDR_REG); + load_addr_to_reg(jump); } while (0); - jump = jump->next; - } - put_label = compiler->put_labels; - while (put_label) { - load_addr_to_reg(put_label, 0); - put_label = put_label->next; + jump = jump->next; } compiler->error = SLJIT_ERR_COMPILED; @@ -4236,18 +4210,18 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi return const_; } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_mov_addr(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) { - struct sljit_put_label *put_label; + struct sljit_jump *jump; sljit_s32 dst_r; CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw)); + CHECK_PTR(check_sljit_emit_mov_addr(compiler, dst, dstw)); ADJUST_LOCAL_OFFSET(dst, dstw); - put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label)); - PTR_FAIL_IF(!put_label); - set_put_label(put_label, compiler, 0); + jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); + PTR_FAIL_IF(!jump); + set_mov_addr(jump, compiler, 0); dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2; PTR_FAIL_IF(push_inst(compiler, (sljit_ins)dst_r, UNMOVABLE_INS)); @@ -4260,5 +4234,5 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct slj if (dst & SLJIT_MEM) PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, DR(TMP_REG2), dst, dstw)); - return put_label; + return jump; } diff --git a/sljit_src/sljitNativePPC_common.c b/sljit_src/sljitNativePPC_common.c index 9decd481..effa87d5 100644 --- a/sljit_src/sljitNativePPC_common.c +++ b/sljit_src/sljitNativePPC_common.c @@ -399,55 +399,84 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) -static SLJIT_INLINE sljit_sw put_label_get_length(struct sljit_put_label *put_label, sljit_uw max_label) +static SLJIT_INLINE sljit_sw mov_addr_get_length(struct sljit_jump *jump, sljit_uw max_label) { if (max_label < 0x80000000l) { - put_label->flags = PATCH_ABS32; + jump->flags |= PATCH_ABS32; return 1; } if (max_label < 0x800000000000l) { - put_label->flags = PATCH_ABS48; + jump->flags |= PATCH_ABS48; return 3; } - put_label->flags = 0; return 4; } #endif /* SLJIT_CONFIG_PPC_64 */ -static void load_addr_to_reg(sljit_ins *buf_ptr, sljit_uw addr, sljit_s32 reg, sljit_uw flags) +static void generate_jump_or_mov_addr(struct sljit_jump *jump, sljit_sw executable_offset) { - SLJIT_UNUSED_ARG(flags); + sljit_uw flags = jump->flags; + sljit_uw addr = (flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr; + sljit_ins *ins = (sljit_ins*)jump->addr; + sljit_s32 reg; + SLJIT_UNUSED_ARG(executable_offset); + + if (flags & PATCH_B) { + if (flags & IS_COND) { + if (!(flags & PATCH_ABS_B)) { + addr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET(ins, executable_offset); + SLJIT_ASSERT((sljit_sw)addr <= 0x7fff && (sljit_sw)addr >= -0x8000); + ins[0] = BCx | ((sljit_ins)addr & 0xfffc) | (ins[0] & 0x03ff0001); + } else { + SLJIT_ASSERT(addr <= 0xffff); + ins[0] = BCx | ((sljit_ins)addr & 0xfffc) | 0x2 | ((*ins) & 0x03ff0001); + } + return; + } + + if (!(flags & PATCH_ABS_B)) { + addr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET(ins, executable_offset); + SLJIT_ASSERT((sljit_sw)addr <= 0x01ffffff && (sljit_sw)addr >= -0x02000000); + ins[0] = Bx | ((sljit_ins)addr & 0x03fffffc) | (ins[0] & 0x1); + } else { + SLJIT_ASSERT(addr <= 0x03ffffff); + ins[0] = Bx | ((sljit_ins)addr & 0x03fffffc) | 0x2 | (ins[0] & 0x1); + } + return; + } + + reg = (flags & JUMP_MOV_ADDR) ? (sljit_s32)ins[0] : TMP_CALL_REG; #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) - buf_ptr[0] = ADDIS | D(reg) | A(0) | IMM(addr >> 16); - buf_ptr[1] = ORI | S(reg) | A(reg) | IMM(addr); + ins[0] = ADDIS | D(reg) | A(0) | IMM(addr >> 16); + ins[1] = ORI | S(reg) | A(reg) | IMM(addr); #else /* !SLJIT_CONFIG_PPC_32 */ /* The TMP_ZERO cannot be used because it is restored for tail calls. */ if (flags & PATCH_ABS32) { SLJIT_ASSERT(addr < 0x80000000l); - buf_ptr[0] = ADDIS | D(reg) | A(0) | IMM(addr >> 16); - buf_ptr[1] = ORI | S(reg) | A(reg) | IMM(addr); + ins[0] = ADDIS | D(reg) | A(0) | IMM(addr >> 16); + ins[1] = ORI | S(reg) | A(reg) | IMM(addr); return; } if (flags & PATCH_ABS48) { SLJIT_ASSERT(addr < 0x800000000000l); - buf_ptr[0] = ADDIS | D(reg) | A(0) | IMM(addr >> 32); - buf_ptr[1] = ORI | S(reg) | A(reg) | IMM(addr >> 16); - buf_ptr[2] = SLDI(16) | S(reg) | A(reg); - buf_ptr[3] = ORI | S(reg) | A(reg) | IMM(addr); + ins[0] = ADDIS | D(reg) | A(0) | IMM(addr >> 32); + ins[1] = ORI | S(reg) | A(reg) | IMM(addr >> 16); + ins[2] = SLDI(16) | S(reg) | A(reg); + ins[3] = ORI | S(reg) | A(reg) | IMM(addr); return; } - buf_ptr[0] = ADDIS | D(reg) | A(0) | IMM(addr >> 48); - buf_ptr[1] = ORI | S(reg) | A(reg) | IMM(addr >> 32); - buf_ptr[2] = SLDI(32) | S(reg) | A(reg); - buf_ptr[3] = ORIS | S(reg) | A(reg) | IMM(addr >> 16); - buf_ptr[4] = ORI | S(reg) | A(reg) | IMM(addr); + ins[0] = ADDIS | D(reg) | A(0) | IMM(addr >> 48); + ins[1] = ORI | S(reg) | A(reg) | IMM(addr >> 32); + ins[2] = SLDI(32) | S(reg) | A(reg); + ins[3] = ORIS | S(reg) | A(reg) | IMM(addr >> 16); + ins[4] = ORI | S(reg) | A(reg) | IMM(addr); #endif /* SLJIT_CONFIG_PPC_32 */ } @@ -456,7 +485,6 @@ static void reduce_code_size(struct sljit_compiler *compiler) struct sljit_label *label; struct sljit_jump *jump; struct sljit_const *const_; - struct sljit_put_label *put_label; SLJIT_NEXT_DEFINE_TYPES; sljit_uw total_size; sljit_uw size_reduce = 0; @@ -465,7 +493,6 @@ static void reduce_code_size(struct sljit_compiler *compiler) label = compiler->labels; jump = compiler->jumps; const_ = compiler->consts; - put_label = compiler->put_labels; SLJIT_NEXT_INIT_TYPES(); while (1) { @@ -481,8 +508,18 @@ static void reduce_code_size(struct sljit_compiler *compiler) next_label_size = SLJIT_GET_NEXT_SIZE(label); } - if (next_min_addr == next_jump_addr) { - jump->addr -= size_reduce; + if (next_min_addr == next_const_addr) { + const_->addr -= size_reduce; + const_ = const_->next; + next_const_addr = SLJIT_GET_NEXT_ADDRESS(const_); + continue; + } + + if (next_min_addr != next_jump_addr) + continue; + + jump->addr -= size_reduce; + if (!(jump->flags & JUMP_MOV_ADDR)) { total_size = JUMP_MAX_SIZE - 1; if (!(jump->flags & SLJIT_REWRITABLE_JUMP)) { @@ -511,17 +548,10 @@ static void reduce_code_size(struct sljit_compiler *compiler) size_reduce += (JUMP_MAX_SIZE - 1) - total_size; jump->flags |= total_size << JUMP_SIZE_SHIFT; - jump = jump->next; - next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump); - } else if (next_min_addr == next_put_label_addr) { - put_label->addr -= size_reduce; - put_label = put_label->next; - next_put_label_addr = SLJIT_GET_NEXT_ADDRESS(put_label); - } else if (next_min_addr == next_const_addr) { - const_->addr -= size_reduce; - const_ = const_->next; - next_const_addr = SLJIT_GET_NEXT_ADDRESS(const_); } + + jump = jump->next; + next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump); } compiler->size -= size_reduce; @@ -537,12 +567,10 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil sljit_uw word_count; SLJIT_NEXT_DEFINE_TYPES; sljit_sw executable_offset; - sljit_uw addr; struct sljit_label *label; struct sljit_jump *jump; struct sljit_const *const_; - struct sljit_put_label *put_label; CHECK_ERROR_PTR(); CHECK_PTR(check_sljit_generate_code(compiler)); @@ -570,7 +598,6 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil label = compiler->labels; jump = compiler->jumps; const_ = compiler->consts; - put_label = compiler->put_labels; SLJIT_NEXT_INIT_TYPES(); SLJIT_GET_NEXT_MIN(); @@ -583,7 +610,6 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_ASSERT(!label || label->size >= word_count); SLJIT_ASSERT(!jump || jump->addr >= word_count); SLJIT_ASSERT(!const_ || const_->addr >= word_count); - SLJIT_ASSERT(!put_label || put_label->addr >= word_count); /* These structures are ordered by their address. */ if (next_min_addr == next_label_size) { @@ -595,24 +621,24 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil } if (next_min_addr == next_jump_addr) { - word_count += jump->flags >> JUMP_SIZE_SHIFT; - jump->addr = (sljit_uw)code_ptr; - code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset); - SLJIT_ASSERT(((sljit_uw)code_ptr - jump->addr <= (jump->flags >> JUMP_SIZE_SHIFT) * sizeof(sljit_ins))); - jump = jump->next; - next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump); - } else if (next_min_addr == next_put_label_addr) { - SLJIT_ASSERT(put_label->label); - put_label->addr = (sljit_uw)code_ptr; + if (!(jump->flags & JUMP_MOV_ADDR)) { + word_count += jump->flags >> JUMP_SIZE_SHIFT; + jump->addr = (sljit_uw)code_ptr; + code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset); + SLJIT_ASSERT(((sljit_uw)code_ptr - jump->addr <= (jump->flags >> JUMP_SIZE_SHIFT) * sizeof(sljit_ins))); + } else { + SLJIT_ASSERT(jump->u.label); + jump->addr = (sljit_uw)code_ptr; #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - code_ptr += put_label_get_length(put_label, (sljit_uw)(SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + put_label->label->size)); - word_count += 4; + code_ptr += mov_addr_get_length(jump, (sljit_uw)(SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + jump->u.label->size)); + word_count += 4; #else /* !SLJIT_CONFIG_PPC_64 */ - code_ptr++; - word_count++; + code_ptr++; + word_count++; #endif /* SLJIT_CONFIG_PPC_64 */ - put_label = put_label->next; - next_put_label_addr = SLJIT_GET_NEXT_ADDRESS(put_label); + } + jump = jump->next; + next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump); } else if (next_min_addr == next_const_addr) { const_->addr = (sljit_uw)code_ptr; const_ = const_->next; @@ -637,7 +663,6 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_ASSERT(!label); SLJIT_ASSERT(!jump); SLJIT_ASSERT(!const_); - SLJIT_ASSERT(!put_label); #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) SLJIT_ASSERT(code_ptr - code <= (sljit_sw)(compiler->size - (sizeof(struct sljit_function_context) / sizeof(sljit_ins)))); @@ -647,46 +672,10 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil jump = compiler->jumps; while (jump) { - do { - addr = (jump->flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr; - buf_ptr = (sljit_ins *)jump->addr; - - if (jump->flags & PATCH_B) { - if (jump->flags & IS_COND) { - if (!(jump->flags & PATCH_ABS_B)) { - addr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset); - SLJIT_ASSERT((sljit_sw)addr <= 0x7fff && (sljit_sw)addr >= -0x8000); - *buf_ptr = BCx | ((sljit_ins)addr & 0xfffc) | ((*buf_ptr) & 0x03ff0001); - } else { - SLJIT_ASSERT(addr <= 0xffff); - *buf_ptr = BCx | ((sljit_ins)addr & 0xfffc) | 0x2 | ((*buf_ptr) & 0x03ff0001); - } - } else { - if (!(jump->flags & PATCH_ABS_B)) { - addr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset); - SLJIT_ASSERT((sljit_sw)addr <= 0x01ffffff && (sljit_sw)addr >= -0x02000000); - *buf_ptr = Bx | ((sljit_ins)addr & 0x03fffffc) | ((*buf_ptr) & 0x1); - } else { - SLJIT_ASSERT(addr <= 0x03ffffff); - *buf_ptr = Bx | ((sljit_ins)addr & 0x03fffffc) | 0x2 | ((*buf_ptr) & 0x1); - } - } - break; - } - - /* Set the fields of immediate loads. */ - load_addr_to_reg(buf_ptr, addr, TMP_CALL_REG, jump->flags); - } while (0); + generate_jump_or_mov_addr(jump, executable_offset); jump = jump->next; } - put_label = compiler->put_labels; - while (put_label) { - buf_ptr = (sljit_ins *)put_label->addr; - load_addr_to_reg(buf_ptr, put_label->label->u.addr, (sljit_s32)buf_ptr[0], put_label->flags); - put_label = put_label->next; - } - compiler->error = SLJIT_ERR_COMPILED; compiler->executable_offset = executable_offset; @@ -3099,18 +3088,18 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi return const_; } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_mov_addr(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) { - struct sljit_put_label *put_label; + struct sljit_jump *jump; sljit_s32 dst_r; CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw)); + CHECK_PTR(check_sljit_emit_mov_addr(compiler, dst, dstw)); ADJUST_LOCAL_OFFSET(dst, dstw); - put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label)); - PTR_FAIL_IF(!put_label); - set_put_label(put_label, compiler, 0); + jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); + PTR_FAIL_IF(!jump); + set_mov_addr(jump, compiler, 0); dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2; PTR_FAIL_IF(push_inst(compiler, (sljit_ins)dst_r)); @@ -3123,7 +3112,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct slj if (dst & SLJIT_MEM) PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0)); - return put_label; + return jump; } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset) diff --git a/sljit_src/sljitNativeRISCV_common.c b/sljit_src/sljitNativeRISCV_common.c index 52d4d1f3..9857f1e9 100644 --- a/sljit_src/sljitNativeRISCV_common.c +++ b/sljit_src/sljitNativeRISCV_common.c @@ -264,81 +264,64 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i #if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) -static SLJIT_INLINE sljit_sw put_label_get_length(struct sljit_put_label *put_label, sljit_uw addr) +static SLJIT_INLINE sljit_sw mov_addr_get_length(struct sljit_jump *jump, sljit_uw addr) { - sljit_sw diff = (sljit_sw)put_label->label->size - (sljit_sw)put_label->addr; + sljit_sw diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr; if (diff >= (S32_MIN / SSIZE_OF(ins)) && diff <= (S32_MAX / SSIZE_OF(ins))) { - put_label->flags = PATCH_REL32; + jump->flags |= PATCH_REL32; return 1; } - addr += put_label->label->size; + addr += jump->u.label->size; if (addr <= (S32_MAX / sizeof(sljit_ins))) { - put_label->flags = PATCH_ABS32; + jump->flags |= PATCH_ABS32; return 1; } if (addr <= (S44_MAX / sizeof(sljit_ins))) { - put_label->flags = PATCH_ABS44; + jump->flags |= PATCH_ABS44; return 3; } if (addr <= (S52_MAX / sizeof(sljit_ins))) { - put_label->flags = PATCH_ABS52; + jump->flags |= PATCH_ABS52; return 4; } - put_label->flags = 0; return 5; } #endif /* SLJIT_CONFIG_RISCV_64 */ -static SLJIT_INLINE void load_addr_to_reg(void *dst, sljit_u32 reg, sljit_sw executable_offset) +static SLJIT_INLINE void load_addr_to_reg(struct sljit_jump *jump, sljit_sw executable_offset) { - struct sljit_jump *jump = NULL; - struct sljit_put_label *put_label; - sljit_uw flags; - sljit_ins *inst; + sljit_uw flags = jump->flags; + sljit_uw addr = (flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr; + sljit_ins *ins = (sljit_ins*)jump->addr; + sljit_u32 reg = (flags & JUMP_MOV_ADDR) ? *ins : TMP_REG1; #if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) sljit_sw high; #endif - sljit_uw addr; SLJIT_UNUSED_ARG(executable_offset); - if (reg != 0) { - jump = (struct sljit_jump*)dst; - flags = jump->flags; - inst = (sljit_ins*)jump->addr; - addr = (flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr; - } else { - put_label = (struct sljit_put_label*)dst; -#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) - flags = put_label->flags; -#endif - inst = (sljit_ins*)put_label->addr; - addr = put_label->label->u.addr; - reg = *inst; - } - #if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) if (flags & PATCH_REL32) { - addr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); + addr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET(ins, executable_offset); SLJIT_ASSERT((sljit_sw)addr >= S32_MIN && (sljit_sw)addr <= S32_MAX); if ((addr & 0x800) != 0) addr += 0x1000; - inst[0] = AUIPC | RD(reg) | (sljit_ins)((sljit_sw)addr & ~0xfff); + ins[0] = AUIPC | RD(reg) | (sljit_ins)((sljit_sw)addr & ~0xfff); - if (jump != NULL) { - SLJIT_ASSERT((inst[1] & 0x707f) == JALR); - inst[1] = (inst[1] & 0xfffff) | IMM_I(addr); + if (!(flags & JUMP_MOV_ADDR)) { + SLJIT_ASSERT((ins[1] & 0x707f) == JALR); + ins[1] = (ins[1] & 0xfffff) | IMM_I(addr); } else - inst[1] = ADDI | RD(reg) | RS1(reg) | IMM_I(addr); + ins[1] = ADDI | RD(reg) | RS1(reg) | IMM_I(addr); return; } #endif @@ -347,30 +330,30 @@ static SLJIT_INLINE void load_addr_to_reg(void *dst, sljit_u32 reg, sljit_sw exe addr += 0x1000; #if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) - inst[0] = LUI | RD(reg) | (sljit_ins)((sljit_sw)addr & ~0xfff); + ins[0] = LUI | RD(reg) | (sljit_ins)((sljit_sw)addr & ~0xfff); #else /* !SLJIT_CONFIG_RISCV_32 */ if (flags & PATCH_ABS32) { SLJIT_ASSERT(addr <= S32_MAX); - inst[0] = LUI | RD(reg) | (sljit_ins)((sljit_sw)addr & ~0xfff); + ins[0] = LUI | RD(reg) | (sljit_ins)((sljit_sw)addr & ~0xfff); } else if (flags & PATCH_ABS44) { high = (sljit_sw)addr >> 12; SLJIT_ASSERT((sljit_uw)high <= 0x7fffffff); if (high > S32_MAX) { SLJIT_ASSERT((high & 0x800) != 0); - inst[0] = LUI | RD(reg) | (sljit_ins)0x80000000u; - inst[1] = XORI | RD(reg) | RS1(reg) | IMM_I(high); + ins[0] = LUI | RD(reg) | (sljit_ins)0x80000000u; + ins[1] = XORI | RD(reg) | RS1(reg) | IMM_I(high); } else { if ((high & 0x800) != 0) high += 0x1000; - inst[0] = LUI | RD(reg) | (sljit_ins)(high & ~0xfff); - inst[1] = ADDI | RD(reg) | RS1(reg) | IMM_I(high); + ins[0] = LUI | RD(reg) | (sljit_ins)(high & ~0xfff); + ins[1] = ADDI | RD(reg) | RS1(reg) | IMM_I(high); } - inst[2] = SLLI | RD(reg) | RS1(reg) | IMM_I(12); - inst += 2; + ins[2] = SLLI | RD(reg) | RS1(reg) | IMM_I(12); + ins += 2; } else { high = (sljit_sw)addr >> 32; @@ -379,27 +362,27 @@ static SLJIT_INLINE void load_addr_to_reg(void *dst, sljit_u32 reg, sljit_sw exe if (flags & PATCH_ABS52) { SLJIT_ASSERT(addr <= S52_MAX); - inst[0] = LUI | RD(TMP_REG3) | (sljit_ins)(high << 12); + ins[0] = LUI | RD(TMP_REG3) | (sljit_ins)(high << 12); } else { if ((high & 0x800) != 0) high += 0x1000; - inst[0] = LUI | RD(TMP_REG3) | (sljit_ins)(high & ~0xfff); - inst[1] = ADDI | RD(TMP_REG3) | RS1(TMP_REG3) | IMM_I(high); - inst++; + ins[0] = LUI | RD(TMP_REG3) | (sljit_ins)(high & ~0xfff); + ins[1] = ADDI | RD(TMP_REG3) | RS1(TMP_REG3) | IMM_I(high); + ins++; } - inst[1] = LUI | RD(reg) | (sljit_ins)((sljit_sw)addr & ~0xfff); - inst[2] = SLLI | RD(TMP_REG3) | RS1(TMP_REG3) | IMM_I((flags & PATCH_ABS52) ? 20 : 32); - inst[3] = XOR | RD(reg) | RS1(reg) | RS2(TMP_REG3); - inst += 3; + ins[1] = LUI | RD(reg) | (sljit_ins)((sljit_sw)addr & ~0xfff); + ins[2] = SLLI | RD(TMP_REG3) | RS1(TMP_REG3) | IMM_I((flags & PATCH_ABS52) ? 20 : 32); + ins[3] = XOR | RD(reg) | RS1(reg) | RS2(TMP_REG3); + ins += 3; } #endif /* !SLJIT_CONFIG_RISCV_32 */ - if (jump != NULL) { - SLJIT_ASSERT((inst[1] & 0x707f) == JALR); - inst[1] = (inst[1] & 0xfffff) | IMM_I(addr); + if (!(flags & JUMP_MOV_ADDR)) { + SLJIT_ASSERT((ins[1] & 0x707f) == JALR); + ins[1] = (ins[1] & 0xfffff) | IMM_I(addr); } else - inst[1] = ADDI | RD(reg) | RS1(reg) | IMM_I(addr); + ins[1] = ADDI | RD(reg) | RS1(reg) | IMM_I(addr); } static void reduce_code_size(struct sljit_compiler *compiler) @@ -407,7 +390,6 @@ static void reduce_code_size(struct sljit_compiler *compiler) struct sljit_label *label; struct sljit_jump *jump; struct sljit_const *const_; - struct sljit_put_label *put_label; SLJIT_NEXT_DEFINE_TYPES; sljit_uw total_size; sljit_uw size_reduce = 0; @@ -416,7 +398,6 @@ static void reduce_code_size(struct sljit_compiler *compiler) label = compiler->labels; jump = compiler->jumps; const_ = compiler->consts; - put_label = compiler->put_labels; SLJIT_NEXT_INIT_TYPES(); while (1) { @@ -432,8 +413,18 @@ static void reduce_code_size(struct sljit_compiler *compiler) next_label_size = SLJIT_GET_NEXT_SIZE(label); } - if (next_min_addr == next_jump_addr) { - jump->addr -= size_reduce; + if (next_min_addr == next_const_addr) { + const_->addr -= size_reduce; + const_ = const_->next; + next_const_addr = SLJIT_GET_NEXT_ADDRESS(const_); + continue; + } + + if (next_min_addr != next_jump_addr) + continue; + + jump->addr -= size_reduce; + if (!(jump->flags & JUMP_MOV_ADDR)) { total_size = JUMP_MAX_SIZE; if (!(jump->flags & SLJIT_REWRITABLE_JUMP)) { @@ -463,29 +454,21 @@ static void reduce_code_size(struct sljit_compiler *compiler) size_reduce += JUMP_MAX_SIZE - total_size; jump->flags |= total_size << JUMP_SIZE_SHIFT; - jump = jump->next; - next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump); - } else if (next_min_addr == next_put_label_addr) { - put_label->addr -= size_reduce; - + } else { #if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) /* Real size minus 1. Unit size: instruction. */ - diff = (sljit_sw)put_label->label->size - (sljit_sw)put_label->addr; + diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr; if (diff >= (S32_MIN / SSIZE_OF(ins)) && diff <= (S32_MAX / SSIZE_OF(ins))) { size_reduce += 4; - put_label->flags = 1; + jump->flags |= (sljit_uw)1 << JUMP_SIZE_SHIFT; } else - put_label->flags = 5; + jump->flags |= (sljit_uw)5 << JUMP_SIZE_SHIFT; #endif /* !SLJIT_CONFIG_RISCV_64 */ - - put_label = put_label->next; - next_put_label_addr = SLJIT_GET_NEXT_ADDRESS(put_label); - } else if (next_min_addr == next_const_addr) { - const_->addr -= size_reduce; - const_ = const_->next; - next_const_addr = SLJIT_GET_NEXT_ADDRESS(const_); } + + jump = jump->next; + next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump); } compiler->size -= size_reduce; @@ -506,7 +489,6 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil struct sljit_label *label; struct sljit_jump *jump; struct sljit_const *const_; - struct sljit_put_label *put_label; CHECK_ERROR_PTR(); CHECK_PTR(check_sljit_generate_code(compiler)); @@ -526,7 +508,6 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil label = compiler->labels; jump = compiler->jumps; const_ = compiler->consts; - put_label = compiler->put_labels; SLJIT_NEXT_INIT_TYPES(); SLJIT_GET_NEXT_MIN(); @@ -539,7 +520,6 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_ASSERT(!label || label->size >= word_count); SLJIT_ASSERT(!jump || jump->addr >= word_count); SLJIT_ASSERT(!const_ || const_->addr >= word_count); - SLJIT_ASSERT(!put_label || put_label->addr >= word_count); /* These structures are ordered by their address. */ if (next_min_addr == next_label_size) { @@ -550,26 +530,26 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil } if (next_min_addr == next_jump_addr) { - word_count = word_count - 1 + (jump->flags >> JUMP_SIZE_SHIFT); - jump->addr = (sljit_uw)code_ptr; - code_ptr = detect_jump_type(jump, code, executable_offset); - SLJIT_ASSERT((jump->flags & PATCH_B) || ((sljit_uw)code_ptr - jump->addr < (jump->flags >> JUMP_SIZE_SHIFT) * sizeof(sljit_ins))); - jump = jump->next; - next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump); - } else if (next_min_addr == next_put_label_addr) { - SLJIT_ASSERT(put_label->label); + if (!(jump->flags & JUMP_MOV_ADDR)) { + word_count = word_count - 1 + (jump->flags >> JUMP_SIZE_SHIFT); + jump->addr = (sljit_uw)code_ptr; + code_ptr = detect_jump_type(jump, code, executable_offset); + SLJIT_ASSERT((jump->flags & PATCH_B) || ((sljit_uw)code_ptr - jump->addr < (jump->flags >> JUMP_SIZE_SHIFT) * sizeof(sljit_ins))); + } else { + SLJIT_ASSERT(jump->u.label); #if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) - word_count += 1; - put_label->addr = (sljit_uw)code_ptr; - code_ptr += 1; + word_count += 1; + jump->addr = (sljit_uw)code_ptr; + code_ptr += 1; #else /* !SLJIT_CONFIG_RISCV_32 */ - word_count += put_label->flags; - addr = (sljit_uw)code_ptr; - code_ptr += put_label_get_length(put_label, (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code, executable_offset)); - put_label->addr = addr; + word_count += jump->flags >> JUMP_SIZE_SHIFT; + addr = (sljit_uw)code_ptr; + code_ptr += mov_addr_get_length(jump, (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code, executable_offset)); + jump->addr = addr; #endif /* SLJIT_CONFIG_RISCV_32 */ - put_label = put_label->next; - next_put_label_addr = SLJIT_GET_NEXT_ADDRESS(put_label); + } + jump = jump->next; + next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump); } else if (next_min_addr == next_const_addr) { const_->addr = (sljit_uw)code_ptr; const_ = const_->next; @@ -594,14 +574,13 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_ASSERT(!label); SLJIT_ASSERT(!jump); SLJIT_ASSERT(!const_); - SLJIT_ASSERT(!put_label); SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size); jump = compiler->jumps; while (jump) { do { - if (!(jump->flags & (PATCH_B | PATCH_J))) { - load_addr_to_reg(jump, TMP_REG1, executable_offset); + if (!(jump->flags & (PATCH_B | PATCH_J)) || (jump->flags & JUMP_MOV_ADDR)) { + load_addr_to_reg(jump, executable_offset); break; } @@ -620,13 +599,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil addr = (addr & 0xff000) | ((addr & 0x800) << 9) | ((addr & 0x7fe) << 20) | ((addr & 0x100000) << 11); buf_ptr[0] = JAL | RD((jump->flags & IS_CALL) ? RETURN_ADDR_REG : TMP_ZERO) | (sljit_ins)addr; } while (0); - jump = jump->next; - } - put_label = compiler->put_labels; - while (put_label) { - load_addr_to_reg(put_label, 0, executable_offset); - put_label = put_label->next; + jump = jump->next; } compiler->error = SLJIT_ERR_COMPILED; @@ -3079,18 +3053,18 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi return const_; } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_mov_addr(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) { - struct sljit_put_label *put_label; + struct sljit_jump *jump; sljit_s32 dst_r; CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw)); + CHECK_PTR(check_sljit_emit_mov_addr(compiler, dst, dstw)); ADJUST_LOCAL_OFFSET(dst, dstw); - put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label)); - PTR_FAIL_IF(!put_label); - set_put_label(put_label, compiler, 0); + jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); + PTR_FAIL_IF(!jump); + set_mov_addr(jump, compiler, 0); dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2; PTR_FAIL_IF(push_inst(compiler, (sljit_ins)dst_r)); @@ -3103,7 +3077,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct slj if (dst & SLJIT_MEM) PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw)); - return put_label; + return jump; } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset) diff --git a/sljit_src/sljitNativeX86_64.c b/sljit_src/sljitNativeX86_64.c index b76f21db..416e7f94 100644 --- a/sljit_src/sljitNativeX86_64.c +++ b/sljit_src/sljitNativeX86_64.c @@ -395,11 +395,11 @@ static sljit_u8* detect_far_jump_type(struct sljit_jump *jump, sljit_u8 *code_pt return code_ptr + 3; } -static sljit_u8* generate_put_label_code(struct sljit_put_label *put_label, sljit_u8 *code_ptr, sljit_uw addr) +static sljit_u8* generate_mov_addr_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_uw addr) { - sljit_sw diff = (sljit_sw)put_label->label->size - (sljit_sw)put_label->addr; + sljit_sw diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr; - addr += put_label->label->size; + addr += jump->u.label->size; if (addr > 0xffffffffl) { if (diff <= HALFWORD_MAX && diff >= HALFWORD_MIN) { @@ -412,11 +412,11 @@ static sljit_u8* generate_put_label_code(struct sljit_put_label *put_label, slji code_ptr[-1 - SSIZE_OF(s32)] = U8(((code_ptr[-2 - SSIZE_OF(s32)] & 0x7) << 3) | 0x5); code_ptr[-2 - SSIZE_OF(s32)] = LEA_r_m; - put_label->flags = PATCH_MW; + jump->flags |= PATCH_MW; return code_ptr; } - put_label->flags = PATCH_MD; + jump->flags |= PATCH_MD; return code_ptr; } diff --git a/sljit_src/sljitNativeX86_common.c b/sljit_src/sljitNativeX86_common.c index 202487ce..73fcf2ad 100644 --- a/sljit_src/sljitNativeX86_common.c +++ b/sljit_src/sljitNativeX86_common.c @@ -375,7 +375,7 @@ static const sljit_u8 freg_lmap[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2] = { #define SLJIT_INST_LABEL 255 #define SLJIT_INST_JUMP 254 -#define SLJIT_INST_PUT_LABEL 253 +#define SLJIT_INST_MOV_ADDR 253 #define SLJIT_INST_CONST 252 /* Multithreading does not affect these static variables, since they store @@ -612,7 +612,7 @@ static sljit_u8 get_jump_code(sljit_uw type) static sljit_u8* detect_far_jump_type(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_sw executable_offset); #else /* !SLJIT_CONFIG_X86_32 */ static sljit_u8* detect_far_jump_type(struct sljit_jump *jump, sljit_u8 *code_ptr); -static sljit_u8* generate_put_label_code(struct sljit_put_label *put_label, sljit_u8 *code_ptr, sljit_uw max_label); +static sljit_u8* generate_mov_addr_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_uw max_label); #endif /* SLJIT_CONFIG_X86_32 */ static sljit_u8* detect_near_jump_type(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_u8 *code, sljit_sw executable_offset) @@ -661,18 +661,66 @@ static sljit_u8* detect_near_jump_type(struct sljit_jump *jump, sljit_u8 *code_p return code_ptr; } +static void generate_jump_or_mov_addr(struct sljit_jump *jump, sljit_sw executable_offset) +{ + sljit_uw flags = jump->flags; + sljit_uw addr = (flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr; + sljit_uw jump_addr = jump->addr; + SLJIT_UNUSED_ARG(executable_offset); + + if (SLJIT_UNLIKELY(flags & JUMP_MOV_ADDR)) { +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + sljit_unaligned_store_sw((void*)(jump_addr - sizeof(sljit_sw)), (sljit_sw)addr); +#else /* SLJIT_CONFIG_X86_32 */ + if (flags & PATCH_MD) { + SLJIT_ASSERT(addr > HALFWORD_MAX); + sljit_unaligned_store_sw((void*)(jump_addr - sizeof(sljit_sw)), (sljit_sw)addr); + return; + } + + if (flags & PATCH_MW) { + addr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET((sljit_u8*)jump_addr, executable_offset); + SLJIT_ASSERT((sljit_sw)addr <= HALFWORD_MAX && (sljit_sw)addr >= HALFWORD_MIN); + } else { + SLJIT_ASSERT(addr <= HALFWORD_MAX); + } + sljit_unaligned_store_s32((void*)(jump_addr - sizeof(sljit_s32)), (sljit_s32)addr); +#endif /* !SLJIT_CONFIG_X86_32 */ + return; + } + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (SLJIT_UNLIKELY(flags & PATCH_MD)) { + SLJIT_ASSERT(!(flags & JUMP_ADDR)); + sljit_unaligned_store_sw((void*)jump_addr, (sljit_sw)addr); + return; + } +#endif /* SLJIT_CONFIG_X86_64 */ + + addr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET((sljit_u8*)jump_addr, executable_offset); + + if (flags & PATCH_MB) { + addr -= sizeof(sljit_s8); + SLJIT_ASSERT((sljit_sw)addr <= 0x7f && (sljit_sw)addr >= -0x80); + *(sljit_u8*)jump_addr = U8(addr); + return; + } else if (flags & PATCH_MW) { + addr -= sizeof(sljit_s32); +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + sljit_unaligned_store_sw((void*)jump_addr, (sljit_sw)addr); +#else /* !SLJIT_CONFIG_X86_32 */ + SLJIT_ASSERT((sljit_sw)addr <= HALFWORD_MAX && (sljit_sw)addr >= HALFWORD_MIN); + sljit_unaligned_store_s32((void*)jump_addr, (sljit_s32)addr); +#endif /* SLJIT_CONFIG_X86_32 */ + } +} + static void reduce_code_size(struct sljit_compiler *compiler) { struct sljit_label *label; struct sljit_jump *jump; -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - struct sljit_put_label *put_label; -#endif /* SLJIT_CONFIG_X86_64 */ sljit_uw next_label_size; sljit_uw next_jump_addr; -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - sljit_uw next_put_label_addr; -#endif /* SLJIT_CONFIG_X86_64 */ sljit_uw next_min_addr; sljit_uw size_reduce = 0; sljit_sw diff; @@ -683,24 +731,14 @@ static void reduce_code_size(struct sljit_compiler *compiler) label = compiler->labels; jump = compiler->jumps; -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - put_label = compiler->put_labels; -#endif /* SLJIT_CONFIG_X86_64 */ next_label_size = SLJIT_GET_NEXT_SIZE(label); next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump); -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - next_put_label_addr = SLJIT_GET_NEXT_ADDRESS(put_label); -#endif /* SLJIT_CONFIG_X86_64 */ while (1) { next_min_addr = next_label_size; if (next_jump_addr < next_min_addr) next_min_addr = next_jump_addr; -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (next_put_label_addr < next_min_addr) - next_min_addr = next_put_label_addr; -#endif /* SLJIT_CONFIG_X86_64 */ if (next_min_addr == SLJIT_MAX_ADDRESS) break; @@ -712,7 +750,10 @@ static void reduce_code_size(struct sljit_compiler *compiler) next_label_size = SLJIT_GET_NEXT_SIZE(label); } - if (next_min_addr == next_jump_addr) { + if (next_min_addr != next_jump_addr) + continue; + + if (!(jump->flags & JUMP_MOV_ADDR)) { #if (defined SLJIT_DEBUG && SLJIT_DEBUG) size_reduce_max = size_reduce + (((jump->flags >> TYPE_SHIFT) < SLJIT_JUMP) ? CJUMP_MAX_SIZE : JUMP_MAX_SIZE); #endif /* SLJIT_DEBUG */ @@ -758,22 +799,17 @@ static void reduce_code_size(struct sljit_compiler *compiler) #if (defined SLJIT_DEBUG && SLJIT_DEBUG) jump->flags |= (size_reduce_max - size_reduce) << JUMP_SIZE_SHIFT; #endif /* SLJIT_DEBUG */ - - jump = jump->next; - next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump); - } - + } else { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (next_min_addr == next_put_label_addr) { - diff = (sljit_sw)put_label->label->size - (sljit_sw)(put_label->addr - size_reduce - 3); + diff = (sljit_sw)jump->u.label->size - (sljit_sw)(jump->addr - size_reduce - 3); if (diff <= HALFWORD_MAX && diff >= HALFWORD_MIN) size_reduce += 3; - - put_label = put_label->next; - next_put_label_addr = SLJIT_GET_NEXT_ADDRESS(put_label); - } #endif /* SLJIT_CONFIG_X86_64 */ + } + + jump = jump->next; + next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump); } compiler->size -= size_reduce; @@ -788,12 +824,13 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil sljit_u8 *buf_end; sljit_u8 len; sljit_sw executable_offset; +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) sljit_uw addr; +#endif /* SLJIT_DEBUG */ struct sljit_label *label; struct sljit_jump *jump; struct sljit_const *const_; - struct sljit_put_label *put_label; CHECK_ERROR_PTR(); CHECK_PTR(check_sljit_generate_code(compiler)); @@ -811,7 +848,6 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil label = compiler->labels; jump = compiler->jumps; const_ = compiler->consts; - put_label = compiler->put_labels; executable_offset = SLJIT_EXEC_OFFSET(code); do { @@ -841,21 +877,21 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil else { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) code_ptr = detect_far_jump_type(jump, code_ptr, executable_offset); -#else +#else /* !SLJIT_CONFIG_X86_32 */ code_ptr = detect_far_jump_type(jump, code_ptr); -#endif +#endif /* SLJIT_CONFIG_X86_32 */ } SLJIT_ASSERT((sljit_uw)code_ptr - addr <= ((jump->flags >> JUMP_SIZE_SHIFT) & 0x1f)); jump = jump->next; break; - case SLJIT_INST_PUT_LABEL: - SLJIT_ASSERT(put_label->label); + case SLJIT_INST_MOV_ADDR: + SLJIT_ASSERT(jump->u.label != NULL); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - code_ptr = generate_put_label_code(put_label, code_ptr, (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code, executable_offset)); + code_ptr = generate_mov_addr_code(jump, code_ptr, (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code, executable_offset)); #endif /* SLJIT_CONFIG_X86_64 */ - put_label->addr = (sljit_uw)code_ptr; - put_label = put_label->next; + jump->addr = (sljit_uw)code_ptr; + jump = jump->next; break; default: SLJIT_ASSERT(len == SLJIT_INST_CONST); @@ -872,64 +908,14 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_ASSERT(!label); SLJIT_ASSERT(!jump); SLJIT_ASSERT(!const_); - SLJIT_ASSERT(!put_label); SLJIT_ASSERT(code_ptr <= code + compiler->size); jump = compiler->jumps; while (jump) { - if (jump->flags & (PATCH_MB | PATCH_MW)) { - if (jump->flags & JUMP_ADDR) - addr = jump->u.target; - else - addr = jump->u.label->u.addr; - - addr -= jump->addr + (sljit_uw)executable_offset; - - if (jump->flags & PATCH_MB) { - addr -= sizeof(sljit_s8); - SLJIT_ASSERT((sljit_sw)addr <= 0x7f && (sljit_sw)addr >= -0x80); - *(sljit_u8*)jump->addr = U8(addr); - } else { - addr -= sizeof(sljit_s32); -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - sljit_unaligned_store_sw((void*)jump->addr, (sljit_sw)addr); -#else - SLJIT_ASSERT((sljit_sw)addr <= HALFWORD_MAX && (sljit_sw)addr >= HALFWORD_MIN); - sljit_unaligned_store_s32((void*)jump->addr, (sljit_s32)addr); -#endif - } - } -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - else if (jump->flags & PATCH_MD) { - SLJIT_ASSERT(!(jump->flags & JUMP_ADDR)); - sljit_unaligned_store_sw((void*)jump->addr, (sljit_sw)jump->u.label->u.addr); - } -#endif - + generate_jump_or_mov_addr(jump, executable_offset); jump = jump->next; } - put_label = compiler->put_labels; - while (put_label) { -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - sljit_unaligned_store_sw((void*)(put_label->addr - sizeof(sljit_sw)), (sljit_sw)put_label->label->u.addr); -#else /* SLJIT_CONFIG_X86_32 */ - if (put_label->flags & PATCH_MD) { - SLJIT_ASSERT(put_label->label->u.addr > HALFWORD_MAX); - sljit_unaligned_store_sw((void*)(put_label->addr - sizeof(sljit_sw)), (sljit_sw)put_label->label->u.addr); - } else if (put_label->flags & PATCH_MW) { - addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET((sljit_u8*)put_label->addr, executable_offset); - SLJIT_ASSERT((sljit_sw)(put_label->label->u.addr - addr) <= HALFWORD_MAX && (sljit_sw)(put_label->label->u.addr - addr) >= HALFWORD_MIN); - sljit_unaligned_store_s32((void*)(put_label->addr - sizeof(sljit_s32)), (sljit_s32)(put_label->label->u.addr - addr)); - } else { - SLJIT_ASSERT(put_label->label->u.addr <= HALFWORD_MAX); - sljit_unaligned_store_s32((void*)(put_label->addr - sizeof(sljit_s32)), (sljit_s32)put_label->label->u.addr); - } -#endif /* !SLJIT_CONFIG_X86_32 */ - - put_label = put_label->next; - } - compiler->error = SLJIT_ERR_COMPILED; compiler->executable_offset = executable_offset; compiler->executable_size = (sljit_uw)(code_ptr - code); @@ -4843,30 +4829,30 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi return const_; } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_mov_addr(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) { - struct sljit_put_label *put_label; + struct sljit_jump *jump; sljit_u8 *inst; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) sljit_s32 reg; #endif /* SLJIT_CONFIG_X86_64 */ CHECK_ERROR_PTR(); - CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw)); + CHECK_PTR(check_sljit_emit_mov_addr(compiler, dst, dstw)); ADJUST_LOCAL_OFFSET(dst, dstw); CHECK_EXTRA_REGS(dst, dstw, (void)0); - put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label)); - PTR_FAIL_IF(!put_label); - set_put_label(put_label, compiler, 0); + jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); + PTR_FAIL_IF(!jump); + set_mov_addr(jump, compiler, 0); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = 0; reg = FAST_IS_REG(dst) ? dst : TMP_REG1; PTR_FAIL_IF(emit_load_imm64(compiler, reg, 0)); - put_label->addr = compiler->size; + jump->addr = compiler->size; #else /* !SLJIT_CONFIG_X86_64 */ PTR_FAIL_IF(emit_mov(compiler, dst, dstw, SLJIT_IMM, 0)); #endif /* SLJIT_CONFIG_X86_64 */ @@ -4874,14 +4860,14 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct slj inst = (sljit_u8*)ensure_buf(compiler, 1); PTR_FAIL_IF(!inst); - inst[0] = SLJIT_INST_PUT_LABEL; + inst[0] = SLJIT_INST_MOV_ADDR; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (dst & SLJIT_MEM) PTR_FAIL_IF(emit_mov(compiler, dst, dstw, TMP_REG1, 0)); #endif /* SLJIT_CONFIG_X86_64 */ - return put_label; + return jump; } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset) diff --git a/sljit_src/sljitSerialize.c b/sljit_src/sljitSerialize.c index 3c8101d7..4392b2da 100644 --- a/sljit_src/sljitSerialize.c +++ b/sljit_src/sljitSerialize.c @@ -34,6 +34,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_jump_has_target(struct sljit_jump *jump return (jump->flags & JUMP_ADDR) != 0; } +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_jump_is_mov_addr(struct sljit_jump *jump) +{ + return (jump->flags & JUMP_MOV_ADDR) != 0; +} + #define SLJIT_SERIALIZE_DEBUG ((sljit_u16)0x1) struct sljit_serialized_compiler { @@ -44,7 +49,6 @@ struct sljit_serialized_compiler { sljit_uw buf_segment_count; sljit_uw label_count; sljit_uw jump_count; - sljit_uw put_label_count; sljit_uw const_count; sljit_s32 options; @@ -96,12 +100,6 @@ struct sljit_serialized_jump { sljit_uw value; }; -struct sljit_serialized_put_label { - sljit_uw addr; - sljit_uw flags; - sljit_uw index; -}; - struct sljit_serialized_const { sljit_uw addr; }; @@ -121,12 +119,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_uw* sljit_serialize_compiler(struct sljit_compile struct sljit_memory_fragment *buf; struct sljit_label *label; struct sljit_jump *jump; - struct sljit_put_label *put_label; struct sljit_const *const_; struct sljit_serialized_compiler *serialized_compiler; struct sljit_serialized_label *serialized_label; struct sljit_serialized_jump *serialized_jump; - struct sljit_serialized_put_label *serialized_put_label; struct sljit_serialized_const *serialized_const; #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ || (defined SLJIT_DEBUG && SLJIT_DEBUG) @@ -167,12 +163,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_uw* sljit_serialize_compiler(struct sljit_compile jump = jump->next; } - put_label = compiler->put_labels; - while (put_label != NULL) { - total_size += sizeof(struct sljit_serialized_put_label); - put_label = put_label->next; - } - const_ = compiler->consts; while (const_ != NULL) { total_size += sizeof(struct sljit_serialized_const); @@ -266,25 +256,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_uw* sljit_serialize_compiler(struct sljit_compile } serialized_compiler->jump_count = counter; - put_label = compiler->put_labels; - counter = 0; - while (put_label != NULL) { - serialized_put_label = (struct sljit_serialized_put_label*)ptr; - - serialized_put_label->addr = put_label->addr; - serialized_put_label->flags = put_label->flags; - - if (put_label->label != NULL) - serialized_put_label->index = put_label->label->u.index; - else - serialized_put_label->index = ~(sljit_uw)0; - - ptr += sizeof(struct sljit_serialized_put_label); - put_label = put_label->next; - counter++; - } - serialized_compiler->put_label_count = counter; - const_ = compiler->consts; counter = 0; while (const_ != NULL) { @@ -321,7 +292,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler *sljit_deserialize_compiler(sljit struct sljit_serialized_compiler *serialized_compiler; struct sljit_serialized_label *serialized_label; struct sljit_serialized_jump *serialized_jump; - struct sljit_serialized_put_label *serialized_put_label; struct sljit_serialized_const *serialized_const; #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ || (defined SLJIT_DEBUG && SLJIT_DEBUG) @@ -334,8 +304,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler *sljit_deserialize_compiler(sljit struct sljit_label **label_list = NULL; struct sljit_jump *jump; struct sljit_jump *last_jump; - struct sljit_put_label *put_label; - struct sljit_put_label *last_put_label; struct sljit_const *const_; struct sljit_const *last_const; sljit_u8 *ptr = (sljit_u8*)buffer; @@ -499,39 +467,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler *sljit_deserialize_compiler(sljit } compiler->last_jump = last_jump; - last_put_label = NULL; - i = serialized_compiler->put_label_count; - if ((sljit_uw)(end - ptr) < i * sizeof(struct sljit_serialized_put_label)) - goto error; - - while (i > 0) { - put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label)); - if (put_label == NULL) - goto error; - - serialized_put_label = (struct sljit_serialized_put_label*)ptr; - put_label->next = NULL; - put_label->addr = serialized_put_label->addr; - put_label->flags = serialized_put_label->flags; - - if (serialized_put_label->index != ~(sljit_uw)0) { - if (serialized_put_label->index >= label_count) - goto error; - put_label->label = label_list[serialized_put_label->index]; - } else - put_label->label = NULL; - - if (last_put_label != NULL) - last_put_label->next = put_label; - else - compiler->put_labels = put_label; - last_put_label = put_label; - - ptr += sizeof(struct sljit_serialized_put_label); - i--; - } - compiler->last_put_label = last_put_label; - SLJIT_FREE(label_list, allocator_data); label_list = NULL; diff --git a/test_src/sljitTest.c b/test_src/sljitTest.c index 8b2d998a..5a804a62 100644 --- a/test_src/sljitTest.c +++ b/test_src/sljitTest.c @@ -1269,7 +1269,7 @@ static void test13(void) struct sljit_jump *jump1; struct sljit_jump *jump2; struct sljit_const* const1; - struct sljit_put_label *put_label; + struct sljit_jump *mov_addr; sljit_sw executable_offset; sljit_uw const_addr; sljit_uw jump_addr; @@ -1292,7 +1292,7 @@ static void test13(void) label = sljit_emit_label(compiler); sljit_set_label(jump1, label); - put_label = sljit_emit_put_label(compiler, SLJIT_R2, 0); + mov_addr = sljit_emit_mov_addr(compiler, SLJIT_R2, 0); /* buf[0] */ const1 = sljit_emit_const(compiler, SLJIT_MEM1(SLJIT_S0), 0, -1234); @@ -1300,7 +1300,7 @@ static void test13(void) sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_MEM1(SLJIT_S0), 0, SLJIT_IMM, -1234); label = sljit_emit_label(compiler); - sljit_set_put_label(put_label, label); + sljit_set_label(mov_addr, label); /* buf[1] */ sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_MEM1(SLJIT_S0), sizeof(sljit_sw), SLJIT_IMM, -56789); @@ -5194,7 +5194,7 @@ static void test50(void) /* Test put label. */ executable_code code; struct sljit_label *label[2]; - struct sljit_put_label *put_label[5]; + struct sljit_jump *mov_addr[5]; struct sljit_compiler* compiler = sljit_create_compiler(NULL, NULL); sljit_uw addr[2]; sljit_uw buf[4]; @@ -5212,30 +5212,30 @@ static void test50(void) sljit_emit_enter(compiler, 0, SLJIT_ARGS1(W, P), 3, 1, 0, 0, 2 * sizeof(sljit_sw)); /* buf[0-1] */ - put_label[0] = sljit_emit_put_label(compiler, SLJIT_R0, 0); + mov_addr[0] = sljit_emit_mov_addr(compiler, SLJIT_R0, 0); sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_MEM1(SLJIT_S0), 0, SLJIT_R0, 0); - put_label[1] = sljit_emit_put_label(compiler, SLJIT_MEM1(SLJIT_SP), sizeof(sljit_uw)); + mov_addr[1] = sljit_emit_mov_addr(compiler, SLJIT_MEM1(SLJIT_SP), sizeof(sljit_uw)); sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_MEM1(SLJIT_S0), sizeof(sljit_uw), SLJIT_MEM1(SLJIT_SP), sizeof(sljit_uw)); label[0] = sljit_emit_label(compiler); - sljit_set_put_label(put_label[0], label[0]); - sljit_set_put_label(put_label[1], label[0]); + sljit_set_label(mov_addr[0], label[0]); + sljit_set_label(mov_addr[1], label[0]); /* buf[2-3] */ sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_R0, 0, SLJIT_IMM, (sljit_sw)(buf + 2) - offs); - put_label[2] = sljit_emit_put_label(compiler, SLJIT_MEM1(SLJIT_R0), offs); + mov_addr[2] = sljit_emit_mov_addr(compiler, SLJIT_MEM1(SLJIT_R0), offs); sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_R1, 0, SLJIT_IMM, (offs + (sljit_sw)sizeof(sljit_uw)) >> 1); - put_label[3] = sljit_emit_put_label(compiler, SLJIT_MEM2(SLJIT_R0, SLJIT_R1), 1); + mov_addr[3] = sljit_emit_mov_addr(compiler, SLJIT_MEM2(SLJIT_R0, SLJIT_R1), 1); label[1] = sljit_emit_label(compiler); - sljit_set_put_label(put_label[2], label[1]); - sljit_set_put_label(put_label[3], label[1]); + sljit_set_label(mov_addr[2], label[1]); + sljit_set_label(mov_addr[3], label[1]); /* Return value */ - put_label[4] = sljit_emit_put_label(compiler, SLJIT_RETURN_REG, 0); - sljit_set_put_label(put_label[4], label[0]); + mov_addr[4] = sljit_emit_mov_addr(compiler, SLJIT_RETURN_REG, 0); + sljit_set_label(mov_addr[4], label[0]); sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0); code.code = sljit_generate_code(compiler); @@ -5262,7 +5262,7 @@ static void test51(void) executable_code code; sljit_uw malloc_addr; struct sljit_label label[6]; - struct sljit_put_label *put_label[2]; + struct sljit_jump *mov_addr[2]; struct sljit_compiler* compiler; sljit_uw buf[7]; sljit_s32 i; @@ -5317,45 +5317,45 @@ static void test51(void) sljit_emit_enter(compiler, 0, SLJIT_ARGS1(W, P), 3, 1, 0, 0, 2 * sizeof(sljit_sw)); /* buf[0] */ - put_label[0] = sljit_emit_put_label(compiler, SLJIT_R0, 0); + mov_addr[0] = sljit_emit_mov_addr(compiler, SLJIT_R0, 0); sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_MEM1(SLJIT_S0), 0, SLJIT_R0, 0); /* buf[1] */ - put_label[1] = sljit_emit_put_label(compiler, SLJIT_MEM1(SLJIT_SP), sizeof(sljit_uw)); + mov_addr[1] = sljit_emit_mov_addr(compiler, SLJIT_MEM1(SLJIT_SP), sizeof(sljit_uw)); sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_MEM1(SLJIT_S0), sizeof(sljit_uw), SLJIT_MEM1(SLJIT_SP), sizeof(sljit_uw)); - sljit_set_put_label(put_label[0], &label[0]); - sljit_set_put_label(put_label[1], &label[0]); + sljit_set_label(mov_addr[0], &label[0]); + sljit_set_label(mov_addr[1], &label[0]); /* buf[2] */ sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_R0, 0, SLJIT_IMM, (sljit_sw)(buf + 2) - offs1); - put_label[0] = sljit_emit_put_label(compiler, SLJIT_MEM1(SLJIT_R0), offs1); + mov_addr[0] = sljit_emit_mov_addr(compiler, SLJIT_MEM1(SLJIT_R0), offs1); /* buf[3] */ sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_R1, 0, SLJIT_IMM, (offs1 + (sljit_sw)sizeof(sljit_uw)) >> 1); - put_label[1] = sljit_emit_put_label(compiler, SLJIT_MEM2(SLJIT_R0, SLJIT_R1), 1); + mov_addr[1] = sljit_emit_mov_addr(compiler, SLJIT_MEM2(SLJIT_R0, SLJIT_R1), 1); - sljit_set_put_label(put_label[0], &label[1]); - sljit_set_put_label(put_label[1], &label[1]); + sljit_set_label(mov_addr[0], &label[1]); + sljit_set_label(mov_addr[1], &label[1]); /* buf[4] */ - put_label[0] = sljit_emit_put_label(compiler, SLJIT_R1, 0); - sljit_set_put_label(put_label[0], &label[2]); + mov_addr[0] = sljit_emit_mov_addr(compiler, SLJIT_R1, 0); + sljit_set_label(mov_addr[0], &label[2]); sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_MEM1(SLJIT_S0), 4 * sizeof(sljit_uw), SLJIT_R1, 0); /* buf[5] */ - put_label[0] = sljit_emit_put_label(compiler, SLJIT_R2, 0); - sljit_set_put_label(put_label[0], &label[3]); + mov_addr[0] = sljit_emit_mov_addr(compiler, SLJIT_R2, 0); + sljit_set_label(mov_addr[0], &label[3]); sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_MEM1(SLJIT_S0), 5 * sizeof(sljit_uw), SLJIT_R2, 0); /* buf[6] */ - put_label[0] = sljit_emit_put_label(compiler, SLJIT_R1, 0); - sljit_set_put_label(put_label[0], &label[4]); + mov_addr[0] = sljit_emit_mov_addr(compiler, SLJIT_R1, 0); + sljit_set_label(mov_addr[0], &label[4]); sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_MEM1(SLJIT_S0), 6 * sizeof(sljit_uw), SLJIT_R1, 0); /* buf[7] */ - put_label[0] = sljit_emit_put_label(compiler, SLJIT_RETURN_REG, 0); - sljit_set_put_label(put_label[0], &label[5]); + mov_addr[0] = sljit_emit_mov_addr(compiler, SLJIT_RETURN_REG, 0); + sljit_set_label(mov_addr[0], &label[5]); sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0); code.code = sljit_generate_code(compiler); diff --git a/test_src/sljitTestSerialize.h b/test_src/sljitTestSerialize.h index 7200be74..522e91c5 100644 --- a/test_src/sljitTestSerialize.h +++ b/test_src/sljitTestSerialize.h @@ -32,7 +32,7 @@ static void test_serialize1(void) struct sljit_label *label; struct sljit_jump *jump1; struct sljit_jump *jump2; - struct sljit_put_label *put_label; + struct sljit_jump *mov_addr; sljit_sw executable_offset; sljit_uw const_addr; sljit_uw jump_addr; @@ -59,7 +59,7 @@ static void test_serialize1(void) label = sljit_emit_label(compiler); sljit_set_label(jump1, label); - put_label = sljit_emit_put_label(compiler, SLJIT_R2, 0); + mov_addr = sljit_emit_mov_addr(compiler, SLJIT_R2, 0); /* buf[0] */ sljit_emit_const(compiler, SLJIT_MEM1(SLJIT_S0), 0, -1234); @@ -67,7 +67,7 @@ static void test_serialize1(void) sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_MEM1(SLJIT_S0), 0, SLJIT_IMM, -1234); label = sljit_emit_label(compiler); - sljit_set_put_label(put_label, label); + sljit_set_label(mov_addr, label); sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_R1, 0, SLJIT_IMM, 7); for (i = 0; i < 4096; i++) @@ -108,7 +108,8 @@ static void test_serialize1(void) CHECK(compiler); executable_offset = sljit_get_executable_offset(compiler); const_addr = sljit_get_const_addr(sljit_get_first_const(compiler)); - jump1 = sljit_get_next_jump(sljit_get_next_jump(sljit_get_first_jump(compiler))); + jump1 = sljit_get_next_jump(sljit_get_next_jump(sljit_get_next_jump(sljit_get_first_jump(compiler)))); + SLJIT_ASSERT(!sljit_jump_is_mov_addr(jump1)); jump_addr = sljit_get_jump_addr(jump1); label = sljit_get_next_label(sljit_get_next_label(sljit_get_next_label(sljit_get_next_label(sljit_get_first_label(compiler))))); label_addr = sljit_get_label_addr(label); @@ -155,7 +156,7 @@ static void test_serialize2(void) sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_MEM1(SLJIT_S0), 0, SLJIT_IMM, -5678); sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), 16, SLJIT_IMM, -8765); - sljit_emit_put_label(compiler, SLJIT_S2, 0); + sljit_emit_mov_addr(compiler, SLJIT_S2, 0); sljit_emit_cmp(compiler, SLJIT_NOT_EQUAL, SLJIT_S2, 0, SLJIT_IMM, 0); sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_R0, 0, SLJIT_IMM, 0); sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_R0), 0); @@ -172,6 +173,7 @@ static void test_serialize2(void) label = sljit_emit_label(compiler); SLJIT_ASSERT(sljit_get_label_index(label) == 1); jump = sljit_get_first_jump(compiler); + SLJIT_ASSERT(!sljit_jump_is_mov_addr(jump)); SLJIT_ASSERT(!sljit_jump_has_label(jump) && !sljit_jump_has_target(jump)); sljit_set_label(jump, label); @@ -199,6 +201,9 @@ static void test_serialize2(void) jump = sljit_get_first_jump(compiler); SLJIT_ASSERT(sljit_jump_has_label(jump) && !sljit_jump_has_target(jump)); jump = sljit_get_next_jump(jump); + SLJIT_ASSERT(sljit_jump_is_mov_addr(jump)); + jump = sljit_get_next_jump(jump); + SLJIT_ASSERT(!sljit_jump_is_mov_addr(jump)); SLJIT_ASSERT(!sljit_jump_has_label(jump) && !sljit_jump_has_target(jump)); label = sljit_emit_label(compiler); @@ -214,7 +219,9 @@ static void test_serialize2(void) SLJIT_ASSERT(sljit_get_label_index(label) == 1); label = sljit_get_next_label(label); SLJIT_ASSERT(sljit_get_label_index(label) == 2); - sljit_set_put_label(sljit_get_first_put_label(compiler), label); + jump = sljit_get_next_jump(sljit_get_first_jump(compiler)); + SLJIT_ASSERT(sljit_jump_is_mov_addr(jump)); + sljit_set_label(jump, label); label = sljit_get_next_label(label); SLJIT_ASSERT(sljit_get_label_index(label) == 3); SLJIT_ASSERT(sljit_get_next_label(label) == NULL); @@ -246,7 +253,6 @@ static void test_serialize3(void) struct sljit_compiler* compiler = sljit_create_compiler(NULL, NULL); struct sljit_label *label; struct sljit_jump *jump; - struct sljit_put_label *put_label; struct sljit_const *const_; sljit_sw executable_offset; sljit_uw* serialized_buffer; @@ -264,7 +270,7 @@ static void test_serialize3(void) sljit_emit_enter(compiler, 0, SLJIT_ARGS1V(P), 3, 3, 0, 0, 32); - sljit_emit_put_label(compiler, SLJIT_R0, 0); + sljit_emit_mov_addr(compiler, SLJIT_R0, 0); sljit_emit_const(compiler, SLJIT_R1, 0, 0); sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_R2, 0, SLJIT_S0, 0); jump = sljit_emit_call(compiler, SLJIT_CALL, SLJIT_ARGS3V(W, W, W)); @@ -280,7 +286,7 @@ static void test_serialize3(void) SLJIT_FREE(serialized_buffer, NULL); FAILED(!compiler, "cannot deserialize compiler\n"); - sljit_emit_put_label(compiler, SLJIT_R0, 0); + sljit_emit_mov_addr(compiler, SLJIT_R0, 0); sljit_emit_const(compiler, SLJIT_R1, 0, 0); sljit_emit_op2(compiler, SLJIT_ADD, SLJIT_R2, 0, SLJIT_S0, 0, SLJIT_IMM, 2 * sizeof(sljit_sw)); jump = sljit_emit_call(compiler, SLJIT_CALL, SLJIT_ARGS3V(W, W, W)); @@ -296,7 +302,7 @@ static void test_serialize3(void) SLJIT_FREE(serialized_buffer, NULL); FAILED(!compiler, "cannot deserialize compiler\n"); - sljit_emit_put_label(compiler, SLJIT_R0, 0); + sljit_emit_mov_addr(compiler, SLJIT_R0, 0); sljit_emit_const(compiler, SLJIT_R1, 0, 0); sljit_emit_op2(compiler, SLJIT_ADD, SLJIT_R2, 0, SLJIT_S0, 0, SLJIT_IMM, 4 * sizeof(sljit_sw)); jump = sljit_emit_call(compiler, SLJIT_CALL, SLJIT_ARGS3V(W, W, W)); @@ -308,19 +314,22 @@ static void test_serialize3(void) label = sljit_emit_label(compiler); SLJIT_ASSERT(sljit_get_label_index(label) == 0); - put_label = sljit_get_first_put_label(compiler); - sljit_set_put_label(put_label, label); - put_label = sljit_get_next_put_label(put_label); - sljit_set_put_label(put_label, label); - put_label = sljit_get_next_put_label(put_label); - sljit_set_put_label(put_label, label); - SLJIT_ASSERT(sljit_get_next_put_label(put_label) == NULL); - jump = sljit_get_first_jump(compiler); + SLJIT_ASSERT(sljit_jump_is_mov_addr(jump)); + sljit_set_label(jump, label); + jump = sljit_get_next_jump(jump); + SLJIT_ASSERT(!sljit_jump_is_mov_addr(jump)); SLJIT_ASSERT(sljit_jump_has_target(jump) && sljit_jump_get_target(jump) == SLJIT_FUNC_UADDR(test_serialize3_f1)); jump = sljit_get_next_jump(jump); + SLJIT_ASSERT(sljit_jump_is_mov_addr(jump)); + sljit_set_label(jump, label); + jump = sljit_get_next_jump(jump); + SLJIT_ASSERT(!sljit_jump_is_mov_addr(jump)); SLJIT_ASSERT(sljit_jump_has_target(jump) && sljit_jump_get_target(jump) == SLJIT_FUNC_UADDR(test_serialize3_f1)); jump = sljit_get_next_jump(jump); + SLJIT_ASSERT(sljit_jump_is_mov_addr(jump)); + sljit_set_label(jump, label); + jump = sljit_get_next_jump(jump); SLJIT_ASSERT(sljit_jump_has_target(jump) && sljit_jump_get_target(jump) == SLJIT_FUNC_UADDR(test_serialize3_f1)); SLJIT_ASSERT(sljit_get_next_jump(jump) == NULL);