guile-commits
[Top][All Lists]
Advanced

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

[Guile-commits] 01/02: Various fixes for as-needed emission of literal p


From: Andy Wingo
Subject: [Guile-commits] 01/02: Various fixes for as-needed emission of literal pool
Date: Tue, 21 May 2019 09:31:04 -0400 (EDT)

wingo pushed a commit to branch master
in repository guile.

commit b7f367165f6d29cf0eca221a9e1159a9105d9418
Author: Andy Wingo <address@hidden>
Date:   Tue May 21 15:25:08 2019 +0200

    Various fixes for as-needed emission of literal pool
---
 lightening/aarch64-cpu.c | 34 ++++++++++++++++++++++++----------
 lightening/arm-cpu.c     | 24 +++++++++++++++++++++---
 lightening/lightening.c  | 40 +++++++++++++++++++++++-----------------
 3 files changed, 68 insertions(+), 30 deletions(-)

diff --git a/lightening/aarch64-cpu.c b/lightening/aarch64-cpu.c
index c04b4cf..839e55c 100644
--- a/lightening/aarch64-cpu.c
+++ b/lightening/aarch64-cpu.c
@@ -84,7 +84,7 @@ oxx9(jit_state_t *_jit, int32_t Op, int32_t Rd, int32_t Rn, 
int32_t Simm9)
 }
 
 static uint32_t
-encode_ox19(jit_state_t *_jit, int32_t Op, int32_t Rd)
+encode_ox19(int32_t Op, int32_t Rd)
 {
   uint32_t inst = Op;
   inst = write_Rd_bitfield(inst, Rd);
@@ -92,7 +92,7 @@ encode_ox19(jit_state_t *_jit, int32_t Op, int32_t Rd)
 }
 
 static uint32_t
-encode_oc19(jit_state_t *_jit, int32_t Op, int32_t Cc)
+encode_oc19(int32_t Op, int32_t Cc)
 {
   uint32_t inst = Op;
   inst = write_cond2_bitfield(inst, Cc);
@@ -100,7 +100,7 @@ encode_oc19(jit_state_t *_jit, int32_t Op, int32_t Cc)
 }
 
 static uint32_t
-encode_o26(jit_state_t *_jit, int32_t Op)
+encode_o26(int32_t Op)
 {
   uint32_t inst = Op;
   return inst;
@@ -933,13 +933,13 @@ LDP_POS(jit_state_t *_jit, int32_t Rt, int32_t Rt2, 
int32_t Rn, int32_t Simm7)
 static jit_reloc_t
 B(jit_state_t *_jit)
 {
-  return emit_jmp(_jit, encode_o26(_jit, A64_B));
+  return emit_jmp(_jit, encode_o26(A64_B));
 }
 
 static jit_reloc_t
 BL(jit_state_t *_jit)
 {
-  return emit_jmp(_jit, encode_o26(_jit, A64_BL));
+  return emit_jmp(_jit, encode_o26(A64_BL));
 }
 
 static void
@@ -963,19 +963,19 @@ RET(jit_state_t *_jit)
 static jit_reloc_t
 B_C(jit_state_t *_jit, int32_t Cc) 
 {
-  return emit_jcc(_jit, encode_oc19(_jit, A64_B_C, Cc));
+  return emit_jcc(_jit, encode_oc19(A64_B_C, Cc));
 }
 
 static jit_reloc_t
 CBZ(jit_state_t *_jit, int32_t Rd) 
 {
-  return emit_jcc(_jit, encode_ox19(_jit, A64_CBZ|XS,Rd));
+  return emit_jcc(_jit, encode_ox19(A64_CBZ|XS,Rd));
 }
 
 static jit_reloc_t
 CBNZ(jit_state_t *_jit, int32_t Rd) 
 {
-  return emit_jcc(_jit, encode_ox19(_jit, A64_CBNZ|XS,Rd));
+  return emit_jcc(_jit, encode_ox19(A64_CBNZ|XS,Rd));
 }
 
 static void
@@ -987,14 +987,14 @@ NOP(jit_state_t *_jit)
 static jit_reloc_t
 movi_from_pool(jit_state_t *_jit, int32_t Rt)
 {
-  return emit_load_from_pool(_jit, encode_ox19(_jit, A64_LDRI_LITERAL, Rt));
+  return emit_load_from_pool(_jit, encode_ox19(A64_LDRI_LITERAL, Rt));
 }
 
 static void
 emit_veneer(jit_state_t *_jit, jit_pointer_t target)
 {
   jit_gpr_t tmp = get_temp_gpr(_jit);
-  uint32_t inst = encode_ox19(_jit, A64_LDRI_LITERAL, jit_gpr_regno(tmp));
+  uint32_t inst = encode_ox19(A64_LDRI_LITERAL, jit_gpr_regno(tmp));
   uint32_t *loc = _jit->pc.ui;
   emit_u32(_jit, inst);
   BR(_jit, jit_gpr_regno(tmp));
@@ -2536,3 +2536,17 @@ retval_l(jit_state_t *_jit, int32_t r0)
 {
   movr(_jit, r0, jit_gpr_regno(_X0));
 }
+
+static uint32_t*
+jmp_without_veneer(jit_state_t *_jit)
+{
+  uint32_t *loc = _jit->pc.ui;
+  emit_u32(_jit, encode_o26(_jit, A64_B));
+  return loc;
+}
+
+static void
+patch_jmp_without_veneer(jit_state_t *_jit, uint32_t *loc)
+{
+  patch_jmp_offset(loc, _jit->pc.ui - loc);
+}
diff --git a/lightening/arm-cpu.c b/lightening/arm-cpu.c
index 5ce5f06..491b34e 100644
--- a/lightening/arm-cpu.c
+++ b/lightening/arm-cpu.c
@@ -2922,6 +2922,24 @@ retval_i(jit_state_t *_jit, int32_t r0)
   movr(_jit, r0, jit_gpr_regno(_R0));
 }
 
+static uint32_t*
+jmp_without_veneer(jit_state_t *_jit)
+{
+  uint32_t *loc = _jit->pc.ui;
+  emit_u16(_jit, 0);
+  emit_u16(_jit, 0);
+  return loc;
+}
+
+static void
+patch_jmp_without_veneer(jit_state_t *_jit, uint32_t *loc)
+{
+  uint8_t *pc_base = ((uint8_t *)loc) + 4;
+  uint8_t rsh = 1;
+  int32_t off = (_jit->pc.uc - pc_base) >> rsh;
+  write_wide_thumb(loc, THUMB2_B | encode_thumb_jump(off));
+}
+
 struct veneer
 {
   uint16_t ldr;
@@ -2940,11 +2958,11 @@ static void
 emit_veneer(jit_state_t *_jit, jit_pointer_t target)
 {
   uint16_t thumb1_ldr = 0x4800;
-  int32_t tmp = jit_gpr_regno(get_temp_gpr(_jit));
+  int32_t tmp = jit_gpr_regno(JIT_TMP1);
+  int32_t rd = jit_gpr_regno(_PC);
   ASSERT(tmp < 8);
   // Loaded addr is 4 bytes after the LDR, which is aligned, so offset is 0.
   emit_u16(_jit, thumb1_ldr | (tmp << 8));
-  T1_MOV(_jit, jit_gpr_regno(_PC), tmp);
-  unget_temp_gpr(_jit);
+  emit_u16(_jit, THUMB_MOV|((_u4(rd)&8)<<4)|(_u4(tmp)<<3)|(rd&7));
   emit_u32(_jit, (uint32_t) target);
 }
diff --git a/lightening/lightening.c b/lightening/lightening.c
index 9d0d8f2..5050a35 100644
--- a/lightening/lightening.c
+++ b/lightening/lightening.c
@@ -95,7 +95,8 @@ struct abi_arg_iterator;
 #ifdef JIT_NEEDS_LITERAL_POOL
 static struct jit_literal_pool* alloc_literal_pool(jit_state_t *_jit,
                                                    size_t capacity);
-static void clear_literal_pool(struct jit_literal_pool *pool);
+static void reset_literal_pool(jit_state_t *_jit,
+                               struct jit_literal_pool *pool);
 static void grow_literal_pool(jit_state_t *_jit);
 static void add_literal_pool_entry(jit_state_t *_jit,
                                    struct jit_literal_pool_entry entry,
@@ -185,6 +186,9 @@ jit_begin(jit_state_t *_jit, uint8_t* buf, size_t length)
   _jit->limit = buf + length;
   _jit->overflow = 0;
   _jit->frame_size = 0;
+#if JIT_NEEDS_LITERAL_POOL
+  _jit->pool->deadline = length;
+#endif
 }
 
 jit_bool_t
@@ -202,7 +206,7 @@ jit_reset(jit_state_t *_jit)
   _jit->overflow = 0;
   _jit->frame_size = 0;
 #ifdef JIT_NEEDS_LITERAL_POOL
-  clear_literal_pool(_jit->pool);
+  reset_literal_pool(_jit, _jit->pool);
 #endif
 }
 
@@ -240,7 +244,7 @@ jit_end(jit_state_t *_jit, size_t *length)
   _jit->overflow = 0;
   _jit->frame_size = 0;
 #ifdef JIT_NEEDS_LITERAL_POOL
-  clear_literal_pool(_jit->pool);
+  reset_literal_pool(_jit, _jit->pool);
 #endif
 
   return jit_address_to_function_pointer(start);
@@ -1226,9 +1230,10 @@ jit_load_args(jit_state_t *_jit, size_t argc, 
jit_operand_t args[])
 
 #ifdef JIT_NEEDS_LITERAL_POOL
 static void
-clear_literal_pool(struct jit_literal_pool *pool)
+reset_literal_pool(jit_state_t *_jit,
+                   struct jit_literal_pool *pool)
 {
-  pool->deadline = -1;
+  pool->deadline = _jit->limit - _jit->start;
   pool->size = 0;
   pool->byte_size = 0;
   memset(pool->entries, 0, sizeof(pool->entries[0]) * pool->size);
@@ -1245,7 +1250,7 @@ alloc_literal_pool(jit_state_t *_jit, size_t capacity)
                  sizeof (struct jit_literal_pool_entry) * capacity);
   ASSERT (ret);
   ret->capacity = capacity;
-  clear_literal_pool(ret);
+  reset_literal_pool(_jit, ret);
   return ret;
 }
 
@@ -1270,14 +1275,12 @@ add_literal_pool_entry(jit_state_t *_jit, struct 
jit_literal_pool_entry entry,
   if (_jit->pool->size == _jit->pool->capacity)
     grow_literal_pool (_jit);
 
-  max_offset <<= entry.reloc.rsh;
-  ptrdiff_t deadline =
+  uint32_t deadline =
     _jit->pc.uc - _jit->start + max_offset - _jit->pool->byte_size;
-  if (_jit->pool->size == 0)
-    // Assume that we might need a uint32_t for alignment, and another
-    // to branch over the table.
-    _jit->pool->deadline = deadline - 2 * sizeof(uint32_t);
-  else if (deadline < _jit->pool->deadline)
+  // Assume that we might need a uint32_t for alignment, and another
+  // to branch over the table.
+  deadline -= 2 * sizeof(uint32_t);
+  if (deadline < _jit->pool->deadline)
     _jit->pool->deadline = deadline;
 
   // Assume that each entry takes a max of 16 bytes.
@@ -1325,14 +1328,17 @@ patch_pending_literal(jit_state_t *_jit, jit_reloc_t 
src, uint64_t value)
 static void
 emit_literal_pool(jit_state_t *_jit, enum guard_pool guard)
 {
+  if (_jit->overflow)
+    return;
+
   _jit->pool->deadline = -1;
 
   if (!_jit->pool->size)
     return;
 
-  jit_reloc_t skip;
+  uint32_t *patch_loc = NULL;
   if (guard == GUARD_NEEDED)
-    skip = jit_jmp(_jit);
+    patch_loc = jmp_without_veneer(_jit);
 
   // FIXME: Could de-duplicate constants.
   for (size_t i = 0; i < _jit->pool->size; i++) {
@@ -1363,8 +1369,8 @@ emit_literal_pool(jit_state_t *_jit, enum guard_pool 
guard)
   }
 
   if (guard == GUARD_NEEDED)
-    jit_patch_here(_jit, skip);
+    patch_jmp_without_veneer(_jit, patch_loc);
 
-  clear_literal_pool(_jit->pool);
+  reset_literal_pool(_jit, _jit->pool);
 }
 #endif



reply via email to

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