diff options
Diffstat (limited to 'libguile/lightening/lightening/arm-cpu.c')
-rw-r--r-- | libguile/lightening/lightening/arm-cpu.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/libguile/lightening/lightening/arm-cpu.c b/libguile/lightening/lightening/arm-cpu.c index 5ce5f06fd..491b34ebe 100644 --- a/libguile/lightening/lightening/arm-cpu.c +++ b/libguile/lightening/lightening/arm-cpu.c @@ -2922,6 +2922,24 @@ retval_i(jit_state_t *_jit, int32_t r0) movr(_jit, r0, jit_gpr_regno(_R0)); } +static uint32_t* +jmp_without_veneer(jit_state_t *_jit) +{ + uint32_t *loc = _jit->pc.ui; + emit_u16(_jit, 0); + emit_u16(_jit, 0); + return loc; +} + +static void +patch_jmp_without_veneer(jit_state_t *_jit, uint32_t *loc) +{ + uint8_t *pc_base = ((uint8_t *)loc) + 4; + uint8_t rsh = 1; + int32_t off = (_jit->pc.uc - pc_base) >> rsh; + write_wide_thumb(loc, THUMB2_B | encode_thumb_jump(off)); +} + struct veneer { uint16_t ldr; @@ -2940,11 +2958,11 @@ static void emit_veneer(jit_state_t *_jit, jit_pointer_t target) { uint16_t thumb1_ldr = 0x4800; - int32_t tmp = jit_gpr_regno(get_temp_gpr(_jit)); + int32_t tmp = jit_gpr_regno(JIT_TMP1); + int32_t rd = jit_gpr_regno(_PC); ASSERT(tmp < 8); // Loaded addr is 4 bytes after the LDR, which is aligned, so offset is 0. emit_u16(_jit, thumb1_ldr | (tmp << 8)); - T1_MOV(_jit, jit_gpr_regno(_PC), tmp); - unget_temp_gpr(_jit); + emit_u16(_jit, THUMB_MOV|((_u4(rd)&8)<<4)|(_u4(tmp)<<3)|(rd&7)); emit_u32(_jit, (uint32_t) target); } |