guile-commits
[Top][All Lists]
Advanced

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

[Guile-commits] 05/07: Implement reloc shortening, and remove unused fun


From: Andy Wingo
Subject: [Guile-commits] 05/07: Implement reloc shortening, and remove unused functionality
Date: Fri, 26 Apr 2019 06:45:42 -0400 (EDT)

wingo pushed a commit to branch lightening
in repository guile.

commit 04d89a7ce27ba60bc2735e2f563d88c28fff2208
Author: Andy Wingo <address@hidden>
Date:   Fri Apr 26 12:40:44 2019 +0200

    Implement reloc shortening, and remove unused functionality
---
 lightening.h            |   1 -
 lightening/lightening.c |  29 +++++-------
 lightening/x86-cpu.c    | 114 +++++++++++++-----------------------------------
 lightening/x86.c        |  38 +++++++++++++++-
 4 files changed, 79 insertions(+), 103 deletions(-)

diff --git a/lightening.h b/lightening.h
index 43ef7b8..437ba18 100644
--- a/lightening.h
+++ b/lightening.h
@@ -78,7 +78,6 @@ typedef struct jit_reloc
 {
   uint8_t kind;
   uint8_t inst_start_offset;
-  uint16_t flags;
   uint32_t offset;
 } jit_reloc_t;
 
diff --git a/lightening/lightening.c b/lightening/lightening.c
index 1a13559..faba86b 100644
--- a/lightening/lightening.c
+++ b/lightening/lightening.c
@@ -124,11 +124,6 @@ struct jit_state
   void (*free)(void*);
 };
 
-enum jit_reloc_flags
-{
-  JIT_RELOC_CAN_SHORTEN = 1<<0
-};
-
 #define ASSERT(x) do { if (!(x)) abort(); } while (0)
 #if defined(__GNUC__)
 # define UNLIKELY(exprn) __builtin_expect(exprn, 0)
@@ -139,7 +134,8 @@ enum jit_reloc_flags
 static jit_bool_t jit_get_cpu(void);
 static jit_bool_t jit_init(jit_state_t *);
 static void jit_flush(void *fptr, void *tptr);
-static void jit_try_shorten(jit_state_t *_jit, jit_reloc_t reloc);
+static void jit_try_shorten(jit_state_t *_jit, jit_reloc_t reloc,
+                            jit_pointer_t addr);
 
 jit_bool_t
 init_jit(void)
@@ -283,13 +279,12 @@ static inline void emit_u64(jit_state_t *_jit, uint64_t 
u64) {
 
 static inline jit_reloc_t
 jit_reloc (jit_state_t *_jit, enum jit_reloc_kind kind,
-           uint8_t inst_start_offset, uint16_t flags)
+           uint8_t inst_start_offset)
 {
   jit_reloc_t ret;
 
   ret.kind = kind;
   ret.inst_start_offset = inst_start_offset;
-  ret.flags = 0;
   ret.offset = _jit->pc.uc - _jit->start;
   
   switch (kind)
@@ -331,6 +326,7 @@ jit_patch_there(jit_state_t* _jit, jit_reloc_t reloc, 
jit_pointer_t addr)
   if (_jit->overflow)
     return;
   union jit_pc loc;
+  uint8_t *end;
   loc.uc = _jit->start + reloc.offset;
   ptrdiff_t diff;
 
@@ -341,38 +337,37 @@ jit_patch_there(jit_state_t* _jit, jit_reloc_t reloc, 
jit_pointer_t addr)
         *loc.ui = (uintptr_t)addr;
       else
         *loc.ul = (uintptr_t)addr;
-      if (loc.uc + sizeof(diff) == _jit->pc.uc &&
-          (reloc.flags & JIT_RELOC_CAN_SHORTEN))
-        jit_try_shorten (_jit, reloc);
+      end = loc.uc + sizeof(diff);
       break;
     case JIT_RELOC_REL8:
       diff = ((uint8_t*)addr) - (loc.uc + 1);
       ASSERT (INT8_MIN <= diff && diff <= INT8_MAX);
       *loc.uc = diff;
+      end = loc.uc + 1;
       break;
     case JIT_RELOC_REL16:
       diff = ((uint8_t*)addr) - (loc.uc + 2);
       ASSERT (INT16_MIN <= diff && diff <= INT16_MAX);
       *loc.us = diff;
-      if ((loc.uc + 1) == _jit->pc.uc && (reloc.flags & JIT_RELOC_CAN_SHORTEN))
-        jit_try_shorten (_jit, reloc);
+      end = loc.uc + 2;
       break;
     case JIT_RELOC_REL32:
       diff = ((uint8_t*)addr) - (loc.uc + 4);
       ASSERT (INT32_MIN <= diff && diff <= INT32_MAX);
       *loc.ui = diff;
-      if ((loc.ui + 1) == _jit->pc.ui && (reloc.flags & JIT_RELOC_CAN_SHORTEN))
-        jit_try_shorten (_jit, reloc);
+      end = loc.uc + 4;
       break;
     case JIT_RELOC_REL64:
       diff = ((uint8_t*)addr) - (loc.uc + 8);
       *loc.ul = diff;
-      if ((loc.ul + 1) == _jit->pc.ul && (reloc.flags & JIT_RELOC_CAN_SHORTEN))
-        jit_try_shorten (_jit, reloc);
+      end = loc.uc + 8;
       break;
     default:
       abort ();
     }
+
+  if (end == _jit->pc.uc)
+    jit_try_shorten (_jit, reloc, addr);
 }
 
 #if defined(__i386__) || defined(__x86_64__)
diff --git a/lightening/x86-cpu.c b/lightening/x86-cpu.c
index 7b16393..aa9d68a 100644
--- a/lightening/x86-cpu.c
+++ b/lightening/x86-cpu.c
@@ -403,7 +403,7 @@ mov_addr(jit_state_t *_jit, int32_t r0)
   rex(_jit, 0, WIDE, _NOREG, _NOREG, r0);
   ic(_jit, 0xb8 | r7(r0));
   ptrdiff_t inst_start = _jit->pc.uc - pc_start;
-  return jit_reloc(_jit, JIT_RELOC_ABSOLUTE, inst_start, 0);
+  return jit_reloc(_jit, JIT_RELOC_ABSOLUTE, inst_start);
 }
 
 static void
@@ -660,15 +660,6 @@ testi(jit_state_t *_jit, int32_t r0, jit_word_t i0)
 }
 
 static void
-cc(jit_state_t *_jit, int32_t code, int32_t r0)
-{
-  rex(_jit, 0, 0, _NOREG, _NOREG, r0);
-  ic(_jit, 0x0f);
-  ic(_jit, 0x90 | code);
-  mrm(_jit, 0x03, 0x00, r7(r0));
-}
-
-static void
 negr(jit_state_t *_jit, int32_t r0, int32_t r1)
 {
   if (r0 == r1) {
@@ -1466,69 +1457,6 @@ xori(jit_state_t *_jit, int32_t r0, int32_t r1, 
jit_word_t i0)
 }
 
 static void
-cr(jit_state_t *_jit, int32_t code, int32_t r0, int32_t r1, int32_t r2)
-{
-  if (reg8_p(r0)) {
-    jit_bool_t same = r0 == r1 || r0 == r2;
-    if (!same)
-      ixorr(_jit, r0, r0);
-    icmpr(_jit, r1, r2);
-    if (same)
-      imovi(_jit, r0, 0);
-    cc(_jit, code, r0);
-  } else {
-    jit_gpr_t reg = get_temp_gpr(_jit);
-    ixorr(_jit, jit_gpr_regno(reg), jit_gpr_regno(reg));
-    icmpr(_jit, r1, r2);
-    cc(_jit, code, jit_gpr_regno(reg));
-    movr(_jit, r0, jit_gpr_regno(reg));
-    unget_temp_gpr(_jit);
-  }
-}
-
-static void
-ci(jit_state_t *_jit, int32_t code, int32_t r0, int32_t r1, jit_word_t i0)
-{
-  if (reg8_p(r0)) {
-    jit_bool_t same = r0 == r1;
-    if (!same)
-      ixorr(_jit, r0, r0);
-    icmpi(_jit, r1, i0);
-    if (same)
-      imovi(_jit, r0, 0);
-    cc(_jit, code, r0);
-  } else {
-    jit_gpr_t reg = get_temp_gpr(_jit);
-    ixorr(_jit, jit_gpr_regno(reg), jit_gpr_regno(reg));
-    icmpi(_jit, r1, i0);
-    cc(_jit, code, jit_gpr_regno(reg));
-    movr(_jit, r0, jit_gpr_regno(reg));
-    unget_temp_gpr(_jit);
-  }
-}
-
-static void
-ci0(jit_state_t *_jit, int32_t code, int32_t r0, int32_t r1)
-{
-  if (reg8_p(r0)) {
-    jit_bool_t same = r0 == r1;
-    if (!same)
-      ixorr(_jit, r0, r0);
-    testr(_jit, r1, r1);
-    if (same)
-      imovi(_jit, r0, 0);
-    cc(_jit, code, r0);
-  } else {
-    jit_gpr_t reg = get_temp_gpr(_jit);
-    ixorr(_jit, jit_gpr_regno(reg), jit_gpr_regno(reg));
-    testr(_jit, r1, r1);
-    cc(_jit, code, jit_gpr_regno(reg));
-    movr(_jit, r0, jit_gpr_regno(reg));
-    unget_temp_gpr(_jit);
-  }
-}
-
-static void
 extr_c(jit_state_t *_jit, int32_t r0, int32_t r1)
 {
   if (reg8_p(r1)) {
@@ -2255,7 +2183,7 @@ static jit_reloc_t
 jccs(jit_state_t *_jit, int32_t code)
 {
   ic(_jit, 0x70 | code);
-  return jit_reloc(_jit, JIT_RELOC_REL8, 1, 0);
+  return jit_reloc(_jit, JIT_RELOC_REL8, 1);
 }
 
 static jit_reloc_t
@@ -2263,7 +2191,26 @@ jcc(jit_state_t *_jit, int32_t code)
 {
   ic(_jit, 0x0f);
   ic(_jit, 0x80 | code);
-  return jit_reloc(_jit, JIT_RELOC_REL32, 2, 0);
+  return jit_reloc(_jit, JIT_RELOC_REL32, 2);
+}
+
+static void
+jcci(jit_state_t *_jit, int32_t code, jit_word_t i0)
+{
+  ptrdiff_t rel8 = i0 - (_jit->pc.w + 1 + 1);
+  ptrdiff_t rel32 = i0 - (_jit->pc.w + 2 + 4);
+  if (INT8_MIN <= rel8 && rel8 <= INT8_MAX)
+    {
+      ic(_jit, 0x70 | code);
+      ic(_jit, rel8);
+    }
+  else
+    {
+      ASSERT(INT32_MIN <= rel32 && rel32 <= INT32_MAX);
+      ic(_jit, 0x0f);
+      ic(_jit, 0x80 | code);
+      ii(_jit, rel32);
+    }
 }
 
 #define DEFINE_JUMPS(cc, CC, code)                                      \
@@ -2666,8 +2613,14 @@ jmpr(jit_state_t *_jit, int32_t r0)
 static void
 jmpi(jit_state_t *_jit, jit_word_t i0)
 {
+  ptrdiff_t rel8 = i0 - (_jit->pc.w + 1 + 1);
   ptrdiff_t rel32 = i0 - (_jit->pc.w + 1 + 4);
-  if (INT32_MIN <= rel32 && rel32 <= INT32_MAX)
+  if (INT8_MIN <= rel8 && rel8 <= INT8_MAX)
+    {
+      ic(_jit, 0xeb);
+      ic(_jit, rel8);
+    }
+  else if (INT32_MIN <= rel32 && rel32 <= INT32_MAX)
     {
       ic(_jit, 0xe9);
       ii(_jit, rel32);
@@ -2685,14 +2638,7 @@ static jit_reloc_t
 jmp(jit_state_t *_jit)
 {
   ic(_jit, 0xe9);
-  return jit_reloc(_jit, JIT_RELOC_REL32, 1, 0);
-}
-
-static jit_reloc_t
-jmpsi(jit_state_t *_jit)
-{
-  ic(_jit, 0xeb);
-  return jit_reloc(_jit, JIT_RELOC_REL8, 1, 0);
+  return jit_reloc(_jit, JIT_RELOC_REL32, 1);
 }
 
 static void
diff --git a/lightening/x86.c b/lightening/x86.c
index a0afd02..4031bb1 100644
--- a/lightening/x86.c
+++ b/lightening/x86.c
@@ -351,6 +351,42 @@ jit_flush(void *fptr, void *tptr)
 }
 
 static void
-jit_try_shorten(jit_state_t *_jit, jit_reloc_t reloc)
+jit_try_shorten(jit_state_t *_jit, jit_reloc_t reloc, jit_pointer_t addr)
 {
+  uint8_t *loc = _jit->start + reloc.offset;
+  uint8_t *start = loc - reloc.inst_start_offset;
+  jit_imm_t i0 = (jit_imm_t)addr;
+
+  switch (reloc.kind)
+    {
+    case JIT_RELOC_ABSOLUTE: {
+      _jit->pc.uc = start;
+      ASSERT((loc[-1] & ~7) == 0xb8); // MOVI
+      int32_t r0 = loc[-1] & 7;
+      if (start != loc - 1) {
+        ASSERT(start == loc - 2);
+        r0 |= (loc[-2] & 1) << 3;
+      }
+      return movi(_jit, r0, i0);
+    }
+    case JIT_RELOC_REL8:
+      ASSERT((loc[-1] & ~0xf) == 0x70 || loc[-1] == 0xeb); // JCCSI or JMPSI
+      /* Nothing useful to do.  */
+      return;
+    case JIT_RELOC_REL16:
+      /* We don't emit these.  */
+      abort ();
+    case JIT_RELOC_REL32:
+      _jit->pc.uc = start;
+      if (start[0] == 0xe9) { // JMP
+        return jmpi(_jit, i0);
+      }
+      ASSERT(start[0] == 0x0f); // JCC
+      return jcci(_jit, start[1] & ~0x80, i0);
+    case JIT_RELOC_REL64:
+      /* We don't emit these.  */
+      abort ();
+    default:
+      abort ();
+    }
 }



reply via email to

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