diff options
author | Andy Wingo <wingo@pobox.com> | 2019-05-21 15:30:56 +0200 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2019-05-21 15:30:56 +0200 |
commit | 7bc95fde985bf9b27211379f846273c2b6cc08c3 (patch) | |
tree | 7098f799dfc7dc45e50c19c57a6e89606f7b8160 /libguile/lightening | |
parent | 12e0063022c5e7a1eadbf211b60ac0d88260f915 (diff) | |
parent | b7f367165f6d29cf0eca221a9e1159a9105d9418 (diff) | |
download | guile-7bc95fde985bf9b27211379f846273c2b6cc08c3.tar.gz |
Merge remote-tracking branch 'lightening/master'
Diffstat (limited to 'libguile/lightening')
-rw-r--r-- | libguile/lightening/lightening/aarch64-cpu.c | 34 | ||||
-rw-r--r-- | libguile/lightening/lightening/arm-cpu.c | 24 | ||||
-rw-r--r-- | libguile/lightening/lightening/lightening.c | 40 |
3 files changed, 68 insertions, 30 deletions
diff --git a/libguile/lightening/lightening/aarch64-cpu.c b/libguile/lightening/lightening/aarch64-cpu.c index c04b4cfb1..839e55c1a 100644 --- a/libguile/lightening/lightening/aarch64-cpu.c +++ b/libguile/lightening/lightening/aarch64-cpu.c @@ -84,7 +84,7 @@ oxx9(jit_state_t *_jit, int32_t Op, int32_t Rd, int32_t Rn, int32_t Simm9) } static uint32_t -encode_ox19(jit_state_t *_jit, int32_t Op, int32_t Rd) +encode_ox19(int32_t Op, int32_t Rd) { uint32_t inst = Op; inst = write_Rd_bitfield(inst, Rd); @@ -92,7 +92,7 @@ encode_ox19(jit_state_t *_jit, int32_t Op, int32_t Rd) } static uint32_t -encode_oc19(jit_state_t *_jit, int32_t Op, int32_t Cc) +encode_oc19(int32_t Op, int32_t Cc) { uint32_t inst = Op; inst = write_cond2_bitfield(inst, Cc); @@ -100,7 +100,7 @@ encode_oc19(jit_state_t *_jit, int32_t Op, int32_t Cc) } static uint32_t -encode_o26(jit_state_t *_jit, int32_t Op) +encode_o26(int32_t Op) { uint32_t inst = Op; return inst; @@ -933,13 +933,13 @@ LDP_POS(jit_state_t *_jit, int32_t Rt, int32_t Rt2, int32_t Rn, int32_t Simm7) static jit_reloc_t B(jit_state_t *_jit) { - return emit_jmp(_jit, encode_o26(_jit, A64_B)); + return emit_jmp(_jit, encode_o26(A64_B)); } static jit_reloc_t BL(jit_state_t *_jit) { - return emit_jmp(_jit, encode_o26(_jit, A64_BL)); + return emit_jmp(_jit, encode_o26(A64_BL)); } static void @@ -963,19 +963,19 @@ RET(jit_state_t *_jit) static jit_reloc_t B_C(jit_state_t *_jit, int32_t Cc) { - return emit_jcc(_jit, encode_oc19(_jit, A64_B_C, Cc)); + return emit_jcc(_jit, encode_oc19(A64_B_C, Cc)); } static jit_reloc_t CBZ(jit_state_t *_jit, int32_t Rd) { - return emit_jcc(_jit, encode_ox19(_jit, A64_CBZ|XS,Rd)); + return emit_jcc(_jit, encode_ox19(A64_CBZ|XS,Rd)); } static jit_reloc_t CBNZ(jit_state_t *_jit, int32_t Rd) { - return emit_jcc(_jit, encode_ox19(_jit, A64_CBNZ|XS,Rd)); + return emit_jcc(_jit, encode_ox19(A64_CBNZ|XS,Rd)); } static void @@ -987,14 +987,14 @@ NOP(jit_state_t *_jit) static jit_reloc_t movi_from_pool(jit_state_t *_jit, int32_t Rt) { - return emit_load_from_pool(_jit, encode_ox19(_jit, A64_LDRI_LITERAL, Rt)); + return emit_load_from_pool(_jit, encode_ox19(A64_LDRI_LITERAL, Rt)); } static void emit_veneer(jit_state_t *_jit, jit_pointer_t target) { jit_gpr_t tmp = get_temp_gpr(_jit); - uint32_t inst = encode_ox19(_jit, A64_LDRI_LITERAL, jit_gpr_regno(tmp)); + uint32_t inst = encode_ox19(A64_LDRI_LITERAL, jit_gpr_regno(tmp)); uint32_t *loc = _jit->pc.ui; emit_u32(_jit, inst); BR(_jit, jit_gpr_regno(tmp)); @@ -2536,3 +2536,17 @@ retval_l(jit_state_t *_jit, int32_t r0) { movr(_jit, r0, jit_gpr_regno(_X0)); } + +static uint32_t* +jmp_without_veneer(jit_state_t *_jit) +{ + uint32_t *loc = _jit->pc.ui; + emit_u32(_jit, encode_o26(_jit, A64_B)); + return loc; +} + +static void +patch_jmp_without_veneer(jit_state_t *_jit, uint32_t *loc) +{ + patch_jmp_offset(loc, _jit->pc.ui - loc); +} 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); } diff --git a/libguile/lightening/lightening/lightening.c b/libguile/lightening/lightening/lightening.c index 9d0d8f29f..5050a35b0 100644 --- a/libguile/lightening/lightening/lightening.c +++ b/libguile/lightening/lightening/lightening.c @@ -95,7 +95,8 @@ struct abi_arg_iterator; #ifdef JIT_NEEDS_LITERAL_POOL static struct jit_literal_pool* alloc_literal_pool(jit_state_t *_jit, size_t capacity); -static void clear_literal_pool(struct jit_literal_pool *pool); +static void reset_literal_pool(jit_state_t *_jit, + struct jit_literal_pool *pool); static void grow_literal_pool(jit_state_t *_jit); static void add_literal_pool_entry(jit_state_t *_jit, struct jit_literal_pool_entry entry, @@ -185,6 +186,9 @@ jit_begin(jit_state_t *_jit, uint8_t* buf, size_t length) _jit->limit = buf + length; _jit->overflow = 0; _jit->frame_size = 0; +#if JIT_NEEDS_LITERAL_POOL + _jit->pool->deadline = length; +#endif } jit_bool_t @@ -202,7 +206,7 @@ jit_reset(jit_state_t *_jit) _jit->overflow = 0; _jit->frame_size = 0; #ifdef JIT_NEEDS_LITERAL_POOL - clear_literal_pool(_jit->pool); + reset_literal_pool(_jit, _jit->pool); #endif } @@ -240,7 +244,7 @@ jit_end(jit_state_t *_jit, size_t *length) _jit->overflow = 0; _jit->frame_size = 0; #ifdef JIT_NEEDS_LITERAL_POOL - clear_literal_pool(_jit->pool); + reset_literal_pool(_jit, _jit->pool); #endif return jit_address_to_function_pointer(start); @@ -1226,9 +1230,10 @@ jit_load_args(jit_state_t *_jit, size_t argc, jit_operand_t args[]) #ifdef JIT_NEEDS_LITERAL_POOL static void -clear_literal_pool(struct jit_literal_pool *pool) +reset_literal_pool(jit_state_t *_jit, + struct jit_literal_pool *pool) { - pool->deadline = -1; + pool->deadline = _jit->limit - _jit->start; pool->size = 0; pool->byte_size = 0; memset(pool->entries, 0, sizeof(pool->entries[0]) * pool->size); @@ -1245,7 +1250,7 @@ alloc_literal_pool(jit_state_t *_jit, size_t capacity) sizeof (struct jit_literal_pool_entry) * capacity); ASSERT (ret); ret->capacity = capacity; - clear_literal_pool(ret); + reset_literal_pool(_jit, ret); return ret; } @@ -1270,14 +1275,12 @@ add_literal_pool_entry(jit_state_t *_jit, struct jit_literal_pool_entry entry, if (_jit->pool->size == _jit->pool->capacity) grow_literal_pool (_jit); - max_offset <<= entry.reloc.rsh; - ptrdiff_t deadline = + uint32_t deadline = _jit->pc.uc - _jit->start + max_offset - _jit->pool->byte_size; - if (_jit->pool->size == 0) - // Assume that we might need a uint32_t for alignment, and another - // to branch over the table. - _jit->pool->deadline = deadline - 2 * sizeof(uint32_t); - else if (deadline < _jit->pool->deadline) + // Assume that we might need a uint32_t for alignment, and another + // to branch over the table. + deadline -= 2 * sizeof(uint32_t); + if (deadline < _jit->pool->deadline) _jit->pool->deadline = deadline; // Assume that each entry takes a max of 16 bytes. @@ -1325,14 +1328,17 @@ patch_pending_literal(jit_state_t *_jit, jit_reloc_t src, uint64_t value) static void emit_literal_pool(jit_state_t *_jit, enum guard_pool guard) { + if (_jit->overflow) + return; + _jit->pool->deadline = -1; if (!_jit->pool->size) return; - jit_reloc_t skip; + uint32_t *patch_loc = NULL; if (guard == GUARD_NEEDED) - skip = jit_jmp(_jit); + patch_loc = jmp_without_veneer(_jit); // FIXME: Could de-duplicate constants. for (size_t i = 0; i < _jit->pool->size; i++) { @@ -1363,8 +1369,8 @@ emit_literal_pool(jit_state_t *_jit, enum guard_pool guard) } if (guard == GUARD_NEEDED) - jit_patch_here(_jit, skip); + patch_jmp_without_veneer(_jit, patch_loc); - clear_literal_pool(_jit->pool); + reset_literal_pool(_jit, _jit->pool); } #endif |