[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Guile-commits] 10/14: Always emit veneers for non-bl jumps to ARM code
From: |
Andy Wingo |
Subject: |
[Guile-commits] 10/14: Always emit veneers for non-bl jumps to ARM code |
Date: |
Fri, 12 Jun 2020 10:18:44 -0400 (EDT) |
wingo pushed a commit to branch master
in repository guile.
commit 11b9d3744e963a121270712199bbfa7edb70d245
Author: Icecream95 <ixn@keemail.me>
AuthorDate: Thu Apr 9 22:10:15 2020 +1200
Always emit veneers for non-bl jumps to ARM code
It is unlikely for any ARM code to be close enough to not have needed
a veneer, but it is possible, especially if running in a program with
another JIT library.
---
lightening/aarch64.c | 4 ++--
lightening/arm-cpu.c | 26 ++++++++++++++++++--------
lightening/lightening.c | 9 +++++----
3 files changed, 25 insertions(+), 14 deletions(-)
diff --git a/lightening/aarch64.c b/lightening/aarch64.c
index b605cc5..2b3ed4d 100644
--- a/lightening/aarch64.c
+++ b/lightening/aarch64.c
@@ -90,9 +90,9 @@ DEFINE_ENCODER(size, 2, 22, unsigned, uint32_t)
{ \
return read_signed_bitfield(*loc, kind##_width, kind##_shift); \
} \
- static int offset_in_##name##_range(ptrdiff_t diff) maybe_unused; \
+ static int offset_in_##name##_range(ptrdiff_t diff, int flags) maybe_unused;
\
static int \
- offset_in_##name##_range(ptrdiff_t diff) \
+ offset_in_##name##_range(ptrdiff_t diff, int flags) \
{ \
return in_signed_range(diff, kind##_width); \
} \
diff --git a/lightening/arm-cpu.c b/lightening/arm-cpu.c
index 192c705..1bb7394 100644
--- a/lightening/arm-cpu.c
+++ b/lightening/arm-cpu.c
@@ -186,6 +186,8 @@
#define _NOREG (jit_gpr_regno(_PC))
+#define JIT_RELOC_B JIT_RELOC_FLAG_0
+
static void
emit_wide_thumb(jit_state_t *_jit, uint32_t inst)
{
@@ -265,9 +267,12 @@ write_wide_thumb(uint32_t *loc, uint32_t v)
}
static int
-offset_in_jmp_range(int32_t offset)
+offset_in_jmp_range(int32_t offset, int flags)
{
- return -0x1000000 <= offset && offset <= 0xffffff;
+ if (!(offset & 1) && flags | JIT_RELOC_B)
+ return 0;
+ else
+ return -0x1000000 <= offset && offset <= 0xffffff;
}
static int32_t
@@ -295,7 +300,7 @@ static const uint32_t thumb_jump_mask = 0xf800d000;
static uint32_t
encode_thumb_jump(int32_t v)
{
- ASSERT(offset_in_jmp_range(v));
+ ASSERT(offset_in_jmp_range(v, 0));
v >>= 1;
uint32_t s = !!(v & 0x800000);
uint32_t i1 = !!(v & 0x400000);
@@ -339,8 +344,10 @@ emit_thumb_jump(jit_state_t *_jit, uint32_t inst)
while (1) {
uint8_t *pc_base = _jit->pc.uc + 4;
int32_t off = (uint8_t*)jit_address(_jit) - pc_base;
- jit_reloc_t ret =
- jit_reloc (_jit, JIT_RELOC_JMP_WITH_VENEER, 0, _jit->pc.uc, pc_base, 0);
+ enum jit_reloc_kind kind = JIT_RELOC_JMP_WITH_VENEER;
+ if (inst == THUMB2_B)
+ kind |= JIT_RELOC_B;
+ jit_reloc_t ret = jit_reloc (_jit, kind, 0, _jit->pc.uc, pc_base, 0);
uint8_t thumb_jump_width = 24;
if (add_pending_literal(_jit, ret, thumb_jump_width - 1)) {
emit_wide_thumb(_jit, patch_thumb_jump(inst, off));
@@ -350,9 +357,12 @@ emit_thumb_jump(jit_state_t *_jit, uint32_t inst)
}
static int
-offset_in_jcc_range(int32_t v)
+offset_in_jcc_range(int32_t v, int flags)
{
- return -0x100000 <= v && v <= 0xfffff;
+ if (!(v & 1))
+ return 0;
+ else
+ return -0x100000 <= v && v <= 0xfffff;
}
static int32_t
@@ -378,7 +388,7 @@ static const uint32_t thumb_cc_jump_mask = 0xfbc0d000;
static uint32_t
encode_thumb_cc_jump(int32_t v)
{
- ASSERT(offset_in_jcc_range(v));
+ ASSERT(offset_in_jcc_range(v, 0));
v >>= 1;
uint32_t s = !!(v & 0x80000);
uint32_t j2 = !!(v & 0x40000);
diff --git a/lightening/lightening.c b/lightening/lightening.c
index 92e40c4..6620788 100644
--- a/lightening/lightening.c
+++ b/lightening/lightening.c
@@ -105,11 +105,11 @@ enum guard_pool { GUARD_NEEDED, NO_GUARD_NEEDED };
static void emit_literal_pool(jit_state_t *_jit, enum guard_pool guard);
static int32_t read_jmp_offset(uint32_t *loc);
-static int offset_in_jmp_range(ptrdiff_t offset);
+static int offset_in_jmp_range(ptrdiff_t offset, int flags);
static void patch_jmp_offset(uint32_t *loc, ptrdiff_t offset);
static void patch_veneer_jmp_offset(uint32_t *loc, ptrdiff_t offset);
static int32_t read_jcc_offset(uint32_t *loc);
-static int offset_in_jcc_range(ptrdiff_t offset);
+static int offset_in_jcc_range(ptrdiff_t offset, int flags);
static void patch_jcc_offset(uint32_t *loc, ptrdiff_t offset);
static void patch_veneer_jcc_offset(uint32_t *loc, ptrdiff_t offset);
static void patch_veneer(uint32_t *loc, jit_pointer_t addr);
@@ -380,6 +380,7 @@ jit_patch_there(jit_state_t* _jit, jit_reloc_t reloc,
jit_pointer_t addr)
ptrdiff_t diff = (uint8_t*)addr - pc_base;
ASSERT((diff & ((1 << reloc.rsh) - 1)) == 0);
diff >>= reloc.rsh;
+ int flags = reloc.kind & ~JIT_RELOC_MASK;
switch (reloc.kind & JIT_RELOC_MASK)
{
@@ -406,7 +407,7 @@ jit_patch_there(jit_state_t* _jit, jit_reloc_t reloc,
jit_pointer_t addr)
uint8_t *target = pc_base + (voff << reloc.rsh);
if (target == loc.uc) {
// PC still in range to reify direct branch.
- if (offset_in_jmp_range(diff)) {
+ if (offset_in_jmp_range(diff, flags)) {
// Target also in range: reify direct branch.
patch_jmp_offset(loc.ui, diff);
remove_pending_literal(_jit, reloc);
@@ -425,7 +426,7 @@ jit_patch_there(jit_state_t* _jit, jit_reloc_t reloc,
jit_pointer_t addr)
int32_t voff = read_jcc_offset(loc.ui);
uint8_t *target = pc_base + (voff << reloc.rsh);
if (target == loc.uc) {
- if (offset_in_jcc_range(diff)) {
+ if (offset_in_jcc_range(diff, flags)) {
patch_jcc_offset(loc.ui, diff);
remove_pending_literal(_jit, reloc);
} else {
- [Guile-commits] 05/14: Use an rsh of 0 for jumps on ARM, (continued)
- [Guile-commits] 05/14: Use an rsh of 0 for jumps on ARM, Andy Wingo, 2020/06/12
- [Guile-commits] 06/14: Return a function pointer from jit_address, Andy Wingo, 2020/06/12
- [Guile-commits] 08/14: Use bx instead of mov for jumps on ARM, Andy Wingo, 2020/06/12
- [Guile-commits] 09/14: Remove T2_BLXI, Andy Wingo, 2020/06/12
- [Guile-commits] 03/14: Add separate functions for veneer patching, Andy Wingo, 2020/06/12
- [Guile-commits] 04/14: Add a test for local forward and backward jumps, Andy Wingo, 2020/06/12
- [Guile-commits] 07/14: Stop setting the thumb bit except on jumps to veneers, Andy Wingo, 2020/06/12
- [Guile-commits] 12/14: Add CI jobs for ARM in both instruction sets, Andy Wingo, 2020/06/12
- [Guile-commits] 11/14: Convert BLI to BLXI for jumps to ARM code, Andy Wingo, 2020/06/12
- [Guile-commits] 14/14: Update lightening, Andy Wingo, 2020/06/12
- [Guile-commits] 10/14: Always emit veneers for non-bl jumps to ARM code,
Andy Wingo <=
- [Guile-commits] 13/14: Merge branch 'arm-fix' into 'master', Andy Wingo, 2020/06/12