[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Guile-commits] 01/05: Add jmpi_with_link instruction
From: |
Andy Wingo |
Subject: |
[Guile-commits] 01/05: Add jmpi_with_link instruction |
Date: |
Thu, 20 Jun 2019 04:59:14 -0400 (EDT) |
wingo pushed a commit to branch master
in repository guile.
commit 62183fb098e14ad45fc0eae727f98558812b67db
Author: Andy Wingo <address@hidden>
Date: Thu Jun 20 10:08:28 2019 +0200
Add jmpi_with_link instruction
The existing calli / callr interface is for ABI calls. Sometimes though
you want to call some of your own code, just to get the current return
address. ARM's branch-and-link instructions are ideal for this but they
don't exist on x86; there we emulate them by adding corresponding
pop_link_register / push_link_register instructions that are no-ops on
ARM.
* lightening.h (FOR_EACH_INSTRUCTION): Add jit_jmpi_with_link,
pop_link_register, push_link_register.
* lightening/arm-cpu.c:
* lightening/x86-cpu.c:
* lightening/aarch64-cpu.c (jmpi_with_link, push_link_register)
(pop_link_register): Add implementations.
* lightening/arm.h:
* lightening/aarch64.h:
* lightening/x86.h (JIT_LR): New definition.
* tests/link-register.c: New test.
---
lightening.h | 4 ++++
lightening/aarch64-cpu.c | 16 ++++++++++++++++
lightening/aarch64.h | 1 +
lightening/arm-cpu.c | 16 ++++++++++++++++
lightening/arm.h | 1 +
lightening/x86-cpu.c | 18 ++++++++++++++++++
lightening/x86.h | 1 +
tests/link-register.c | 35 +++++++++++++++++++++++++++++++++++
8 files changed, 92 insertions(+)
diff --git a/lightening.h b/lightening.h
index 7fd96f2..bcf2032 100644
--- a/lightening.h
+++ b/lightening.h
@@ -584,6 +584,10 @@ jit_load_args_3(jit_state_t *_jit, jit_operand_t a,
jit_operand_t b,
M(_G___, jmpr) \
M(_p___, jmpi) \
M(R____, jmp) \
+ \
+ M(_p___, jmpi_with_link) \
+ M(_____, pop_link_register) \
+ M(_____, push_link_register) \
\
M(_____, ret) \
M(_G___, retr) \
diff --git a/lightening/aarch64-cpu.c b/lightening/aarch64-cpu.c
index e99c696..13aa351 100644
--- a/lightening/aarch64-cpu.c
+++ b/lightening/aarch64-cpu.c
@@ -2426,6 +2426,22 @@ calli(jit_state_t *_jit, jit_word_t i0)
}
static void
+jmpi_with_link(jit_state_t *_jit, jit_word_t i0)
+{
+ return calli(_jit, i0);
+}
+
+static void
+push_link_register(jit_state_t *_jit)
+{
+}
+
+static void
+pop_link_register(jit_state_t *_jit)
+{
+}
+
+static void
ret(jit_state_t *_jit)
{
RET(_jit);
diff --git a/lightening/aarch64.h b/lightening/aarch64.h
index 9aa0f0d..5c99f63 100644
--- a/lightening/aarch64.h
+++ b/lightening/aarch64.h
@@ -123,6 +123,7 @@
#define JIT_PLATFORM_CALLEE_SAVE_GPRS _X29, _X30
// x31 is stack pointer.
+#define JIT_LR _X30
#define JIT_SP _X31
#define JIT_F0 _D0
diff --git a/lightening/arm-cpu.c b/lightening/arm-cpu.c
index a280ca1..d96d57b 100644
--- a/lightening/arm-cpu.c
+++ b/lightening/arm-cpu.c
@@ -2912,6 +2912,22 @@ calli(jit_state_t *_jit, jit_word_t i0)
}
static void
+jmpi_with_link(jit_state_t *_jit, jit_word_t i0)
+{
+ jit_patch_there(_jit, T2_BLI(_jit), (void*)i0);
+}
+
+static void
+push_link_register(jit_state_t *_jit)
+{
+}
+
+static void
+pop_link_register(jit_state_t *_jit)
+{
+}
+
+static void
ret(jit_state_t *_jit)
{
T1_BX(_jit, jit_gpr_regno(_LR));
diff --git a/lightening/arm.h b/lightening/arm.h
index 47bd2c2..b18411e 100644
--- a/lightening/arm.h
+++ b/lightening/arm.h
@@ -105,6 +105,7 @@
#define JIT_V5 _R10
#define JIT_V6 _R11
+#define JIT_LR _R14
#define JIT_SP _R13
#define _LR _R14
#define _PC _R15
diff --git a/lightening/x86-cpu.c b/lightening/x86-cpu.c
index aa2bbdd..d737f26 100644
--- a/lightening/x86-cpu.c
+++ b/lightening/x86-cpu.c
@@ -2553,6 +2553,24 @@ calli(jit_state_t *_jit, jit_word_t i0)
}
static void
+jmpi_with_link(jit_state_t *_jit, jit_word_t i0)
+{
+ return calli(_jit, i0);
+}
+
+static void
+pop_link_register(jit_state_t *_jit)
+{
+ popr(_jit, jit_gpr_regno (JIT_LR));
+}
+
+static void
+push_link_register(jit_state_t *_jit)
+{
+ pushr(_jit, jit_gpr_regno (JIT_LR));
+}
+
+static void
jmpr(jit_state_t *_jit, int32_t r0)
{
rex(_jit, 0, WIDE, _NOREG, _NOREG, r0);
diff --git a/lightening/x86.h b/lightening/x86.h
index 64ee006..983ebdb 100644
--- a/lightening/x86.h
+++ b/lightening/x86.h
@@ -74,6 +74,7 @@
#endif
#define JIT_SP _RSP
+#define JIT_LR JIT_TMP0
#if __X32
# define JIT_R0 _RAX
# define JIT_R1 _RCX
diff --git a/tests/link-register.c b/tests/link-register.c
new file mode 100644
index 0000000..96ee959
--- /dev/null
+++ b/tests/link-register.c
@@ -0,0 +1,35 @@
+#include "test.h"
+
+static void
+run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
+{
+ jit_begin(j, arena_base, arena_size);
+ size_t align = jit_enter_jit_abi(j, 0, 0, 0);
+ jit_load_args_1(j, jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0));
+
+ jit_reloc_t call_tramp = jit_jmp (j);
+
+ void *tramp = jit_address (j);
+ jit_pop_link_register (j);
+ jit_movr (j, JIT_R0, JIT_LR);
+ jit_leave_jit_abi(j, 0, 0, align);
+ jit_retr (j, JIT_R0);
+
+ jit_patch_here (j, call_tramp);
+ jit_jmpi_with_link (j, tramp);
+
+ void *expected_link = jit_address_to_function_pointer (jit_address (j));
+
+ size_t size = 0;
+ void* ret = jit_end(j, &size);
+
+ void* (*f)(void) = ret;
+
+ ASSERT(f() == expected_link);
+}
+
+int
+main (int argc, char *argv[])
+{
+ return main_helper(argc, argv, run_test);
+}