diff --git a/jit/jit.c b/jit/jit.c index 17115bf85..586b9b1fe 100644 --- a/jit/jit.c +++ b/jit/jit.c @@ -300,7 +300,7 @@ static inline void emit_u64(jit_state_t *_jit, uint64_t u64) { static inline jit_reloc_t jit_reloc (jit_state_t *_jit, enum jit_reloc_kind kind, - uint8_t inst_start_offset, uint16_t flags, intptr_t addend) + uint8_t inst_start_offset, uint16_t flags) { jit_reloc_t ret; @@ -313,24 +313,21 @@ jit_reloc (jit_state_t *_jit, enum jit_reloc_kind kind, { case JIT_RELOC_ABSOLUTE: if (sizeof(intptr_t) == 4) - emit_u32 (_jit, addend); + emit_u32 (_jit, 0); else - emit_u64 (_jit, addend); + emit_u64 (_jit, 0); break; case JIT_RELOC_REL8: - ASSERT (INT8_MIN <= addend && addend <= INT8_MAX); - emit_u8 (_jit, addend - 1); + emit_u8 (_jit, 0); break; case JIT_RELOC_REL16: - ASSERT (INT16_MIN <= addend && addend <= INT16_MAX); - emit_u16 (_jit, addend - 2); + emit_u16 (_jit, 0); break; case JIT_RELOC_REL32: - ASSERT (INT32_MIN <= addend && addend <= INT32_MAX); - emit_u32 (_jit, addend - 4); + emit_u32 (_jit, 0); break; case JIT_RELOC_REL64: - emit_u64 (_jit, addend - 8); + emit_u64 (_jit, 0); break; default: abort (); @@ -352,40 +349,41 @@ jit_patch_there(jit_state_t* _jit, jit_reloc_t reloc, jit_pointer_t addr) return; union jit_pc loc; loc.uc = _jit->start + reloc.offset; - ptrdiff_t diff = addr - ((void*) 0); + ptrdiff_t diff; switch (reloc.kind) { case JIT_RELOC_ABSOLUTE: if (sizeof(diff) == 4) - *loc.ui = diff + (int32_t)*loc.ui; + *loc.ui = (uintptr_t)addr; else - *loc.ul = diff + (int64_t)*loc.ul; + *loc.ul = (uintptr_t)addr; if (loc.uc + sizeof(diff) == _jit->pc.uc && (reloc.flags & JIT_RELOC_CAN_SHORTEN)) jit_try_shorten (_jit, reloc); break; case JIT_RELOC_REL8: - diff += (int8_t)*loc.uc; + diff = ((uint8_t*)addr) - (loc.uc + 1); ASSERT (INT8_MIN <= diff && diff <= INT8_MAX); *loc.uc = diff; break; case JIT_RELOC_REL16: - diff += (int16_t)*loc.us; + diff = ((uint8_t*)addr) - (loc.uc + 2); ASSERT (INT16_MIN <= diff && diff <= INT16_MAX); *loc.us = diff; if ((loc.uc + 1) == _jit->pc.uc && (reloc.flags & JIT_RELOC_CAN_SHORTEN)) jit_try_shorten (_jit, reloc); break; case JIT_RELOC_REL32: - diff += (int32_t)*loc.ui; + diff = ((uint8_t*)addr) - (loc.uc + 4); ASSERT (INT32_MIN <= diff && diff <= INT32_MAX); *loc.ui = diff; if ((loc.ui + 1) == _jit->pc.ui && (reloc.flags & JIT_RELOC_CAN_SHORTEN)) jit_try_shorten (_jit, reloc); break; case JIT_RELOC_REL64: - *loc.ul = diff + (int64_t)*loc.ul; + diff = ((uint8_t*)addr) - (loc.uc + 8); + *loc.ul = diff; if ((loc.ul + 1) == _jit->pc.ul && (reloc.flags & JIT_RELOC_CAN_SHORTEN)) jit_try_shorten (_jit, reloc); break; diff --git a/jit/x86-cpu.c b/jit/x86-cpu.c index 0bc73b297..7d5a1b79a 100644 --- a/jit/x86-cpu.c +++ b/jit/x86-cpu.c @@ -401,7 +401,7 @@ mov_addr(jit_state_t *_jit, int32_t r0) rex(_jit, 0, WIDE, _NOREG, _NOREG, r0); ic(_jit, 0xb8 | r7(r0)); ptrdiff_t inst_start = _jit->pc.uc - pc_start; - return jit_reloc(_jit, JIT_RELOC_ABSOLUTE, inst_start, 0, 0); + return jit_reloc(_jit, JIT_RELOC_ABSOLUTE, inst_start, 0); } static void @@ -2253,7 +2253,7 @@ static jit_reloc_t jccs(jit_state_t *_jit, int32_t code) { ic(_jit, 0x70 | code); - return jit_reloc(_jit, JIT_RELOC_REL8, 1, 0, -_jit->pc.w); + return jit_reloc(_jit, JIT_RELOC_REL8, 1, 0); } static jit_reloc_t @@ -2261,7 +2261,7 @@ jcc(jit_state_t *_jit, int32_t code) { ic(_jit, 0x0f); ic(_jit, 0x80 | code); - return jit_reloc(_jit, JIT_RELOC_REL32, 2, 0, -_jit->pc.w); + return jit_reloc(_jit, JIT_RELOC_REL32, 2, 0); } #define DEFINE_JUMPS(cc, CC, code) \ @@ -2673,14 +2673,14 @@ static jit_reloc_t jmp(jit_state_t *_jit) { ic(_jit, 0xe9); - return jit_reloc(_jit, JIT_RELOC_REL32, 1, 0, -_jit->pc.w); + return jit_reloc(_jit, JIT_RELOC_REL32, 1, 0); } static jit_reloc_t jmpsi(jit_state_t *_jit) { ic(_jit, 0xeb); - return jit_reloc(_jit, JIT_RELOC_REL8, 1, 0, -_jit->pc.w); + return jit_reloc(_jit, JIT_RELOC_REL8, 1, 0); } static void diff --git a/tests/bltr.c b/tests/bltr.c new file mode 100644 index 000000000..56b0d68ee --- /dev/null +++ b/tests/bltr.c @@ -0,0 +1,33 @@ +#include "test.h" + +static void +run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size) +{ + jit_begin(j, arena_base, arena_size); + + const jit_arg_abi_t abi[] = { JIT_ARG_ABI_INTMAX, JIT_ARG_ABI_INTMAX }; + jit_arg_t args[2]; + const jit_anyreg_t regs[] = { { .gpr=JIT_R0 }, { .gpr=JIT_R1 } }; + + jit_receive(j, 2, abi, args); + jit_load_args(j, 2, abi, args, regs); + + jit_reloc_t r = jit_bltr(j, JIT_R0, JIT_R1); + jit_reti(j, 0); + jit_patch_here(j, r); + jit_reti(j, 1); + + intmax_t (*f)(intmax_t, intmax_t) = jit_end(j, NULL); + + ASSERT(f(0, 0) == 0); + ASSERT(f(0, 1) == 1); + ASSERT(f(1, 0) == 0); + ASSERT(f(-1, 0) == 1); + ASSERT(f(0, -1) == 0); +} + +int +main (int argc, char *argv[]) +{ + return main_helper(argc, argv, run_test); +}