summaryrefslogtreecommitdiff
path: root/lightening/lightening.c
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2020-06-11 16:11:24 +0000
committerAndy Wingo <wingo@pobox.com>2020-06-11 16:11:24 +0000
commit3260f7deebf4148f7c268e9a56cdab7a221e3da5 (patch)
tree5526bf74913d0cf6310c7678026a096029ca1338 /lightening/lightening.c
parent763b1f87e769cbe617f30c9100fd61c81ef821e9 (diff)
parent2a4ed4b77648fc6cc640c1b6bd9a4019cd6a1974 (diff)
downloadguile-3260f7deebf4148f7c268e9a56cdab7a221e3da5.tar.gz
Merge branch 'arm-fix' into 'master'
Fix armv7 with the ARM instruction set Closes #12 See merge request wingo/lightening!3
Diffstat (limited to 'lightening/lightening.c')
-rw-r--r--lightening/lightening.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/lightening/lightening.c b/lightening/lightening.c
index ca5708f0a..66207885f 100644
--- a/lightening/lightening.c
+++ b/lightening/lightening.c
@@ -105,11 +105,13 @@ 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);
static int32_t read_load_from_pool_offset(uint32_t *loc);
#endif
@@ -169,7 +171,7 @@ jit_pointer_t
jit_address(jit_state_t *_jit)
{
ASSERT (_jit->start);
- return _jit->pc.uc;
+ return jit_address_to_function_pointer (_jit->pc.uc);
}
void
@@ -378,8 +380,9 @@ 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)
+ switch (reloc.kind & JIT_RELOC_MASK)
{
case JIT_RELOC_ABSOLUTE:
if (sizeof(diff) == 4)
@@ -404,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);
@@ -423,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 {
@@ -1365,13 +1368,13 @@ emit_literal_pool(jit_state_t *_jit, enum guard_pool guard)
if (_jit->overflow)
return;
- switch (entry->reloc.kind) {
+ switch (entry->reloc.kind & JIT_RELOC_MASK) {
case JIT_RELOC_JMP_WITH_VENEER:
- patch_jmp_offset((uint32_t*) loc, diff);
+ patch_veneer_jmp_offset((uint32_t*) loc, diff);
emit_veneer(_jit, (void*) (uintptr_t) entry->value);
break;
case JIT_RELOC_JCC_WITH_VENEER:
- patch_jcc_offset((uint32_t*) loc, diff);
+ patch_veneer_jcc_offset((uint32_t*) loc, diff);
emit_veneer(_jit, (void*) (uintptr_t) entry->value);
break;
case JIT_RELOC_LOAD_FROM_POOL: