guile-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Guile-commits] 10/20: Add facility to enter and leave JIT ABI


From: Andy Wingo
Subject: [Guile-commits] 10/20: Add facility to enter and leave JIT ABI
Date: Sun, 28 Apr 2019 07:54:20 -0400 (EDT)

wingo pushed a commit to branch lightening
in repository guile.

commit 42bc762d2614996d8e23a50cc26e4a4ac29d787f
Author: Andy Wingo <address@hidden>
Date:   Fri Apr 26 17:26:03 2019 +0200

    Add facility to enter and leave JIT ABI
    
    This allows us to save and restore callee-save temporaries, i.e. RBP on
    32-bit x86.  Otherwise it's a disaster shuffling stack arguments using
    temporaries.
---
 lightening.h            |  5 +++
 lightening/lightening.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++
 lightening/x86-cpu.c    |  6 +--
 lightening/x86.h        |  1 +
 tests/qdivr.c           | 22 +----------
 tests/qdivr_u.c         | 22 +----------
 tests/qmulr.c           | 22 +----------
 tests/qmulr_u.c         | 22 +----------
 8 files changed, 113 insertions(+), 85 deletions(-)

diff --git a/lightening.h b/lightening.h
index db327fc..40db318 100644
--- a/lightening.h
+++ b/lightening.h
@@ -228,6 +228,11 @@ JIT_API void jit_move_operands (jit_state_t *_jit, 
jit_operand_t *dst,
 JIT_API size_t jit_align_stack (jit_state_t *_jit, size_t expand);
 JIT_API void jit_shrink_stack (jit_state_t *_jit, size_t diff);
 
+JIT_API size_t jit_enter_jit_abi (jit_state_t *_jit,
+                                  size_t v, size_t vf, size_t frame_size);
+JIT_API void jit_leave_jit_abi (jit_state_t *_jit,
+                                size_t v, size_t vf, size_t frame_size);
+
 /* Note that all functions that take jit_operand_t args[] use the args
    as scratch space while shuffling values into position.  */
 JIT_API void jit_calli(jit_state_t *, jit_pointer_t f,
diff --git a/lightening/lightening.c b/lightening/lightening.c
index de945e0..74ecf99 100644
--- a/lightening/lightening.c
+++ b/lightening/lightening.c
@@ -863,6 +863,104 @@ jit_shrink_stack(jit_state_t *_jit, size_t diff)
   _jit->frame_size -= diff;
 }
 
+static const jit_gpr_t V[] = {
+#ifdef JIT_VTMP
+  JIT_VTMP ,
+#endif
+  JIT_V0, JIT_V1, JIT_V2
+#ifdef JIT_V3
+  , JIT_V3
+#endif
+#ifdef JIT_V4
+  , JIT_V4
+#endif
+#ifdef JIT_V5
+  , JIT_V5
+#endif
+#ifdef JIT_V6
+  , JIT_V6
+#endif
+#ifdef JIT_V7
+  , JIT_V7
+#endif
+ };
+
+static const jit_fpr_t VF[] = {
+#ifdef JIT_VFTMP
+  JIT_VFTMP ,
+#endif
+#ifdef JIT_VF0
+  JIT_VF0
+#endif
+#ifdef JIT_VF1
+  , JIT_VF1
+#endif
+#ifdef JIT_VF2
+  , JIT_VF2
+#endif
+#ifdef JIT_VF3
+  , JIT_VF3
+#endif
+#ifdef JIT_VF4
+  , JIT_VF4
+#endif
+#ifdef JIT_VF5
+  , JIT_VF5
+#endif
+#ifdef JIT_VF6
+  , JIT_VF6
+#endif
+#ifdef JIT_VF7
+  , JIT_VF7
+#endif
+};
+
+static const size_t v_count = sizeof(V) / sizeof(V[0]);
+static const size_t vf_count = sizeof(VF) / sizeof(VF[0]);
+
+size_t
+jit_enter_jit_abi(jit_state_t *_jit, size_t v, size_t vf, size_t frame_size)
+{
+#ifdef JIT_VTMP
+  v++;
+#endif
+#ifdef JIT_VFTMP
+  vf++;
+#endif
+
+  ASSERT(v <= v_count);
+  ASSERT(vf <= vf_count);
+
+  /* Save values of callee-save registers.  */
+  for (size_t i = 0; i < v; i++)
+    jit_pushr (_jit, V[i]);
+  for (size_t i = 0; i < vf; i++)
+    jit_pushr_d (_jit, VF[i]);
+
+  return jit_align_stack(_jit, frame_size);
+}
+
+void
+jit_leave_jit_abi(jit_state_t *_jit, size_t v, size_t vf, size_t frame_size)
+{
+#ifdef JIT_VTMP
+  v++;
+#endif
+#ifdef JIT_VFTMP
+  vf++;
+#endif
+
+  jit_shrink_stack(_jit, frame_size);
+
+  /* Restore callee-save registers.  */
+  for (size_t i = 0; i < vf; i++)
+    jit_popr_d (_jit, VF[vf_count - i - 1]);
+
+  for (size_t i = 0; i < v; i++)
+    jit_popr (_jit, V[v_count - i - 1]);
+}
+
+
 // Precondition: stack is already aligned.
 static size_t
 prepare_call_args(jit_state_t *_jit, size_t argc, jit_operand_t args[])
diff --git a/lightening/x86-cpu.c b/lightening/x86-cpu.c
index 537e331..6d56b11 100644
--- a/lightening/x86-cpu.c
+++ b/lightening/x86-cpu.c
@@ -273,8 +273,7 @@ get_temp_gpr(jit_state_t *_jit)
 #ifdef JIT_RTMP
   return JIT_RTMP;
 #else
-  pushr(_jit, _RBP_REGNO);
-  return _RBP;
+  return JIT_VTMP;
 #endif
 }
 
@@ -283,9 +282,6 @@ unget_temp_gpr(jit_state_t *_jit)
 {
   ASSERT(_jit->temp_gpr_saved);
   _jit->temp_gpr_saved = 0;
-#ifndef JIT_RTMP
-  popr(_jit, _RBP_REGNO);
-#endif
 }
 
 static void
diff --git a/lightening/x86.h b/lightening/x86.h
index 804af86..db50722 100644
--- a/lightening/x86.h
+++ b/lightening/x86.h
@@ -133,6 +133,7 @@ jit_fpr_is_callee_save (jit_fpr_t reg)
 #  define JIT_V0   _RBX
 #  define JIT_V1   _RSI
 #  define JIT_V2   _RDI
+#  define JIT_VTMP _RBP
 #  define JIT_F0   _XMM0
 #  define JIT_F1   _XMM1
 #  define JIT_F2   _XMM2
diff --git a/tests/qdivr.c b/tests/qdivr.c
index 9e1b8da..665053c 100644
--- a/tests/qdivr.c
+++ b/tests/qdivr.c
@@ -1,26 +1,10 @@
 #include "test.h"
 
 static void
-maybe_save(jit_state_t *j, jit_gpr_t reg)
-{
-  if (jit_gpr_is_callee_save (reg))
-    jit_pushr(j, reg);
-}    
-
-static void
-maybe_restore(jit_state_t *j, jit_gpr_t reg)
-{
-  if (jit_gpr_is_callee_save (reg))
-    jit_popr(j, reg);
-}    
-
-static void
 run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
 {
   jit_begin(j, arena_base, arena_size);
-  maybe_save(j, JIT_V0);
-  maybe_save(j, JIT_V1);
-  maybe_save(j, JIT_V2);
+  size_t align = jit_enter_jit_abi(j, 3, 0, 0);
 
   jit_operand_t args[] =
     { jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
@@ -33,9 +17,7 @@ run_test(jit_state_t *j, uint8_t *arena_base, size_t 
arena_size)
   jit_str(j, JIT_R0, JIT_V1);
   jit_str(j, JIT_R1, JIT_V2);
 
-  maybe_restore(j, JIT_V2);
-  maybe_restore(j, JIT_V1);
-  maybe_restore(j, JIT_V0);
+  jit_leave_jit_abi(j, 3, 0, align);
 
   jit_ret(j);
 
diff --git a/tests/qdivr_u.c b/tests/qdivr_u.c
index 2762199..e260193 100644
--- a/tests/qdivr_u.c
+++ b/tests/qdivr_u.c
@@ -1,27 +1,11 @@
 #include "test.h"
 
 static void
-maybe_save(jit_state_t *j, jit_gpr_t reg)
-{
-  if (jit_gpr_is_callee_save (reg))
-    jit_pushr(j, reg);
-}    
-
-static void
-maybe_restore(jit_state_t *j, jit_gpr_t reg)
-{
-  if (jit_gpr_is_callee_save (reg))
-    jit_popr(j, reg);
-}    
-
-static void
 run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
 {
   jit_begin(j, arena_base, arena_size);
 
-  maybe_save(j, JIT_V0);
-  maybe_save(j, JIT_V1);
-  maybe_save(j, JIT_V2);
+  size_t align = jit_enter_jit_abi(j, 3, 0, 0);
 
   jit_operand_t args[] =
     { jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
@@ -34,9 +18,7 @@ run_test(jit_state_t *j, uint8_t *arena_base, size_t 
arena_size)
   jit_str(j, JIT_R0, JIT_V1);
   jit_str(j, JIT_R1, JIT_V2);
 
-  maybe_restore(j, JIT_V2);
-  maybe_restore(j, JIT_V1);
-  maybe_restore(j, JIT_V0);
+  jit_leave_jit_abi(j, 3, 0, align);
 
   jit_ret(j);
 
diff --git a/tests/qmulr.c b/tests/qmulr.c
index eed0d58..1645f5a 100644
--- a/tests/qmulr.c
+++ b/tests/qmulr.c
@@ -1,27 +1,11 @@
 #include "test.h"
 
 static void
-maybe_save(jit_state_t *j, jit_gpr_t reg)
-{
-  if (jit_gpr_is_callee_save (reg))
-    jit_pushr(j, reg);
-}    
-
-static void
-maybe_restore(jit_state_t *j, jit_gpr_t reg)
-{
-  if (jit_gpr_is_callee_save (reg))
-    jit_popr(j, reg);
-}    
-
-static void
 run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
 {
   jit_begin(j, arena_base, arena_size);
 
-  maybe_save(j, JIT_V0);
-  maybe_save(j, JIT_V1);
-  maybe_save(j, JIT_V2);
+  size_t align = jit_enter_jit_abi(j, 3, 0, 0);
 
   jit_operand_t args[] =
     { jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
@@ -34,9 +18,7 @@ run_test(jit_state_t *j, uint8_t *arena_base, size_t 
arena_size)
   jit_str(j, JIT_R0, JIT_V1);
   jit_str(j, JIT_R1, JIT_V2);
 
-  maybe_restore(j, JIT_V2);
-  maybe_restore(j, JIT_V1);
-  maybe_restore(j, JIT_V0);
+  jit_leave_jit_abi(j, 3, 0, align);
 
   jit_ret(j);
 
diff --git a/tests/qmulr_u.c b/tests/qmulr_u.c
index ff3c926..bb1d50d 100644
--- a/tests/qmulr_u.c
+++ b/tests/qmulr_u.c
@@ -1,27 +1,11 @@
 #include "test.h"
 
 static void
-maybe_save(jit_state_t *j, jit_gpr_t reg)
-{
-  if (jit_gpr_is_callee_save (reg))
-    jit_pushr(j, reg);
-}    
-
-static void
-maybe_restore(jit_state_t *j, jit_gpr_t reg)
-{
-  if (jit_gpr_is_callee_save (reg))
-    jit_popr(j, reg);
-}    
-
-static void
 run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
 {
   jit_begin(j, arena_base, arena_size);
 
-  maybe_save(j, JIT_V0);
-  maybe_save(j, JIT_V1);
-  maybe_save(j, JIT_V2);
+  size_t align = jit_enter_jit_abi(j, 3, 0, 0);
 
   jit_operand_t args[] =
     { jit_operand_gpr (JIT_OPERAND_ABI_POINTER, JIT_R0),
@@ -34,9 +18,7 @@ run_test(jit_state_t *j, uint8_t *arena_base, size_t 
arena_size)
   jit_str(j, JIT_R0, JIT_V1);
   jit_str(j, JIT_R1, JIT_V2);
 
-  maybe_restore(j, JIT_V2);
-  maybe_restore(j, JIT_V1);
-  maybe_restore(j, JIT_V0);
+  jit_leave_jit_abi(j, 3, 0, align);
 
   jit_ret(j);
 



reply via email to

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