summaryrefslogtreecommitdiff
path: root/libguile/lightening/lightening/arm-cpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'libguile/lightening/lightening/arm-cpu.c')
-rw-r--r--libguile/lightening/lightening/arm-cpu.c24
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);
}