1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-14 01:30:19 +02:00

Add bltr test

Also rework how relocs are represented.
This commit is contained in:
Andy Wingo 2019-03-26 14:21:00 +01:00
parent 9adbed9e7a
commit 52a9ab856d
3 changed files with 53 additions and 22 deletions

View file

@ -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;

View file

@ -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

33
tests/bltr.c Normal file
View file

@ -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);
}