JIT compiler update.
This commit is contained in:
parent
255bc030d9
commit
27eab0b836
|
@ -251,6 +251,12 @@
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR)
|
||||||
|
#define SLJIT_ADD_EXEC_OFFSET(ptr, exec_offset) ((sljit_u8 *)(ptr) + (exec_offset))
|
||||||
|
#else
|
||||||
|
#define SLJIT_ADD_EXEC_OFFSET(ptr, exec_offset) ((sljit_u8 *)(ptr))
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Argument checking features. */
|
/* Argument checking features. */
|
||||||
|
|
||||||
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||||
|
@ -289,13 +295,6 @@
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define CHECK_DYN_CODE_MOD(extra_check) \
|
|
||||||
if ((extra_check) && !sljit_is_dyn_code_modification_enabled()) \
|
|
||||||
{ \
|
|
||||||
compiler->error = SLJIT_ERR_DYN_CODE_MOD; \
|
|
||||||
return NULL; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#elif (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
#elif (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
||||||
|
|
||||||
/* Assertion failure occures if an invalid argument is passed. */
|
/* Assertion failure occures if an invalid argument is passed. */
|
||||||
|
@ -308,7 +307,6 @@
|
||||||
#define CHECK(x) x
|
#define CHECK(x) x
|
||||||
#define CHECK_PTR(x) x
|
#define CHECK_PTR(x) x
|
||||||
#define CHECK_REG_INDEX(x) x
|
#define CHECK_REG_INDEX(x) x
|
||||||
#define CHECK_DYN_CODE_MOD(extra_check) SLJIT_ASSERT(!(extra_check) || sljit_is_dyn_code_modification_enabled())
|
|
||||||
|
|
||||||
#elif (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
#elif (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
||||||
|
|
||||||
|
@ -318,7 +316,6 @@
|
||||||
#define CHECK(x) x
|
#define CHECK(x) x
|
||||||
#define CHECK_PTR(x) x
|
#define CHECK_PTR(x) x
|
||||||
#define CHECK_REG_INDEX(x) x
|
#define CHECK_REG_INDEX(x) x
|
||||||
#define CHECK_DYN_CODE_MOD(extra_check)
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
@ -326,7 +323,6 @@
|
||||||
#define CHECK(x)
|
#define CHECK(x)
|
||||||
#define CHECK_PTR(x)
|
#define CHECK_PTR(x)
|
||||||
#define CHECK_REG_INDEX(x)
|
#define CHECK_REG_INDEX(x)
|
||||||
#define CHECK_DYN_CODE_MOD(extra_check)
|
|
||||||
|
|
||||||
#endif /* SLJIT_ARGUMENT_CHECKS */
|
#endif /* SLJIT_ARGUMENT_CHECKS */
|
||||||
|
|
||||||
|
@ -457,15 +453,6 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compi
|
||||||
compiler->error = SLJIT_ERR_ALLOC_FAILED;
|
compiler->error = SLJIT_ERR_ALLOC_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_dyn_code_modification_enabled(void)
|
|
||||||
{
|
|
||||||
#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) \
|
|
||||||
&& (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR)
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
|
#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
|
||||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
|
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
|
||||||
{
|
{
|
||||||
|
@ -1626,7 +1613,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler
|
||||||
sljit_sw tmp_srcw;
|
sljit_sw tmp_srcw;
|
||||||
|
|
||||||
CHECK_ERROR_PTR();
|
CHECK_ERROR_PTR();
|
||||||
CHECK_DYN_CODE_MOD(type & SLJIT_REWRITABLE_JUMP);
|
|
||||||
CHECK_PTR(check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w));
|
CHECK_PTR(check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w));
|
||||||
|
|
||||||
condition = type & 0xff;
|
condition = type & 0xff;
|
||||||
|
@ -1707,7 +1693,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compile
|
||||||
sljit_s32 flags, condition;
|
sljit_s32 flags, condition;
|
||||||
|
|
||||||
CHECK_ERROR_PTR();
|
CHECK_ERROR_PTR();
|
||||||
CHECK_DYN_CODE_MOD(type & SLJIT_REWRITABLE_JUMP);
|
|
||||||
CHECK_PTR(check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w));
|
CHECK_PTR(check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w));
|
||||||
|
|
||||||
condition = type & 0xff;
|
condition = type & 0xff;
|
||||||
|
@ -2055,17 +2040,19 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
|
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
|
||||||
{
|
{
|
||||||
SLJIT_UNUSED_ARG(addr);
|
SLJIT_UNUSED_ARG(addr);
|
||||||
SLJIT_UNUSED_ARG(new_addr);
|
SLJIT_UNUSED_ARG(new_target);
|
||||||
|
SLJIT_UNUSED_ARG(executable_offset);
|
||||||
SLJIT_ASSERT_STOP();
|
SLJIT_ASSERT_STOP();
|
||||||
}
|
}
|
||||||
|
|
||||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
|
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
|
||||||
{
|
{
|
||||||
SLJIT_UNUSED_ARG(addr);
|
SLJIT_UNUSED_ARG(addr);
|
||||||
SLJIT_UNUSED_ARG(new_constant);
|
SLJIT_UNUSED_ARG(new_constant);
|
||||||
|
SLJIT_UNUSED_ARG(executable_offset);
|
||||||
SLJIT_ASSERT_STOP();
|
SLJIT_ASSERT_STOP();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -325,7 +325,9 @@ struct sljit_compiler {
|
||||||
sljit_s32 local_size;
|
sljit_s32 local_size;
|
||||||
/* Code size. */
|
/* Code size. */
|
||||||
sljit_uw size;
|
sljit_uw size;
|
||||||
/* For statistical purposes. */
|
/* Relative offset of the executable mapping from the writable mapping. */
|
||||||
|
sljit_uw executable_offset;
|
||||||
|
/* Executable size for statistical purposes. */
|
||||||
sljit_uw executable_size;
|
sljit_uw executable_size;
|
||||||
|
|
||||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||||
|
@ -457,10 +459,6 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compile
|
||||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose);
|
SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Returns with non-zero if dynamic code modification is enabled. */
|
|
||||||
|
|
||||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_dyn_code_modification_enabled(void);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Create executable code from the sljit instruction stream. This is the final step
|
Create executable code from the sljit instruction stream. This is the final step
|
||||||
of the code generation so no more instructions can be added after this call.
|
of the code generation so no more instructions can be added after this call.
|
||||||
|
@ -473,10 +471,21 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code);
|
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
After the machine code generation is finished we can retrieve the allocated
|
When the protected executable allocator is used the JIT code is mapped
|
||||||
executable memory size, although this area may not be fully filled with
|
twice. The first mapping has read/write and the second mapping has read/exec
|
||||||
instructions depending on some optimizations. This function is useful only
|
permissions. This function returns with the relative offset of the executable
|
||||||
for statistical purposes.
|
mapping using the writable mapping as the base after the machine code is
|
||||||
|
successfully generated. The returned value is always 0 for the normal executable
|
||||||
|
allocator, since it uses only one mapping with read/write/exec permissions.
|
||||||
|
Dynamic code modifications requires this value.
|
||||||
|
|
||||||
|
Before a successful code generation, this function returns with 0.
|
||||||
|
*/
|
||||||
|
static SLJIT_INLINE sljit_sw sljit_get_executable_offset(struct sljit_compiler *compiler) { return compiler->executable_offset; }
|
||||||
|
|
||||||
|
/*
|
||||||
|
The executable memory consumption of the generated code can be retrieved by
|
||||||
|
this function. The returned value can be used for statistical purposes.
|
||||||
|
|
||||||
Before a successful code generation, this function returns with 0.
|
Before a successful code generation, this function returns with 0.
|
||||||
*/
|
*/
|
||||||
|
@ -1100,9 +1109,10 @@ static SLJIT_INLINE sljit_uw sljit_get_label_addr(struct sljit_label *label) { r
|
||||||
static SLJIT_INLINE sljit_uw sljit_get_jump_addr(struct sljit_jump *jump) { return jump->addr; }
|
static SLJIT_INLINE sljit_uw sljit_get_jump_addr(struct sljit_jump *jump) { return jump->addr; }
|
||||||
static SLJIT_INLINE sljit_uw sljit_get_const_addr(struct sljit_const *const_) { return const_->addr; }
|
static SLJIT_INLINE sljit_uw sljit_get_const_addr(struct sljit_const *const_) { return const_->addr; }
|
||||||
|
|
||||||
/* Only the address is required to rewrite the code. */
|
/* Only the address and executable offset are required to perform dynamic
|
||||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr);
|
code modifications. See sljit_get_executable_offset function. */
|
||||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant);
|
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset);
|
||||||
|
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset);
|
||||||
|
|
||||||
/* --------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------- */
|
||||||
/* Miscellaneous utility functions */
|
/* Miscellaneous utility functions */
|
||||||
|
|
|
@ -389,7 +389,7 @@ static SLJIT_INLINE sljit_s32 emit_imm(struct sljit_compiler *compiler, sljit_s3
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_uw *code_ptr, sljit_uw *code)
|
static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_uw *code_ptr, sljit_uw *code, sljit_sw executable_offset)
|
||||||
{
|
{
|
||||||
sljit_sw diff;
|
sljit_sw diff;
|
||||||
|
|
||||||
|
@ -401,7 +401,7 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_uw
|
||||||
code_ptr--;
|
code_ptr--;
|
||||||
|
|
||||||
if (jump->flags & JUMP_ADDR)
|
if (jump->flags & JUMP_ADDR)
|
||||||
diff = ((sljit_sw)jump->u.target - (sljit_sw)(code_ptr + 2));
|
diff = ((sljit_sw)jump->u.target - (sljit_sw)(code_ptr + 2) - executable_offset);
|
||||||
else {
|
else {
|
||||||
SLJIT_ASSERT(jump->flags & JUMP_LABEL);
|
SLJIT_ASSERT(jump->flags & JUMP_LABEL);
|
||||||
diff = ((sljit_sw)(code + jump->u.label->size) - (sljit_sw)(code_ptr + 2));
|
diff = ((sljit_sw)(code + jump->u.label->size) - (sljit_sw)(code_ptr + 2));
|
||||||
|
@ -426,7 +426,7 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_uw
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (jump->flags & JUMP_ADDR)
|
if (jump->flags & JUMP_ADDR)
|
||||||
diff = ((sljit_sw)jump->u.target - (sljit_sw)code_ptr);
|
diff = ((sljit_sw)jump->u.target - (sljit_sw)code_ptr - executable_offset);
|
||||||
else {
|
else {
|
||||||
SLJIT_ASSERT(jump->flags & JUMP_LABEL);
|
SLJIT_ASSERT(jump->flags & JUMP_LABEL);
|
||||||
diff = ((sljit_sw)(code + jump->u.label->size) - (sljit_sw)code_ptr);
|
diff = ((sljit_sw)(code + jump->u.label->size) - (sljit_sw)code_ptr);
|
||||||
|
@ -446,26 +446,28 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_uw
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SLJIT_INLINE void inline_set_jump_addr(sljit_uw addr, sljit_uw new_addr, sljit_s32 flush)
|
static SLJIT_INLINE void inline_set_jump_addr(sljit_uw jump_ptr, sljit_sw executable_offset, sljit_uw new_addr, sljit_s32 flush_cache)
|
||||||
{
|
{
|
||||||
#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
|
#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
|
||||||
sljit_uw *ptr = (sljit_uw*)addr;
|
sljit_uw *ptr = (sljit_uw *)jump_ptr;
|
||||||
sljit_uw *inst = (sljit_uw *)ptr[0];
|
sljit_uw *inst = (sljit_uw *)ptr[0];
|
||||||
sljit_uw mov_pc = ptr[1];
|
sljit_uw mov_pc = ptr[1];
|
||||||
sljit_s32 bl = (mov_pc & 0x0000f000) != RD(TMP_PC);
|
sljit_s32 bl = (mov_pc & 0x0000f000) != RD(TMP_PC);
|
||||||
sljit_sw diff = (sljit_sw)(((sljit_sw)new_addr - (sljit_sw)(inst + 2)) >> 2);
|
sljit_sw diff = (sljit_sw)(((sljit_sw)new_addr - (sljit_sw)(inst + 2) - executable_offset) >> 2);
|
||||||
|
|
||||||
if (diff <= 0x7fffff && diff >= -0x800000) {
|
if (diff <= 0x7fffff && diff >= -0x800000) {
|
||||||
/* Turn to branch. */
|
/* Turn to branch. */
|
||||||
if (!bl) {
|
if (!bl) {
|
||||||
inst[0] = (mov_pc & COND_MASK) | (B - CONDITIONAL) | (diff & 0xffffff);
|
inst[0] = (mov_pc & COND_MASK) | (B - CONDITIONAL) | (diff & 0xffffff);
|
||||||
if (flush) {
|
if (flush_cache) {
|
||||||
|
inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||||
SLJIT_CACHE_FLUSH(inst, inst + 1);
|
SLJIT_CACHE_FLUSH(inst, inst + 1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
inst[0] = (mov_pc & COND_MASK) | (BL - CONDITIONAL) | (diff & 0xffffff);
|
inst[0] = (mov_pc & COND_MASK) | (BL - CONDITIONAL) | (diff & 0xffffff);
|
||||||
inst[1] = NOP;
|
inst[1] = NOP;
|
||||||
if (flush) {
|
if (flush_cache) {
|
||||||
|
inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||||
SLJIT_CACHE_FLUSH(inst, inst + 2);
|
SLJIT_CACHE_FLUSH(inst, inst + 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -479,12 +481,14 @@ static SLJIT_INLINE void inline_set_jump_addr(sljit_uw addr, sljit_uw new_addr,
|
||||||
if (*inst != mov_pc) {
|
if (*inst != mov_pc) {
|
||||||
inst[0] = mov_pc;
|
inst[0] = mov_pc;
|
||||||
if (!bl) {
|
if (!bl) {
|
||||||
if (flush) {
|
if (flush_cache) {
|
||||||
|
inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||||
SLJIT_CACHE_FLUSH(inst, inst + 1);
|
SLJIT_CACHE_FLUSH(inst, inst + 1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
inst[1] = BLX | RM(TMP_REG1);
|
inst[1] = BLX | RM(TMP_REG1);
|
||||||
if (flush) {
|
if (flush_cache) {
|
||||||
|
inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||||
SLJIT_CACHE_FLUSH(inst, inst + 2);
|
SLJIT_CACHE_FLUSH(inst, inst + 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -492,11 +496,12 @@ static SLJIT_INLINE void inline_set_jump_addr(sljit_uw addr, sljit_uw new_addr,
|
||||||
*ptr = new_addr;
|
*ptr = new_addr;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
sljit_uw *inst = (sljit_uw*)addr;
|
sljit_uw *inst = (sljit_uw*)jump_ptr;
|
||||||
SLJIT_ASSERT((inst[0] & 0xfff00000) == MOVW && (inst[1] & 0xfff00000) == MOVT);
|
SLJIT_ASSERT((inst[0] & 0xfff00000) == MOVW && (inst[1] & 0xfff00000) == MOVT);
|
||||||
inst[0] = MOVW | (inst[0] & 0xf000) | ((new_addr << 4) & 0xf0000) | (new_addr & 0xfff);
|
inst[0] = MOVW | (inst[0] & 0xf000) | ((new_addr << 4) & 0xf0000) | (new_addr & 0xfff);
|
||||||
inst[1] = MOVT | (inst[1] & 0xf000) | ((new_addr >> 12) & 0xf0000) | ((new_addr >> 16) & 0xfff);
|
inst[1] = MOVT | (inst[1] & 0xf000) | ((new_addr >> 12) & 0xf0000) | ((new_addr >> 16) & 0xfff);
|
||||||
if (flush) {
|
if (flush_cache) {
|
||||||
|
inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||||
SLJIT_CACHE_FLUSH(inst, inst + 2);
|
SLJIT_CACHE_FLUSH(inst, inst + 2);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -504,7 +509,7 @@ static SLJIT_INLINE void inline_set_jump_addr(sljit_uw addr, sljit_uw new_addr,
|
||||||
|
|
||||||
static sljit_uw get_imm(sljit_uw imm);
|
static sljit_uw get_imm(sljit_uw imm);
|
||||||
|
|
||||||
static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw new_constant, sljit_s32 flush)
|
static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw executable_offset, sljit_sw new_constant, sljit_s32 flush_cache)
|
||||||
{
|
{
|
||||||
#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
|
#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
|
||||||
sljit_uw *ptr = (sljit_uw*)addr;
|
sljit_uw *ptr = (sljit_uw*)addr;
|
||||||
|
@ -515,7 +520,8 @@ static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw new_constant,
|
||||||
src2 = get_imm(new_constant);
|
src2 = get_imm(new_constant);
|
||||||
if (src2) {
|
if (src2) {
|
||||||
*inst = 0xe3a00000 | (ldr_literal & 0xf000) | src2;
|
*inst = 0xe3a00000 | (ldr_literal & 0xf000) | src2;
|
||||||
if (flush) {
|
if (flush_cache) {
|
||||||
|
inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||||
SLJIT_CACHE_FLUSH(inst, inst + 1);
|
SLJIT_CACHE_FLUSH(inst, inst + 1);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -524,7 +530,8 @@ static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw new_constant,
|
||||||
src2 = get_imm(~new_constant);
|
src2 = get_imm(~new_constant);
|
||||||
if (src2) {
|
if (src2) {
|
||||||
*inst = 0xe3e00000 | (ldr_literal & 0xf000) | src2;
|
*inst = 0xe3e00000 | (ldr_literal & 0xf000) | src2;
|
||||||
if (flush) {
|
if (flush_cache) {
|
||||||
|
inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||||
SLJIT_CACHE_FLUSH(inst, inst + 1);
|
SLJIT_CACHE_FLUSH(inst, inst + 1);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -537,7 +544,8 @@ static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw new_constant,
|
||||||
|
|
||||||
if (*inst != ldr_literal) {
|
if (*inst != ldr_literal) {
|
||||||
*inst = ldr_literal;
|
*inst = ldr_literal;
|
||||||
if (flush) {
|
if (flush_cache) {
|
||||||
|
inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||||
SLJIT_CACHE_FLUSH(inst, inst + 1);
|
SLJIT_CACHE_FLUSH(inst, inst + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -547,7 +555,8 @@ static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw new_constant,
|
||||||
SLJIT_ASSERT((inst[0] & 0xfff00000) == MOVW && (inst[1] & 0xfff00000) == MOVT);
|
SLJIT_ASSERT((inst[0] & 0xfff00000) == MOVW && (inst[1] & 0xfff00000) == MOVT);
|
||||||
inst[0] = MOVW | (inst[0] & 0xf000) | ((new_constant << 4) & 0xf0000) | (new_constant & 0xfff);
|
inst[0] = MOVW | (inst[0] & 0xf000) | ((new_constant << 4) & 0xf0000) | (new_constant & 0xfff);
|
||||||
inst[1] = MOVT | (inst[1] & 0xf000) | ((new_constant >> 12) & 0xf0000) | ((new_constant >> 16) & 0xfff);
|
inst[1] = MOVT | (inst[1] & 0xf000) | ((new_constant >> 12) & 0xf0000) | ((new_constant >> 16) & 0xfff);
|
||||||
if (flush) {
|
if (flush_cache) {
|
||||||
|
inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||||
SLJIT_CACHE_FLUSH(inst, inst + 2);
|
SLJIT_CACHE_FLUSH(inst, inst + 2);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -562,6 +571,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
sljit_uw *buf_end;
|
sljit_uw *buf_end;
|
||||||
sljit_uw size;
|
sljit_uw size;
|
||||||
sljit_uw word_count;
|
sljit_uw word_count;
|
||||||
|
sljit_sw executable_offset;
|
||||||
|
sljit_sw jump_addr;
|
||||||
#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
|
#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
|
||||||
sljit_uw cpool_size;
|
sljit_uw cpool_size;
|
||||||
sljit_uw cpool_skip_alignment;
|
sljit_uw cpool_skip_alignment;
|
||||||
|
@ -602,14 +613,14 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
|
|
||||||
code_ptr = code;
|
code_ptr = code;
|
||||||
word_count = 0;
|
word_count = 0;
|
||||||
|
executable_offset = SLJIT_EXEC_OFFSET(code);
|
||||||
|
|
||||||
label = compiler->labels;
|
label = compiler->labels;
|
||||||
jump = compiler->jumps;
|
jump = compiler->jumps;
|
||||||
const_ = compiler->consts;
|
const_ = compiler->consts;
|
||||||
|
|
||||||
if (label && label->size == 0) {
|
if (label && label->size == 0) {
|
||||||
label->addr = (sljit_uw)code;
|
label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
|
||||||
label->size = 0;
|
|
||||||
label = label->next;
|
label = label->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -636,7 +647,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
cpool_size = 0;
|
cpool_size = 0;
|
||||||
if (label && label->size == word_count) {
|
if (label && label->size == word_count) {
|
||||||
/* Points after the current instruction. */
|
/* Points after the current instruction. */
|
||||||
label->addr = (sljit_uw)code_ptr;
|
label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
|
||||||
label->size = code_ptr - code;
|
label->size = code_ptr - code;
|
||||||
label = label->next;
|
label = label->next;
|
||||||
}
|
}
|
||||||
|
@ -652,19 +663,19 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
SLJIT_ASSERT(!const_ || const_->addr >= word_count);
|
SLJIT_ASSERT(!const_ || const_->addr >= word_count);
|
||||||
if (jump && jump->addr == word_count) {
|
if (jump && jump->addr == word_count) {
|
||||||
#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
|
#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
|
||||||
if (detect_jump_type(jump, code_ptr, code))
|
if (detect_jump_type(jump, code_ptr, code, executable_offset))
|
||||||
code_ptr--;
|
code_ptr--;
|
||||||
jump->addr = (sljit_uw)code_ptr;
|
jump->addr = (sljit_uw)code_ptr;
|
||||||
#else
|
#else
|
||||||
jump->addr = (sljit_uw)(code_ptr - 2);
|
jump->addr = (sljit_uw)(code_ptr - 2);
|
||||||
if (detect_jump_type(jump, code_ptr, code))
|
if (detect_jump_type(jump, code_ptr, code, executable_offset))
|
||||||
code_ptr -= 2;
|
code_ptr -= 2;
|
||||||
#endif
|
#endif
|
||||||
jump = jump->next;
|
jump = jump->next;
|
||||||
}
|
}
|
||||||
if (label && label->size == word_count) {
|
if (label && label->size == word_count) {
|
||||||
/* code_ptr can be affected above. */
|
/* code_ptr can be affected above. */
|
||||||
label->addr = (sljit_uw)(code_ptr + 1);
|
label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr + 1, executable_offset);
|
||||||
label->size = (code_ptr + 1) - code;
|
label->size = (code_ptr + 1) - code;
|
||||||
label = label->next;
|
label = label->next;
|
||||||
}
|
}
|
||||||
|
@ -732,14 +743,15 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
buf_ptr = (sljit_uw *)jump->addr;
|
buf_ptr = (sljit_uw *)jump->addr;
|
||||||
|
|
||||||
if (jump->flags & PATCH_B) {
|
if (jump->flags & PATCH_B) {
|
||||||
|
jump_addr = (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr + 2, executable_offset);
|
||||||
if (!(jump->flags & JUMP_ADDR)) {
|
if (!(jump->flags & JUMP_ADDR)) {
|
||||||
SLJIT_ASSERT(jump->flags & JUMP_LABEL);
|
SLJIT_ASSERT(jump->flags & JUMP_LABEL);
|
||||||
SLJIT_ASSERT(((sljit_sw)jump->u.label->addr - (sljit_sw)(buf_ptr + 2)) <= 0x01ffffff && ((sljit_sw)jump->u.label->addr - (sljit_sw)(buf_ptr + 2)) >= -0x02000000);
|
SLJIT_ASSERT(((sljit_sw)jump->u.label->addr - jump_addr) <= 0x01ffffff && ((sljit_sw)jump->u.label->addr - jump_addr) >= -0x02000000);
|
||||||
*buf_ptr |= (((sljit_sw)jump->u.label->addr - (sljit_sw)(buf_ptr + 2)) >> 2) & 0x00ffffff;
|
*buf_ptr |= (((sljit_sw)jump->u.label->addr - jump_addr) >> 2) & 0x00ffffff;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
SLJIT_ASSERT(((sljit_sw)jump->u.target - (sljit_sw)(buf_ptr + 2)) <= 0x01ffffff && ((sljit_sw)jump->u.target - (sljit_sw)(buf_ptr + 2)) >= -0x02000000);
|
SLJIT_ASSERT(((sljit_sw)jump->u.target - jump_addr) <= 0x01ffffff && ((sljit_sw)jump->u.target - jump_addr) >= -0x02000000);
|
||||||
*buf_ptr |= (((sljit_sw)jump->u.target - (sljit_sw)(buf_ptr + 2)) >> 2) & 0x00ffffff;
|
*buf_ptr |= (((sljit_sw)jump->u.target - jump_addr) >> 2) & 0x00ffffff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (jump->flags & SLJIT_REWRITABLE_JUMP) {
|
else if (jump->flags & SLJIT_REWRITABLE_JUMP) {
|
||||||
|
@ -747,10 +759,10 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
jump->addr = (sljit_uw)code_ptr;
|
jump->addr = (sljit_uw)code_ptr;
|
||||||
code_ptr[0] = (sljit_uw)buf_ptr;
|
code_ptr[0] = (sljit_uw)buf_ptr;
|
||||||
code_ptr[1] = *buf_ptr;
|
code_ptr[1] = *buf_ptr;
|
||||||
inline_set_jump_addr((sljit_uw)code_ptr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0);
|
inline_set_jump_addr((sljit_uw)code_ptr, executable_offset, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0);
|
||||||
code_ptr += 2;
|
code_ptr += 2;
|
||||||
#else
|
#else
|
||||||
inline_set_jump_addr((sljit_uw)buf_ptr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0);
|
inline_set_jump_addr((sljit_uw)buf_ptr, executable_offset, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -763,7 +775,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
buf_ptr += 1;
|
buf_ptr += 1;
|
||||||
*buf_ptr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
|
*buf_ptr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
|
||||||
#else
|
#else
|
||||||
inline_set_jump_addr((sljit_uw)buf_ptr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0);
|
inline_set_jump_addr((sljit_uw)buf_ptr, executable_offset, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
jump = jump->next;
|
jump = jump->next;
|
||||||
|
@ -782,7 +794,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
else
|
else
|
||||||
buf_ptr += 1;
|
buf_ptr += 1;
|
||||||
/* Set the value again (can be a simple constant). */
|
/* Set the value again (can be a simple constant). */
|
||||||
inline_set_const((sljit_uw)code_ptr, *buf_ptr, 0);
|
inline_set_const((sljit_uw)code_ptr, executable_offset, *buf_ptr, 0);
|
||||||
code_ptr += 2;
|
code_ptr += 2;
|
||||||
|
|
||||||
const_ = const_->next;
|
const_ = const_->next;
|
||||||
|
@ -792,7 +804,12 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
SLJIT_ASSERT(code_ptr - code <= (sljit_s32)size);
|
SLJIT_ASSERT(code_ptr - code <= (sljit_s32)size);
|
||||||
|
|
||||||
compiler->error = SLJIT_ERR_COMPILED;
|
compiler->error = SLJIT_ERR_COMPILED;
|
||||||
|
compiler->executable_offset = executable_offset;
|
||||||
compiler->executable_size = (code_ptr - code) * sizeof(sljit_uw);
|
compiler->executable_size = (code_ptr - code) * sizeof(sljit_uw);
|
||||||
|
|
||||||
|
code = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
|
||||||
|
code_ptr = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
|
||||||
|
|
||||||
SLJIT_CACHE_FLUSH(code, code_ptr);
|
SLJIT_CACHE_FLUSH(code, code_ptr);
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -2402,7 +2419,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
|
||||||
struct sljit_jump *jump;
|
struct sljit_jump *jump;
|
||||||
|
|
||||||
CHECK_ERROR_PTR();
|
CHECK_ERROR_PTR();
|
||||||
CHECK_DYN_CODE_MOD(type & SLJIT_REWRITABLE_JUMP);
|
|
||||||
CHECK_PTR(check_sljit_emit_jump(compiler, type));
|
CHECK_PTR(check_sljit_emit_jump(compiler, type));
|
||||||
|
|
||||||
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
||||||
|
@ -2535,7 +2551,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
|
||||||
sljit_s32 reg;
|
sljit_s32 reg;
|
||||||
|
|
||||||
CHECK_ERROR_PTR();
|
CHECK_ERROR_PTR();
|
||||||
CHECK_DYN_CODE_MOD(1);
|
|
||||||
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
||||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||||
|
|
||||||
|
@ -2557,12 +2572,12 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
|
||||||
return const_;
|
return const_;
|
||||||
}
|
}
|
||||||
|
|
||||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
|
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
|
||||||
{
|
{
|
||||||
inline_set_jump_addr(addr, new_addr, 1);
|
inline_set_jump_addr(addr, executable_offset, new_target, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
|
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
|
||||||
{
|
{
|
||||||
inline_set_const(addr, new_constant, 1);
|
inline_set_const(addr, executable_offset, new_constant, 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,7 +151,7 @@ static SLJIT_INLINE void modify_imm64_const(sljit_ins* inst, sljit_uw new_imm)
|
||||||
inst[3] = MOVK | dst | ((new_imm >> 48) << 5) | (3 << 21);
|
inst[3] = MOVK | dst | ((new_imm >> 48) << 5) | (3 << 21);
|
||||||
}
|
}
|
||||||
|
|
||||||
static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code)
|
static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)
|
||||||
{
|
{
|
||||||
sljit_sw diff;
|
sljit_sw diff;
|
||||||
sljit_uw target_addr;
|
sljit_uw target_addr;
|
||||||
|
@ -165,9 +165,10 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_in
|
||||||
target_addr = jump->u.target;
|
target_addr = jump->u.target;
|
||||||
else {
|
else {
|
||||||
SLJIT_ASSERT(jump->flags & JUMP_LABEL);
|
SLJIT_ASSERT(jump->flags & JUMP_LABEL);
|
||||||
target_addr = (sljit_uw)(code + jump->u.label->size);
|
target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset;
|
||||||
}
|
}
|
||||||
diff = (sljit_sw)target_addr - (sljit_sw)(code_ptr + 4);
|
|
||||||
|
diff = (sljit_sw)target_addr - (sljit_sw)(code_ptr + 4) - executable_offset;
|
||||||
|
|
||||||
if (jump->flags & IS_COND) {
|
if (jump->flags & IS_COND) {
|
||||||
diff += sizeof(sljit_ins);
|
diff += sizeof(sljit_ins);
|
||||||
|
@ -211,6 +212,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
sljit_ins *buf_ptr;
|
sljit_ins *buf_ptr;
|
||||||
sljit_ins *buf_end;
|
sljit_ins *buf_end;
|
||||||
sljit_uw word_count;
|
sljit_uw word_count;
|
||||||
|
sljit_sw executable_offset;
|
||||||
sljit_uw addr;
|
sljit_uw addr;
|
||||||
sljit_s32 dst;
|
sljit_s32 dst;
|
||||||
|
|
||||||
|
@ -228,6 +230,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
|
|
||||||
code_ptr = code;
|
code_ptr = code;
|
||||||
word_count = 0;
|
word_count = 0;
|
||||||
|
executable_offset = SLJIT_EXEC_OFFSET(code);
|
||||||
|
|
||||||
label = compiler->labels;
|
label = compiler->labels;
|
||||||
jump = compiler->jumps;
|
jump = compiler->jumps;
|
||||||
const_ = compiler->consts;
|
const_ = compiler->consts;
|
||||||
|
@ -242,13 +246,13 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
SLJIT_ASSERT(!jump || jump->addr >= word_count);
|
SLJIT_ASSERT(!jump || jump->addr >= word_count);
|
||||||
SLJIT_ASSERT(!const_ || const_->addr >= word_count);
|
SLJIT_ASSERT(!const_ || const_->addr >= word_count);
|
||||||
if (label && label->size == word_count) {
|
if (label && label->size == word_count) {
|
||||||
label->addr = (sljit_uw)code_ptr;
|
label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
|
||||||
label->size = code_ptr - code;
|
label->size = code_ptr - code;
|
||||||
label = label->next;
|
label = label->next;
|
||||||
}
|
}
|
||||||
if (jump && jump->addr == word_count) {
|
if (jump && jump->addr == word_count) {
|
||||||
jump->addr = (sljit_uw)(code_ptr - 4);
|
jump->addr = (sljit_uw)(code_ptr - 4);
|
||||||
code_ptr -= detect_jump_type(jump, code_ptr, code);
|
code_ptr -= detect_jump_type(jump, code_ptr, code, executable_offset);
|
||||||
jump = jump->next;
|
jump = jump->next;
|
||||||
}
|
}
|
||||||
if (const_ && const_->addr == word_count) {
|
if (const_ && const_->addr == word_count) {
|
||||||
|
@ -263,7 +267,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
} while (buf);
|
} while (buf);
|
||||||
|
|
||||||
if (label && label->size == word_count) {
|
if (label && label->size == word_count) {
|
||||||
label->addr = (sljit_uw)code_ptr;
|
label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
|
||||||
label->size = code_ptr - code;
|
label->size = code_ptr - code;
|
||||||
label = label->next;
|
label = label->next;
|
||||||
}
|
}
|
||||||
|
@ -278,8 +282,9 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
do {
|
do {
|
||||||
addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
|
addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
|
||||||
buf_ptr = (sljit_ins *)jump->addr;
|
buf_ptr = (sljit_ins *)jump->addr;
|
||||||
|
|
||||||
if (jump->flags & PATCH_B) {
|
if (jump->flags & PATCH_B) {
|
||||||
addr = (sljit_sw)(addr - jump->addr) >> 2;
|
addr = (sljit_sw)(addr - (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) >> 2;
|
||||||
SLJIT_ASSERT((sljit_sw)addr <= 0x1ffffff && (sljit_sw)addr >= -0x2000000);
|
SLJIT_ASSERT((sljit_sw)addr <= 0x1ffffff && (sljit_sw)addr >= -0x2000000);
|
||||||
buf_ptr[0] = ((jump->flags & IS_BL) ? BL : B) | (addr & 0x3ffffff);
|
buf_ptr[0] = ((jump->flags & IS_BL) ? BL : B) | (addr & 0x3ffffff);
|
||||||
if (jump->flags & IS_COND)
|
if (jump->flags & IS_COND)
|
||||||
|
@ -287,7 +292,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (jump->flags & PATCH_COND) {
|
if (jump->flags & PATCH_COND) {
|
||||||
addr = (sljit_sw)(addr - jump->addr) >> 2;
|
addr = (sljit_sw)(addr - (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) >> 2;
|
||||||
SLJIT_ASSERT((sljit_sw)addr <= 0x3ffff && (sljit_sw)addr >= -0x40000);
|
SLJIT_ASSERT((sljit_sw)addr <= 0x3ffff && (sljit_sw)addr >= -0x40000);
|
||||||
buf_ptr[0] = (buf_ptr[0] & ~0xffffe0) | ((addr & 0x7ffff) << 5);
|
buf_ptr[0] = (buf_ptr[0] & ~0xffffe0) | ((addr & 0x7ffff) << 5);
|
||||||
break;
|
break;
|
||||||
|
@ -308,7 +313,12 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
}
|
}
|
||||||
|
|
||||||
compiler->error = SLJIT_ERR_COMPILED;
|
compiler->error = SLJIT_ERR_COMPILED;
|
||||||
|
compiler->executable_offset = executable_offset;
|
||||||
compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
|
compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
|
||||||
|
|
||||||
|
code = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
|
||||||
|
code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
|
||||||
|
|
||||||
SLJIT_CACHE_FLUSH(code, code_ptr);
|
SLJIT_CACHE_FLUSH(code, code_ptr);
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -1882,7 +1892,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
|
||||||
struct sljit_jump *jump;
|
struct sljit_jump *jump;
|
||||||
|
|
||||||
CHECK_ERROR_PTR();
|
CHECK_ERROR_PTR();
|
||||||
CHECK_DYN_CODE_MOD(type & SLJIT_REWRITABLE_JUMP);
|
|
||||||
CHECK_PTR(check_sljit_emit_jump(compiler, type));
|
CHECK_PTR(check_sljit_emit_jump(compiler, type));
|
||||||
|
|
||||||
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
||||||
|
@ -2021,7 +2030,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
|
||||||
sljit_s32 dst_r;
|
sljit_s32 dst_r;
|
||||||
|
|
||||||
CHECK_ERROR_PTR();
|
CHECK_ERROR_PTR();
|
||||||
CHECK_DYN_CODE_MOD(1);
|
|
||||||
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
||||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||||
|
|
||||||
|
@ -2037,16 +2045,18 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
|
||||||
return const_;
|
return const_;
|
||||||
}
|
}
|
||||||
|
|
||||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
|
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
|
||||||
{
|
{
|
||||||
sljit_ins* inst = (sljit_ins*)addr;
|
sljit_ins* inst = (sljit_ins*)addr;
|
||||||
modify_imm64_const(inst, new_addr);
|
modify_imm64_const(inst, new_target);
|
||||||
|
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||||
SLJIT_CACHE_FLUSH(inst, inst + 4);
|
SLJIT_CACHE_FLUSH(inst, inst + 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
|
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
|
||||||
{
|
{
|
||||||
sljit_ins* inst = (sljit_ins*)addr;
|
sljit_ins* inst = (sljit_ins*)addr;
|
||||||
modify_imm64_const(inst, new_constant);
|
modify_imm64_const(inst, new_constant);
|
||||||
|
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||||
SLJIT_CACHE_FLUSH(inst, inst + 4);
|
SLJIT_CACHE_FLUSH(inst, inst + 4);
|
||||||
}
|
}
|
||||||
|
|
|
@ -221,7 +221,7 @@ static SLJIT_INLINE void modify_imm32_const(sljit_u16 *inst, sljit_uw new_imm)
|
||||||
inst[3] = dst | COPY_BITS(new_imm, 8 + 16, 12, 3) | ((new_imm & 0xff0000) >> 16);
|
inst[3] = dst | COPY_BITS(new_imm, 8 + 16, 12, 3) | ((new_imm & 0xff0000) >> 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_u16 *code_ptr, sljit_u16 *code)
|
static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_u16 *code_ptr, sljit_u16 *code, sljit_sw executable_offset)
|
||||||
{
|
{
|
||||||
sljit_sw diff;
|
sljit_sw diff;
|
||||||
|
|
||||||
|
@ -232,7 +232,7 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_u1
|
||||||
/* Branch to ARM code is not optimized yet. */
|
/* Branch to ARM code is not optimized yet. */
|
||||||
if (!(jump->u.target & 0x1))
|
if (!(jump->u.target & 0x1))
|
||||||
return 0;
|
return 0;
|
||||||
diff = ((sljit_sw)jump->u.target - (sljit_sw)(code_ptr + 2)) >> 1;
|
diff = ((sljit_sw)jump->u.target - (sljit_sw)(code_ptr + 2) - executable_offset) >> 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
SLJIT_ASSERT(jump->flags & JUMP_LABEL);
|
SLJIT_ASSERT(jump->flags & JUMP_LABEL);
|
||||||
|
@ -276,7 +276,7 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_u1
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SLJIT_INLINE void set_jump_instruction(struct sljit_jump *jump)
|
static SLJIT_INLINE void set_jump_instruction(struct sljit_jump *jump, sljit_sw executable_offset)
|
||||||
{
|
{
|
||||||
sljit_s32 type = (jump->flags >> 4) & 0xf;
|
sljit_s32 type = (jump->flags >> 4) & 0xf;
|
||||||
sljit_sw diff;
|
sljit_sw diff;
|
||||||
|
@ -290,10 +290,12 @@ static SLJIT_INLINE void set_jump_instruction(struct sljit_jump *jump)
|
||||||
|
|
||||||
if (jump->flags & JUMP_ADDR) {
|
if (jump->flags & JUMP_ADDR) {
|
||||||
SLJIT_ASSERT(jump->u.target & 0x1);
|
SLJIT_ASSERT(jump->u.target & 0x1);
|
||||||
diff = ((sljit_sw)jump->u.target - (sljit_sw)(jump->addr + 4)) >> 1;
|
diff = ((sljit_sw)jump->u.target - (sljit_sw)(jump->addr + sizeof(sljit_u32)) - executable_offset) >> 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SLJIT_ASSERT(jump->u.label->addr & 0x1);
|
||||||
|
diff = ((sljit_sw)(jump->u.label->addr) - (sljit_sw)(jump->addr + sizeof(sljit_u32)) - executable_offset) >> 1;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
diff = ((sljit_sw)(jump->u.label->addr) - (sljit_sw)(jump->addr + 4)) >> 1;
|
|
||||||
jump_inst = (sljit_u16*)jump->addr;
|
jump_inst = (sljit_u16*)jump->addr;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
@ -347,6 +349,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
sljit_u16 *buf_ptr;
|
sljit_u16 *buf_ptr;
|
||||||
sljit_u16 *buf_end;
|
sljit_u16 *buf_end;
|
||||||
sljit_uw half_count;
|
sljit_uw half_count;
|
||||||
|
sljit_sw executable_offset;
|
||||||
|
|
||||||
struct sljit_label *label;
|
struct sljit_label *label;
|
||||||
struct sljit_jump *jump;
|
struct sljit_jump *jump;
|
||||||
|
@ -362,6 +365,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
|
|
||||||
code_ptr = code;
|
code_ptr = code;
|
||||||
half_count = 0;
|
half_count = 0;
|
||||||
|
executable_offset = SLJIT_EXEC_OFFSET(code);
|
||||||
|
|
||||||
label = compiler->labels;
|
label = compiler->labels;
|
||||||
jump = compiler->jumps;
|
jump = compiler->jumps;
|
||||||
const_ = compiler->consts;
|
const_ = compiler->consts;
|
||||||
|
@ -376,13 +381,13 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
SLJIT_ASSERT(!jump || jump->addr >= half_count);
|
SLJIT_ASSERT(!jump || jump->addr >= half_count);
|
||||||
SLJIT_ASSERT(!const_ || const_->addr >= half_count);
|
SLJIT_ASSERT(!const_ || const_->addr >= half_count);
|
||||||
if (label && label->size == half_count) {
|
if (label && label->size == half_count) {
|
||||||
label->addr = ((sljit_uw)code_ptr) | 0x1;
|
label->addr = ((sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset)) | 0x1;
|
||||||
label->size = code_ptr - code;
|
label->size = code_ptr - code;
|
||||||
label = label->next;
|
label = label->next;
|
||||||
}
|
}
|
||||||
if (jump && jump->addr == half_count) {
|
if (jump && jump->addr == half_count) {
|
||||||
jump->addr = (sljit_uw)code_ptr - ((jump->flags & IS_COND) ? 10 : 8);
|
jump->addr = (sljit_uw)code_ptr - ((jump->flags & IS_COND) ? 10 : 8);
|
||||||
code_ptr -= detect_jump_type(jump, code_ptr, code);
|
code_ptr -= detect_jump_type(jump, code_ptr, code, executable_offset);
|
||||||
jump = jump->next;
|
jump = jump->next;
|
||||||
}
|
}
|
||||||
if (const_ && const_->addr == half_count) {
|
if (const_ && const_->addr == half_count) {
|
||||||
|
@ -397,7 +402,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
} while (buf);
|
} while (buf);
|
||||||
|
|
||||||
if (label && label->size == half_count) {
|
if (label && label->size == half_count) {
|
||||||
label->addr = ((sljit_uw)code_ptr) | 0x1;
|
label->addr = ((sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset)) | 0x1;
|
||||||
label->size = code_ptr - code;
|
label->size = code_ptr - code;
|
||||||
label = label->next;
|
label = label->next;
|
||||||
}
|
}
|
||||||
|
@ -409,12 +414,17 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
|
|
||||||
jump = compiler->jumps;
|
jump = compiler->jumps;
|
||||||
while (jump) {
|
while (jump) {
|
||||||
set_jump_instruction(jump);
|
set_jump_instruction(jump, executable_offset);
|
||||||
jump = jump->next;
|
jump = jump->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
compiler->error = SLJIT_ERR_COMPILED;
|
compiler->error = SLJIT_ERR_COMPILED;
|
||||||
|
compiler->executable_offset = executable_offset;
|
||||||
compiler->executable_size = (code_ptr - code) * sizeof(sljit_u16);
|
compiler->executable_size = (code_ptr - code) * sizeof(sljit_u16);
|
||||||
|
|
||||||
|
code = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
|
||||||
|
code_ptr = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
|
||||||
|
|
||||||
SLJIT_CACHE_FLUSH(code, code_ptr);
|
SLJIT_CACHE_FLUSH(code, code_ptr);
|
||||||
/* Set thumb mode flag. */
|
/* Set thumb mode flag. */
|
||||||
return (void*)((sljit_uw)code | 0x1);
|
return (void*)((sljit_uw)code | 0x1);
|
||||||
|
@ -1917,7 +1927,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
|
||||||
sljit_ins cc;
|
sljit_ins cc;
|
||||||
|
|
||||||
CHECK_ERROR_PTR();
|
CHECK_ERROR_PTR();
|
||||||
CHECK_DYN_CODE_MOD(type & SLJIT_REWRITABLE_JUMP);
|
|
||||||
CHECK_PTR(check_sljit_emit_jump(compiler, type));
|
CHECK_PTR(check_sljit_emit_jump(compiler, type));
|
||||||
|
|
||||||
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
||||||
|
@ -2061,7 +2070,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
|
||||||
sljit_s32 dst_r;
|
sljit_s32 dst_r;
|
||||||
|
|
||||||
CHECK_ERROR_PTR();
|
CHECK_ERROR_PTR();
|
||||||
CHECK_DYN_CODE_MOD(1);
|
|
||||||
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
||||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||||
|
|
||||||
|
@ -2077,16 +2085,18 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
|
||||||
return const_;
|
return const_;
|
||||||
}
|
}
|
||||||
|
|
||||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
|
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
|
||||||
{
|
{
|
||||||
sljit_u16 *inst = (sljit_u16*)addr;
|
sljit_u16 *inst = (sljit_u16*)addr;
|
||||||
modify_imm32_const(inst, new_addr);
|
modify_imm32_const(inst, new_target);
|
||||||
|
inst = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||||
SLJIT_CACHE_FLUSH(inst, inst + 4);
|
SLJIT_CACHE_FLUSH(inst, inst + 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
|
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
|
||||||
{
|
{
|
||||||
sljit_u16 *inst = (sljit_u16*)addr;
|
sljit_u16 *inst = (sljit_u16*)addr;
|
||||||
modify_imm32_const(inst, new_constant);
|
modify_imm32_const(inst, new_constant);
|
||||||
|
inst = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||||
SLJIT_CACHE_FLUSH(inst, inst + 4);
|
SLJIT_CACHE_FLUSH(inst, inst + 4);
|
||||||
}
|
}
|
||||||
|
|
|
@ -347,20 +347,22 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_
|
||||||
return push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value), DR(dst));
|
return push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value), DR(dst));
|
||||||
}
|
}
|
||||||
|
|
||||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
|
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
|
||||||
{
|
{
|
||||||
sljit_ins *inst = (sljit_ins *)addr;
|
sljit_ins *inst = (sljit_ins *)addr;
|
||||||
|
|
||||||
inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 16) & 0xffff);
|
inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 16) & 0xffff);
|
||||||
inst[1] = (inst[1] & 0xffff0000) | (new_addr & 0xffff);
|
inst[1] = (inst[1] & 0xffff0000) | (new_target & 0xffff);
|
||||||
|
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||||
SLJIT_CACHE_FLUSH(inst, inst + 2);
|
SLJIT_CACHE_FLUSH(inst, inst + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
|
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
|
||||||
{
|
{
|
||||||
sljit_ins *inst = (sljit_ins *)addr;
|
sljit_ins *inst = (sljit_ins *)addr;
|
||||||
|
|
||||||
inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
|
inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
|
||||||
inst[1] = (inst[1] & 0xffff0000) | (new_constant & 0xffff);
|
inst[1] = (inst[1] & 0xffff0000) | (new_constant & 0xffff);
|
||||||
|
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||||
SLJIT_CACHE_FLUSH(inst, inst + 2);
|
SLJIT_CACHE_FLUSH(inst, inst + 2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -446,18 +446,19 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_
|
||||||
return push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value), DR(dst));
|
return push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value), DR(dst));
|
||||||
}
|
}
|
||||||
|
|
||||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
|
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
|
||||||
{
|
{
|
||||||
sljit_ins *inst = (sljit_ins *)addr;
|
sljit_ins *inst = (sljit_ins *)addr;
|
||||||
|
|
||||||
inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 48) & 0xffff);
|
inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 48) & 0xffff);
|
||||||
inst[1] = (inst[1] & 0xffff0000) | ((new_addr >> 32) & 0xffff);
|
inst[1] = (inst[1] & 0xffff0000) | ((new_target >> 32) & 0xffff);
|
||||||
inst[3] = (inst[3] & 0xffff0000) | ((new_addr >> 16) & 0xffff);
|
inst[3] = (inst[3] & 0xffff0000) | ((new_target >> 16) & 0xffff);
|
||||||
inst[5] = (inst[5] & 0xffff0000) | (new_addr & 0xffff);
|
inst[5] = (inst[5] & 0xffff0000) | (new_target & 0xffff);
|
||||||
|
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||||
SLJIT_CACHE_FLUSH(inst, inst + 6);
|
SLJIT_CACHE_FLUSH(inst, inst + 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
|
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
|
||||||
{
|
{
|
||||||
sljit_ins *inst = (sljit_ins *)addr;
|
sljit_ins *inst = (sljit_ins *)addr;
|
||||||
|
|
||||||
|
@ -465,5 +466,6 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_consta
|
||||||
inst[1] = (inst[1] & 0xffff0000) | ((new_constant >> 32) & 0xffff);
|
inst[1] = (inst[1] & 0xffff0000) | ((new_constant >> 32) & 0xffff);
|
||||||
inst[3] = (inst[3] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
|
inst[3] = (inst[3] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
|
||||||
inst[5] = (inst[5] & 0xffff0000) | (new_constant & 0xffff);
|
inst[5] = (inst[5] & 0xffff0000) | (new_constant & 0xffff);
|
||||||
|
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||||
SLJIT_CACHE_FLUSH(inst, inst + 6);
|
SLJIT_CACHE_FLUSH(inst, inst + 6);
|
||||||
}
|
}
|
||||||
|
|
|
@ -218,7 +218,7 @@ static SLJIT_INLINE sljit_ins invert_branch(sljit_s32 flags)
|
||||||
return (flags & IS_BIT26_COND) ? (1 << 26) : (1 << 16);
|
return (flags & IS_BIT26_COND) ? (1 << 26) : (1 << 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code)
|
static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)
|
||||||
{
|
{
|
||||||
sljit_sw diff;
|
sljit_sw diff;
|
||||||
sljit_uw target_addr;
|
sljit_uw target_addr;
|
||||||
|
@ -237,8 +237,9 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i
|
||||||
target_addr = jump->u.target;
|
target_addr = jump->u.target;
|
||||||
else {
|
else {
|
||||||
SLJIT_ASSERT(jump->flags & JUMP_LABEL);
|
SLJIT_ASSERT(jump->flags & JUMP_LABEL);
|
||||||
target_addr = (sljit_uw)(code + jump->u.label->size);
|
target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
inst = (sljit_ins *)jump->addr;
|
inst = (sljit_ins *)jump->addr;
|
||||||
if (jump->flags & IS_COND)
|
if (jump->flags & IS_COND)
|
||||||
inst--;
|
inst--;
|
||||||
|
@ -250,7 +251,7 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i
|
||||||
|
|
||||||
/* B instructions. */
|
/* B instructions. */
|
||||||
if (jump->flags & IS_MOVABLE) {
|
if (jump->flags & IS_MOVABLE) {
|
||||||
diff = ((sljit_sw)target_addr - (sljit_sw)(inst)) >> 2;
|
diff = ((sljit_sw)target_addr - (sljit_sw)inst - executable_offset) >> 2;
|
||||||
if (diff <= SIMM_MAX && diff >= SIMM_MIN) {
|
if (diff <= SIMM_MAX && diff >= SIMM_MIN) {
|
||||||
jump->flags |= PATCH_B;
|
jump->flags |= PATCH_B;
|
||||||
|
|
||||||
|
@ -268,7 +269,7 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
diff = ((sljit_sw)target_addr - (sljit_sw)(inst + 1)) >> 2;
|
diff = ((sljit_sw)target_addr - (sljit_sw)(inst + 1) - executable_offset) >> 2;
|
||||||
if (diff <= SIMM_MAX && diff >= SIMM_MIN) {
|
if (diff <= SIMM_MAX && diff >= SIMM_MIN) {
|
||||||
jump->flags |= PATCH_B;
|
jump->flags |= PATCH_B;
|
||||||
|
|
||||||
|
@ -364,6 +365,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
sljit_ins *buf_ptr;
|
sljit_ins *buf_ptr;
|
||||||
sljit_ins *buf_end;
|
sljit_ins *buf_end;
|
||||||
sljit_uw word_count;
|
sljit_uw word_count;
|
||||||
|
sljit_sw executable_offset;
|
||||||
sljit_uw addr;
|
sljit_uw addr;
|
||||||
|
|
||||||
struct sljit_label *label;
|
struct sljit_label *label;
|
||||||
|
@ -380,9 +382,12 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
|
|
||||||
code_ptr = code;
|
code_ptr = code;
|
||||||
word_count = 0;
|
word_count = 0;
|
||||||
|
executable_offset = SLJIT_EXEC_OFFSET(code);
|
||||||
|
|
||||||
label = compiler->labels;
|
label = compiler->labels;
|
||||||
jump = compiler->jumps;
|
jump = compiler->jumps;
|
||||||
const_ = compiler->consts;
|
const_ = compiler->consts;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
buf_ptr = (sljit_ins*)buf->memory;
|
buf_ptr = (sljit_ins*)buf->memory;
|
||||||
buf_end = buf_ptr + (buf->used_size >> 2);
|
buf_end = buf_ptr + (buf->used_size >> 2);
|
||||||
|
@ -393,8 +398,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
SLJIT_ASSERT(!const_ || const_->addr >= word_count);
|
SLJIT_ASSERT(!const_ || const_->addr >= word_count);
|
||||||
/* These structures are ordered by their address. */
|
/* These structures are ordered by their address. */
|
||||||
if (label && label->size == word_count) {
|
if (label && label->size == word_count) {
|
||||||
/* Just recording the address. */
|
label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
|
||||||
label->addr = (sljit_uw)code_ptr;
|
|
||||||
label->size = code_ptr - code;
|
label->size = code_ptr - code;
|
||||||
label = label->next;
|
label = label->next;
|
||||||
}
|
}
|
||||||
|
@ -404,7 +408,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
#else
|
#else
|
||||||
jump->addr = (sljit_uw)(code_ptr - 7);
|
jump->addr = (sljit_uw)(code_ptr - 7);
|
||||||
#endif
|
#endif
|
||||||
code_ptr = detect_jump_type(jump, code_ptr, code);
|
code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset);
|
||||||
jump = jump->next;
|
jump = jump->next;
|
||||||
}
|
}
|
||||||
if (const_ && const_->addr == word_count) {
|
if (const_ && const_->addr == word_count) {
|
||||||
|
@ -437,13 +441,13 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
buf_ptr = (sljit_ins *)jump->addr;
|
buf_ptr = (sljit_ins *)jump->addr;
|
||||||
|
|
||||||
if (jump->flags & PATCH_B) {
|
if (jump->flags & PATCH_B) {
|
||||||
addr = (sljit_sw)(addr - (jump->addr + sizeof(sljit_ins))) >> 2;
|
addr = (sljit_sw)(addr - ((sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset) + sizeof(sljit_ins))) >> 2;
|
||||||
SLJIT_ASSERT((sljit_sw)addr <= SIMM_MAX && (sljit_sw)addr >= SIMM_MIN);
|
SLJIT_ASSERT((sljit_sw)addr <= SIMM_MAX && (sljit_sw)addr >= SIMM_MIN);
|
||||||
buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | (addr & 0xffff);
|
buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | (addr & 0xffff);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (jump->flags & PATCH_J) {
|
if (jump->flags & PATCH_J) {
|
||||||
SLJIT_ASSERT((addr & ~0xfffffff) == ((jump->addr + sizeof(sljit_ins)) & ~0xfffffff));
|
SLJIT_ASSERT((addr & ~0xfffffff) == (((sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset) + sizeof(sljit_ins)) & ~0xfffffff));
|
||||||
buf_ptr[0] |= (addr >> 2) & 0x03ffffff;
|
buf_ptr[0] |= (addr >> 2) & 0x03ffffff;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -476,7 +480,12 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
}
|
}
|
||||||
|
|
||||||
compiler->error = SLJIT_ERR_COMPILED;
|
compiler->error = SLJIT_ERR_COMPILED;
|
||||||
|
compiler->executable_offset = executable_offset;
|
||||||
compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
|
compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
|
||||||
|
|
||||||
|
code = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
|
||||||
|
code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
|
||||||
|
|
||||||
#ifndef __GNUC__
|
#ifndef __GNUC__
|
||||||
SLJIT_CACHE_FLUSH(code, code_ptr);
|
SLJIT_CACHE_FLUSH(code, code_ptr);
|
||||||
#else
|
#else
|
||||||
|
@ -1625,7 +1634,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
|
||||||
sljit_s32 delay_check = UNMOVABLE_INS;
|
sljit_s32 delay_check = UNMOVABLE_INS;
|
||||||
|
|
||||||
CHECK_ERROR_PTR();
|
CHECK_ERROR_PTR();
|
||||||
CHECK_DYN_CODE_MOD(type & SLJIT_REWRITABLE_JUMP);
|
|
||||||
CHECK_PTR(check_sljit_emit_jump(compiler, type));
|
CHECK_PTR(check_sljit_emit_jump(compiler, type));
|
||||||
|
|
||||||
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
||||||
|
@ -1743,7 +1751,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler
|
||||||
sljit_ins inst;
|
sljit_ins inst;
|
||||||
|
|
||||||
CHECK_ERROR_PTR();
|
CHECK_ERROR_PTR();
|
||||||
CHECK_DYN_CODE_MOD(type & SLJIT_REWRITABLE_JUMP);
|
|
||||||
CHECK_PTR(check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w));
|
CHECK_PTR(check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w));
|
||||||
ADJUST_LOCAL_OFFSET(src1, src1w);
|
ADJUST_LOCAL_OFFSET(src1, src1w);
|
||||||
ADJUST_LOCAL_OFFSET(src2, src2w);
|
ADJUST_LOCAL_OFFSET(src2, src2w);
|
||||||
|
@ -1865,7 +1872,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compile
|
||||||
sljit_s32 if_true;
|
sljit_s32 if_true;
|
||||||
|
|
||||||
CHECK_ERROR_PTR();
|
CHECK_ERROR_PTR();
|
||||||
CHECK_DYN_CODE_MOD(type & SLJIT_REWRITABLE_JUMP);
|
|
||||||
CHECK_PTR(check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w));
|
CHECK_PTR(check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w));
|
||||||
|
|
||||||
compiler->cache_arg = 0;
|
compiler->cache_arg = 0;
|
||||||
|
@ -2124,7 +2130,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
|
||||||
sljit_s32 reg;
|
sljit_s32 reg;
|
||||||
|
|
||||||
CHECK_ERROR_PTR();
|
CHECK_ERROR_PTR();
|
||||||
CHECK_DYN_CODE_MOD(1);
|
|
||||||
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
||||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||||
|
|
||||||
|
|
|
@ -250,20 +250,22 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_
|
||||||
return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value));
|
return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value));
|
||||||
}
|
}
|
||||||
|
|
||||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
|
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
|
||||||
{
|
{
|
||||||
sljit_ins *inst = (sljit_ins *)addr;
|
sljit_ins *inst = (sljit_ins *)addr;
|
||||||
|
|
||||||
inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 16) & 0xffff);
|
inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 16) & 0xffff);
|
||||||
inst[1] = (inst[1] & 0xffff0000) | (new_addr & 0xffff);
|
inst[1] = (inst[1] & 0xffff0000) | (new_target & 0xffff);
|
||||||
|
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||||
SLJIT_CACHE_FLUSH(inst, inst + 2);
|
SLJIT_CACHE_FLUSH(inst, inst + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
|
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
|
||||||
{
|
{
|
||||||
sljit_ins *inst = (sljit_ins *)addr;
|
sljit_ins *inst = (sljit_ins *)addr;
|
||||||
|
|
||||||
inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
|
inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
|
||||||
inst[1] = (inst[1] & 0xffff0000) | (new_constant & 0xffff);
|
inst[1] = (inst[1] & 0xffff0000) | (new_constant & 0xffff);
|
||||||
|
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||||
SLJIT_CACHE_FLUSH(inst, inst + 2);
|
SLJIT_CACHE_FLUSH(inst, inst + 2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -398,18 +398,19 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_
|
||||||
return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value));
|
return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value));
|
||||||
}
|
}
|
||||||
|
|
||||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
|
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
|
||||||
{
|
{
|
||||||
sljit_ins *inst = (sljit_ins*)addr;
|
sljit_ins *inst = (sljit_ins*)addr;
|
||||||
|
|
||||||
inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 48) & 0xffff);
|
inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 48) & 0xffff);
|
||||||
inst[1] = (inst[1] & 0xffff0000) | ((new_addr >> 32) & 0xffff);
|
inst[1] = (inst[1] & 0xffff0000) | ((new_target >> 32) & 0xffff);
|
||||||
inst[3] = (inst[3] & 0xffff0000) | ((new_addr >> 16) & 0xffff);
|
inst[3] = (inst[3] & 0xffff0000) | ((new_target >> 16) & 0xffff);
|
||||||
inst[4] = (inst[4] & 0xffff0000) | (new_addr & 0xffff);
|
inst[4] = (inst[4] & 0xffff0000) | (new_target & 0xffff);
|
||||||
|
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||||
SLJIT_CACHE_FLUSH(inst, inst + 5);
|
SLJIT_CACHE_FLUSH(inst, inst + 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
|
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
|
||||||
{
|
{
|
||||||
sljit_ins *inst = (sljit_ins*)addr;
|
sljit_ins *inst = (sljit_ins*)addr;
|
||||||
|
|
||||||
|
@ -417,5 +418,6 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_consta
|
||||||
inst[1] = (inst[1] & 0xffff0000) | ((new_constant >> 32) & 0xffff);
|
inst[1] = (inst[1] & 0xffff0000) | ((new_constant >> 32) & 0xffff);
|
||||||
inst[3] = (inst[3] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
|
inst[3] = (inst[3] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
|
||||||
inst[4] = (inst[4] & 0xffff0000) | (new_constant & 0xffff);
|
inst[4] = (inst[4] & 0xffff0000) | (new_constant & 0xffff);
|
||||||
|
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||||
SLJIT_CACHE_FLUSH(inst, inst + 5);
|
SLJIT_CACHE_FLUSH(inst, inst + 5);
|
||||||
}
|
}
|
||||||
|
|
|
@ -249,7 +249,7 @@ static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins)
|
||||||
return SLJIT_SUCCESS;
|
return SLJIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code)
|
static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)
|
||||||
{
|
{
|
||||||
sljit_sw diff;
|
sljit_sw diff;
|
||||||
sljit_uw target_addr;
|
sljit_uw target_addr;
|
||||||
|
@ -267,7 +267,7 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_in
|
||||||
target_addr = jump->u.target;
|
target_addr = jump->u.target;
|
||||||
else {
|
else {
|
||||||
SLJIT_ASSERT(jump->flags & JUMP_LABEL);
|
SLJIT_ASSERT(jump->flags & JUMP_LABEL);
|
||||||
target_addr = (sljit_uw)(code + jump->u.label->size);
|
target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) && (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
|
#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) && (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
|
||||||
|
@ -275,7 +275,7 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_in
|
||||||
goto keep_address;
|
goto keep_address;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
diff = ((sljit_sw)target_addr - (sljit_sw)(code_ptr)) & ~0x3l;
|
diff = ((sljit_sw)target_addr - (sljit_sw)(code_ptr) - executable_offset) & ~0x3l;
|
||||||
|
|
||||||
extra_jump_flags = 0;
|
extra_jump_flags = 0;
|
||||||
if (jump->flags & IS_COND) {
|
if (jump->flags & IS_COND) {
|
||||||
|
@ -296,6 +296,7 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_in
|
||||||
jump->flags |= PATCH_B | extra_jump_flags;
|
jump->flags |= PATCH_B | extra_jump_flags;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target_addr <= 0x03ffffff) {
|
if (target_addr <= 0x03ffffff) {
|
||||||
jump->flags |= PATCH_B | PATCH_ABS_B | extra_jump_flags;
|
jump->flags |= PATCH_B | PATCH_ABS_B | extra_jump_flags;
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -309,6 +310,7 @@ keep_address:
|
||||||
jump->flags |= PATCH_ABS32;
|
jump->flags |= PATCH_ABS32;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target_addr <= 0x7fffffffffffl) {
|
if (target_addr <= 0x7fffffffffffl) {
|
||||||
jump->flags |= PATCH_ABS48;
|
jump->flags |= PATCH_ABS48;
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -326,6 +328,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
sljit_ins *buf_ptr;
|
sljit_ins *buf_ptr;
|
||||||
sljit_ins *buf_end;
|
sljit_ins *buf_end;
|
||||||
sljit_uw word_count;
|
sljit_uw word_count;
|
||||||
|
sljit_sw executable_offset;
|
||||||
sljit_uw addr;
|
sljit_uw addr;
|
||||||
|
|
||||||
struct sljit_label *label;
|
struct sljit_label *label;
|
||||||
|
@ -349,9 +352,12 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
|
|
||||||
code_ptr = code;
|
code_ptr = code;
|
||||||
word_count = 0;
|
word_count = 0;
|
||||||
|
executable_offset = SLJIT_EXEC_OFFSET(code);
|
||||||
|
|
||||||
label = compiler->labels;
|
label = compiler->labels;
|
||||||
jump = compiler->jumps;
|
jump = compiler->jumps;
|
||||||
const_ = compiler->consts;
|
const_ = compiler->consts;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
buf_ptr = (sljit_ins*)buf->memory;
|
buf_ptr = (sljit_ins*)buf->memory;
|
||||||
buf_end = buf_ptr + (buf->used_size >> 2);
|
buf_end = buf_ptr + (buf->used_size >> 2);
|
||||||
|
@ -363,7 +369,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
/* These structures are ordered by their address. */
|
/* These structures are ordered by their address. */
|
||||||
if (label && label->size == word_count) {
|
if (label && label->size == word_count) {
|
||||||
/* Just recording the address. */
|
/* Just recording the address. */
|
||||||
label->addr = (sljit_uw)code_ptr;
|
label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
|
||||||
label->size = code_ptr - code;
|
label->size = code_ptr - code;
|
||||||
label = label->next;
|
label = label->next;
|
||||||
}
|
}
|
||||||
|
@ -373,7 +379,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
#else
|
#else
|
||||||
jump->addr = (sljit_uw)(code_ptr - 6);
|
jump->addr = (sljit_uw)(code_ptr - 6);
|
||||||
#endif
|
#endif
|
||||||
if (detect_jump_type(jump, code_ptr, code)) {
|
if (detect_jump_type(jump, code_ptr, code, executable_offset)) {
|
||||||
#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
|
#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
|
||||||
code_ptr[-3] = code_ptr[0];
|
code_ptr[-3] = code_ptr[0];
|
||||||
code_ptr -= 3;
|
code_ptr -= 3;
|
||||||
|
@ -420,7 +426,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
} while (buf);
|
} while (buf);
|
||||||
|
|
||||||
if (label && label->size == word_count) {
|
if (label && label->size == word_count) {
|
||||||
label->addr = (sljit_uw)code_ptr;
|
label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
|
||||||
label->size = code_ptr - code;
|
label->size = code_ptr - code;
|
||||||
label = label->next;
|
label = label->next;
|
||||||
}
|
}
|
||||||
|
@ -439,10 +445,11 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
do {
|
do {
|
||||||
addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
|
addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
|
||||||
buf_ptr = (sljit_ins *)jump->addr;
|
buf_ptr = (sljit_ins *)jump->addr;
|
||||||
|
|
||||||
if (jump->flags & PATCH_B) {
|
if (jump->flags & PATCH_B) {
|
||||||
if (jump->flags & IS_COND) {
|
if (jump->flags & IS_COND) {
|
||||||
if (!(jump->flags & PATCH_ABS_B)) {
|
if (!(jump->flags & PATCH_ABS_B)) {
|
||||||
addr = addr - jump->addr;
|
addr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset);
|
||||||
SLJIT_ASSERT((sljit_sw)addr <= 0x7fff && (sljit_sw)addr >= -0x8000);
|
SLJIT_ASSERT((sljit_sw)addr <= 0x7fff && (sljit_sw)addr >= -0x8000);
|
||||||
*buf_ptr = BCx | (addr & 0xfffc) | ((*buf_ptr) & 0x03ff0001);
|
*buf_ptr = BCx | (addr & 0xfffc) | ((*buf_ptr) & 0x03ff0001);
|
||||||
}
|
}
|
||||||
|
@ -453,7 +460,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!(jump->flags & PATCH_ABS_B)) {
|
if (!(jump->flags & PATCH_ABS_B)) {
|
||||||
addr = addr - jump->addr;
|
addr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset);
|
||||||
SLJIT_ASSERT((sljit_sw)addr <= 0x01ffffff && (sljit_sw)addr >= -0x02000000);
|
SLJIT_ASSERT((sljit_sw)addr <= 0x01ffffff && (sljit_sw)addr >= -0x02000000);
|
||||||
*buf_ptr = Bx | (addr & 0x03fffffc) | ((*buf_ptr) & 0x1);
|
*buf_ptr = Bx | (addr & 0x03fffffc) | ((*buf_ptr) & 0x1);
|
||||||
}
|
}
|
||||||
|
@ -464,6 +471,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the fields of immediate loads. */
|
/* Set the fields of immediate loads. */
|
||||||
#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
|
#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
|
||||||
buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff);
|
buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff);
|
||||||
|
@ -492,19 +500,25 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
}
|
}
|
||||||
|
|
||||||
compiler->error = SLJIT_ERR_COMPILED;
|
compiler->error = SLJIT_ERR_COMPILED;
|
||||||
|
compiler->executable_offset = executable_offset;
|
||||||
compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
|
compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
|
||||||
SLJIT_CACHE_FLUSH(code, code_ptr);
|
|
||||||
|
code = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
|
||||||
|
|
||||||
#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
|
#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
|
||||||
#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
|
#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
|
||||||
if (((sljit_sw)code_ptr) & 0x4)
|
if (((sljit_sw)code_ptr) & 0x4)
|
||||||
code_ptr++;
|
code_ptr++;
|
||||||
sljit_set_function_context(NULL, (struct sljit_function_context*)code_ptr, (sljit_sw)code, (void*)sljit_generate_code);
|
|
||||||
return code_ptr;
|
|
||||||
#else
|
|
||||||
sljit_set_function_context(NULL, (struct sljit_function_context*)code_ptr, (sljit_sw)code, (void*)sljit_generate_code);
|
|
||||||
return code_ptr;
|
|
||||||
#endif
|
#endif
|
||||||
|
sljit_set_function_context(NULL, (struct sljit_function_context*)code_ptr, (sljit_sw)code, (void*)sljit_generate_code);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
|
||||||
|
|
||||||
|
SLJIT_CACHE_FLUSH(code, code_ptr);
|
||||||
|
|
||||||
|
#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
|
||||||
|
return code_ptr;
|
||||||
#else
|
#else
|
||||||
return code;
|
return code;
|
||||||
#endif
|
#endif
|
||||||
|
@ -2138,7 +2152,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
|
||||||
sljit_ins bo_bi_flags;
|
sljit_ins bo_bi_flags;
|
||||||
|
|
||||||
CHECK_ERROR_PTR();
|
CHECK_ERROR_PTR();
|
||||||
CHECK_DYN_CODE_MOD(type & SLJIT_REWRITABLE_JUMP);
|
|
||||||
CHECK_PTR(check_sljit_emit_jump(compiler, type));
|
CHECK_PTR(check_sljit_emit_jump(compiler, type));
|
||||||
|
|
||||||
bo_bi_flags = get_bo_bi_flags(type & 0xff);
|
bo_bi_flags = get_bo_bi_flags(type & 0xff);
|
||||||
|
@ -2363,7 +2376,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
|
||||||
sljit_s32 reg;
|
sljit_s32 reg;
|
||||||
|
|
||||||
CHECK_ERROR_PTR();
|
CHECK_ERROR_PTR();
|
||||||
CHECK_DYN_CODE_MOD(1);
|
|
||||||
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
||||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||||
|
|
||||||
|
|
|
@ -145,20 +145,22 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_
|
||||||
return push_inst(compiler, OR | D(dst) | S1(dst) | IMM_ARG | (init_value & 0x3ff), DR(dst));
|
return push_inst(compiler, OR | D(dst) | S1(dst) | IMM_ARG | (init_value & 0x3ff), DR(dst));
|
||||||
}
|
}
|
||||||
|
|
||||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
|
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
|
||||||
{
|
{
|
||||||
sljit_ins *inst = (sljit_ins *)addr;
|
sljit_ins *inst = (sljit_ins *)addr;
|
||||||
|
|
||||||
inst[0] = (inst[0] & 0xffc00000) | ((new_addr >> 10) & 0x3fffff);
|
inst[0] = (inst[0] & 0xffc00000) | ((new_target >> 10) & 0x3fffff);
|
||||||
inst[1] = (inst[1] & 0xfffffc00) | (new_addr & 0x3ff);
|
inst[1] = (inst[1] & 0xfffffc00) | (new_target & 0x3ff);
|
||||||
|
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||||
SLJIT_CACHE_FLUSH(inst, inst + 2);
|
SLJIT_CACHE_FLUSH(inst, inst + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
|
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
|
||||||
{
|
{
|
||||||
sljit_ins *inst = (sljit_ins *)addr;
|
sljit_ins *inst = (sljit_ins *)addr;
|
||||||
|
|
||||||
inst[0] = (inst[0] & 0xffc00000) | ((new_constant >> 10) & 0x3fffff);
|
inst[0] = (inst[0] & 0xffc00000) | ((new_constant >> 10) & 0x3fffff);
|
||||||
inst[1] = (inst[1] & 0xfffffc00) | (new_constant & 0x3ff);
|
inst[1] = (inst[1] & 0xfffffc00) | (new_constant & 0x3ff);
|
||||||
|
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||||
SLJIT_CACHE_FLUSH(inst, inst + 2);
|
SLJIT_CACHE_FLUSH(inst, inst + 2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -199,7 +199,7 @@ static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit
|
||||||
return SLJIT_SUCCESS;
|
return SLJIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code)
|
static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)
|
||||||
{
|
{
|
||||||
sljit_sw diff;
|
sljit_sw diff;
|
||||||
sljit_uw target_addr;
|
sljit_uw target_addr;
|
||||||
|
@ -213,7 +213,7 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i
|
||||||
target_addr = jump->u.target;
|
target_addr = jump->u.target;
|
||||||
else {
|
else {
|
||||||
SLJIT_ASSERT(jump->flags & JUMP_LABEL);
|
SLJIT_ASSERT(jump->flags & JUMP_LABEL);
|
||||||
target_addr = (sljit_uw)(code + jump->u.label->size);
|
target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset;
|
||||||
}
|
}
|
||||||
inst = (sljit_ins*)jump->addr;
|
inst = (sljit_ins*)jump->addr;
|
||||||
|
|
||||||
|
@ -239,8 +239,9 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i
|
||||||
if (jump->flags & IS_COND)
|
if (jump->flags & IS_COND)
|
||||||
inst--;
|
inst--;
|
||||||
|
|
||||||
|
diff = ((sljit_sw)target_addr - (sljit_sw)(inst - 1) - executable_offset) >> 2;
|
||||||
|
|
||||||
if (jump->flags & IS_MOVABLE) {
|
if (jump->flags & IS_MOVABLE) {
|
||||||
diff = ((sljit_sw)target_addr - (sljit_sw)(inst - 1)) >> 2;
|
|
||||||
if (diff <= MAX_DISP && diff >= MIN_DISP) {
|
if (diff <= MAX_DISP && diff >= MIN_DISP) {
|
||||||
jump->flags |= PATCH_B;
|
jump->flags |= PATCH_B;
|
||||||
inst--;
|
inst--;
|
||||||
|
@ -257,7 +258,8 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
diff = ((sljit_sw)target_addr - (sljit_sw)(inst)) >> 2;
|
diff += sizeof(sljit_ins);
|
||||||
|
|
||||||
if (diff <= MAX_DISP && diff >= MIN_DISP) {
|
if (diff <= MAX_DISP && diff >= MIN_DISP) {
|
||||||
jump->flags |= PATCH_B;
|
jump->flags |= PATCH_B;
|
||||||
if (jump->flags & IS_COND)
|
if (jump->flags & IS_COND)
|
||||||
|
@ -280,6 +282,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
sljit_ins *buf_ptr;
|
sljit_ins *buf_ptr;
|
||||||
sljit_ins *buf_end;
|
sljit_ins *buf_end;
|
||||||
sljit_uw word_count;
|
sljit_uw word_count;
|
||||||
|
sljit_sw executable_offset;
|
||||||
sljit_uw addr;
|
sljit_uw addr;
|
||||||
|
|
||||||
struct sljit_label *label;
|
struct sljit_label *label;
|
||||||
|
@ -296,9 +299,12 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
|
|
||||||
code_ptr = code;
|
code_ptr = code;
|
||||||
word_count = 0;
|
word_count = 0;
|
||||||
|
executable_offset = SLJIT_EXEC_OFFSET(code);
|
||||||
|
|
||||||
label = compiler->labels;
|
label = compiler->labels;
|
||||||
jump = compiler->jumps;
|
jump = compiler->jumps;
|
||||||
const_ = compiler->consts;
|
const_ = compiler->consts;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
buf_ptr = (sljit_ins*)buf->memory;
|
buf_ptr = (sljit_ins*)buf->memory;
|
||||||
buf_end = buf_ptr + (buf->used_size >> 2);
|
buf_end = buf_ptr + (buf->used_size >> 2);
|
||||||
|
@ -310,7 +316,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
/* These structures are ordered by their address. */
|
/* These structures are ordered by their address. */
|
||||||
if (label && label->size == word_count) {
|
if (label && label->size == word_count) {
|
||||||
/* Just recording the address. */
|
/* Just recording the address. */
|
||||||
label->addr = (sljit_uw)code_ptr;
|
label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
|
||||||
label->size = code_ptr - code;
|
label->size = code_ptr - code;
|
||||||
label = label->next;
|
label = label->next;
|
||||||
}
|
}
|
||||||
|
@ -320,7 +326,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
#else
|
#else
|
||||||
jump->addr = (sljit_uw)(code_ptr - 6);
|
jump->addr = (sljit_uw)(code_ptr - 6);
|
||||||
#endif
|
#endif
|
||||||
code_ptr = detect_jump_type(jump, code_ptr, code);
|
code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset);
|
||||||
jump = jump->next;
|
jump = jump->next;
|
||||||
}
|
}
|
||||||
if (const_ && const_->addr == word_count) {
|
if (const_ && const_->addr == word_count) {
|
||||||
|
@ -336,7 +342,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
} while (buf);
|
} while (buf);
|
||||||
|
|
||||||
if (label && label->size == word_count) {
|
if (label && label->size == word_count) {
|
||||||
label->addr = (sljit_uw)code_ptr;
|
label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
|
||||||
label->size = code_ptr - code;
|
label->size = code_ptr - code;
|
||||||
label = label->next;
|
label = label->next;
|
||||||
}
|
}
|
||||||
|
@ -353,13 +359,13 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
buf_ptr = (sljit_ins *)jump->addr;
|
buf_ptr = (sljit_ins *)jump->addr;
|
||||||
|
|
||||||
if (jump->flags & PATCH_CALL) {
|
if (jump->flags & PATCH_CALL) {
|
||||||
addr = (sljit_sw)(addr - jump->addr) >> 2;
|
addr = (sljit_sw)(addr - (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) >> 2;
|
||||||
SLJIT_ASSERT((sljit_sw)addr <= 0x1fffffff && (sljit_sw)addr >= -0x20000000);
|
SLJIT_ASSERT((sljit_sw)addr <= 0x1fffffff && (sljit_sw)addr >= -0x20000000);
|
||||||
buf_ptr[0] = CALL | (addr & 0x3fffffff);
|
buf_ptr[0] = CALL | (addr & 0x3fffffff);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (jump->flags & PATCH_B) {
|
if (jump->flags & PATCH_B) {
|
||||||
addr = (sljit_sw)(addr - jump->addr) >> 2;
|
addr = (sljit_sw)(addr - (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) >> 2;
|
||||||
SLJIT_ASSERT((sljit_sw)addr <= MAX_DISP && (sljit_sw)addr >= MIN_DISP);
|
SLJIT_ASSERT((sljit_sw)addr <= MAX_DISP && (sljit_sw)addr >= MIN_DISP);
|
||||||
buf_ptr[0] = (buf_ptr[0] & ~DISP_MASK) | (addr & DISP_MASK);
|
buf_ptr[0] = (buf_ptr[0] & ~DISP_MASK) | (addr & DISP_MASK);
|
||||||
break;
|
break;
|
||||||
|
@ -378,7 +384,12 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
|
|
||||||
|
|
||||||
compiler->error = SLJIT_ERR_COMPILED;
|
compiler->error = SLJIT_ERR_COMPILED;
|
||||||
|
compiler->executable_offset = executable_offset;
|
||||||
compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
|
compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
|
||||||
|
|
||||||
|
code = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
|
||||||
|
code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
|
||||||
|
|
||||||
SLJIT_CACHE_FLUSH(code, code_ptr);
|
SLJIT_CACHE_FLUSH(code, code_ptr);
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -1295,7 +1306,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
|
||||||
struct sljit_jump *jump;
|
struct sljit_jump *jump;
|
||||||
|
|
||||||
CHECK_ERROR_PTR();
|
CHECK_ERROR_PTR();
|
||||||
CHECK_DYN_CODE_MOD(type & SLJIT_REWRITABLE_JUMP);
|
|
||||||
CHECK_PTR(check_sljit_emit_jump(compiler, type));
|
CHECK_PTR(check_sljit_emit_jump(compiler, type));
|
||||||
|
|
||||||
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
||||||
|
@ -1423,7 +1433,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
|
||||||
struct sljit_const *const_;
|
struct sljit_const *const_;
|
||||||
|
|
||||||
CHECK_ERROR_PTR();
|
CHECK_ERROR_PTR();
|
||||||
CHECK_DYN_CODE_MOD(1);
|
|
||||||
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
||||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||||
|
|
||||||
|
|
|
@ -2412,7 +2412,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump * sljit_emit_jump(struct sljit_compil
|
||||||
flush_buffer(compiler);
|
flush_buffer(compiler);
|
||||||
|
|
||||||
CHECK_ERROR_PTR();
|
CHECK_ERROR_PTR();
|
||||||
CHECK_DYN_CODE_MOD(type & SLJIT_REWRITABLE_JUMP);
|
|
||||||
CHECK_PTR(check_sljit_emit_jump(compiler, type));
|
CHECK_PTR(check_sljit_emit_jump(compiler, type));
|
||||||
|
|
||||||
jump = (struct sljit_jump *)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
jump = (struct sljit_jump *)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
||||||
|
@ -2511,7 +2510,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const * sljit_emit_const(struct sljit_comp
|
||||||
flush_buffer(compiler);
|
flush_buffer(compiler);
|
||||||
|
|
||||||
CHECK_ERROR_PTR();
|
CHECK_ERROR_PTR();
|
||||||
CHECK_DYN_CODE_MOD(1);
|
|
||||||
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
||||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||||
|
|
||||||
|
@ -2528,13 +2526,13 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const * sljit_emit_const(struct sljit_comp
|
||||||
return const_;
|
return const_;
|
||||||
}
|
}
|
||||||
|
|
||||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
|
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target)
|
||||||
{
|
{
|
||||||
sljit_ins *inst = (sljit_ins *)addr;
|
sljit_ins *inst = (sljit_ins *)addr;
|
||||||
|
|
||||||
inst[0] = (inst[0] & ~(0xFFFFL << 43)) | (((new_addr >> 32) & 0xffff) << 43);
|
inst[0] = (inst[0] & ~(0xFFFFL << 43)) | (((new_target >> 32) & 0xffff) << 43);
|
||||||
inst[1] = (inst[1] & ~(0xFFFFL << 43)) | (((new_addr >> 16) & 0xffff) << 43);
|
inst[1] = (inst[1] & ~(0xFFFFL << 43)) | (((new_target >> 16) & 0xffff) << 43);
|
||||||
inst[2] = (inst[2] & ~(0xFFFFL << 43)) | ((new_addr & 0xffff) << 43);
|
inst[2] = (inst[2] & ~(0xFFFFL << 43)) | ((new_target & 0xffff) << 43);
|
||||||
SLJIT_CACHE_FLUSH(inst, inst + 3);
|
SLJIT_CACHE_FLUSH(inst, inst + 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ static sljit_s32 emit_do_imm(struct sljit_compiler *compiler, sljit_u8 opcode, s
|
||||||
return SLJIT_SUCCESS;
|
return SLJIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type)
|
static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type, sljit_sw executable_offset)
|
||||||
{
|
{
|
||||||
if (type == SLJIT_JUMP) {
|
if (type == SLJIT_JUMP) {
|
||||||
*code_ptr++ = JMP_i32;
|
*code_ptr++ = JMP_i32;
|
||||||
|
@ -57,7 +57,7 @@ static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_
|
||||||
if (jump->flags & JUMP_LABEL)
|
if (jump->flags & JUMP_LABEL)
|
||||||
jump->flags |= PATCH_MW;
|
jump->flags |= PATCH_MW;
|
||||||
else
|
else
|
||||||
sljit_unaligned_store_sw(code_ptr, jump->u.target - (jump->addr + 4));
|
sljit_unaligned_store_sw(code_ptr, jump->u.target - (jump->addr + 4) - (sljit_uw)executable_offset);
|
||||||
code_ptr += 4;
|
code_ptr += 4;
|
||||||
|
|
||||||
return code_ptr;
|
return code_ptr;
|
||||||
|
|
|
@ -409,7 +409,11 @@ static sljit_u8 get_jump_code(sljit_s32 type)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||||
|
static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type, sljit_sw executable_offset);
|
||||||
|
#else
|
||||||
static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type);
|
static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type);
|
||||||
|
#endif
|
||||||
|
|
||||||
static sljit_u8* generate_near_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_u8 *code, sljit_s32 type, sljit_sw executable_offset)
|
static sljit_u8* generate_near_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_u8 *code, sljit_s32 type, sljit_sw executable_offset)
|
||||||
{
|
{
|
||||||
|
@ -511,8 +515,13 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
jump->addr = (sljit_uw)code_ptr;
|
jump->addr = (sljit_uw)code_ptr;
|
||||||
if (!(jump->flags & SLJIT_REWRITABLE_JUMP))
|
if (!(jump->flags & SLJIT_REWRITABLE_JUMP))
|
||||||
code_ptr = generate_near_jump_code(jump, code_ptr, code, *buf_ptr - 2, executable_offset);
|
code_ptr = generate_near_jump_code(jump, code_ptr, code, *buf_ptr - 2, executable_offset);
|
||||||
else
|
else {
|
||||||
|
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||||
|
code_ptr = generate_far_jump_code(jump, code_ptr, *buf_ptr - 2, executable_offset);
|
||||||
|
#else
|
||||||
code_ptr = generate_far_jump_code(jump, code_ptr, *buf_ptr - 2);
|
code_ptr = generate_far_jump_code(jump, code_ptr, *buf_ptr - 2);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
jump = jump->next;
|
jump = jump->next;
|
||||||
}
|
}
|
||||||
else if (*buf_ptr == 0) {
|
else if (*buf_ptr == 0) {
|
||||||
|
@ -521,7 +530,6 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
label = label->next;
|
label = label->next;
|
||||||
}
|
}
|
||||||
else { /* *buf_ptr is 1 */
|
else { /* *buf_ptr is 1 */
|
||||||
SLJIT_ASSERT(sljit_is_dyn_code_modification_enabled());
|
|
||||||
const_->addr = ((sljit_uw)code_ptr) - sizeof(sljit_sw);
|
const_->addr = ((sljit_uw)code_ptr) - sizeof(sljit_sw);
|
||||||
const_ = const_->next;
|
const_ = const_->next;
|
||||||
}
|
}
|
||||||
|
@ -572,6 +580,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
/* Some space may be wasted because of short jumps. */
|
/* Some space may be wasted because of short jumps. */
|
||||||
SLJIT_ASSERT(code_ptr <= code + compiler->size);
|
SLJIT_ASSERT(code_ptr <= code + compiler->size);
|
||||||
compiler->error = SLJIT_ERR_COMPILED;
|
compiler->error = SLJIT_ERR_COMPILED;
|
||||||
|
compiler->executable_offset = executable_offset;
|
||||||
compiler->executable_size = code_ptr - code;
|
compiler->executable_size = code_ptr - code;
|
||||||
return (void*)(code + executable_offset);
|
return (void*)(code + executable_offset);
|
||||||
}
|
}
|
||||||
|
@ -2572,7 +2581,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
|
||||||
struct sljit_jump *jump;
|
struct sljit_jump *jump;
|
||||||
|
|
||||||
CHECK_ERROR_PTR();
|
CHECK_ERROR_PTR();
|
||||||
CHECK_DYN_CODE_MOD(type & SLJIT_REWRITABLE_JUMP);
|
|
||||||
CHECK_PTR(check_sljit_emit_jump(compiler, type));
|
CHECK_PTR(check_sljit_emit_jump(compiler, type));
|
||||||
|
|
||||||
if (SLJIT_UNLIKELY(compiler->flags_saved)) {
|
if (SLJIT_UNLIKELY(compiler->flags_saved)) {
|
||||||
|
@ -2901,7 +2909,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CHECK_ERROR_PTR();
|
CHECK_ERROR_PTR();
|
||||||
CHECK_DYN_CODE_MOD(1);
|
|
||||||
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
||||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||||
|
|
||||||
|
@ -2940,17 +2947,19 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
|
||||||
return const_;
|
return const_;
|
||||||
}
|
}
|
||||||
|
|
||||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
|
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
|
||||||
{
|
{
|
||||||
|
SLJIT_UNUSED_ARG(executable_offset);
|
||||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||||
sljit_unaligned_store_sw((void*)addr, new_addr - (addr + 4));
|
sljit_unaligned_store_sw((void*)addr, new_target - (addr + 4) - (sljit_uw)executable_offset);
|
||||||
#else
|
#else
|
||||||
sljit_unaligned_store_sw((void*)addr, (sljit_sw) new_addr);
|
sljit_unaligned_store_sw((void*)addr, (sljit_sw) new_target);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
|
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
|
||||||
{
|
{
|
||||||
|
SLJIT_UNUSED_ARG(executable_offset);
|
||||||
sljit_unaligned_store_sw((void*)addr, new_constant);
|
sljit_unaligned_store_sw((void*)addr, new_constant);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue