guile-commits
[Top][All Lists]
Advanced

[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);
+}



reply via email to

[Prev in Thread] Current Thread [Next in Thread]