wingo pushed a commit to branch main
in repository guile.

commit 624dd8a17a377a7ab38ca5068006fbdb14af6731
Author: Andy Wingo <wi...@pobox.com>
AuthorDate: Mon Oct 2 13:58:34 2023 +0200

    Improve handling of push/pop/drop in jit
    
    Previously, these instructions were compiled directly.  However, the JIT
    also wants to fuse comparisons with branches, and an intervening "drop"
    breaks that.  Instead we take a different approach and rely on the
    compiler only emitting push/pop/drop in a peephole sort of way, and we
    can just simulate the temp stack space and dispatch directly.
    
    * libguile/jit.c (compile_push, compile_push_slow, compile_pop):
    (compile_pop_slow, compile_drop, compile_drop_slow): Crash if these are
    called.
    (COMPILE_WIDE_OP1, COMPILE_WIDE_OP2, COMPILE_WIDE_OP3, COMPILE_WIDE_OP4)
    (COMPILE_WIDE_OP5):
    (COMPILE_WIDE_DOP1, COMPILE_WIDE_DOP2, COMPILE_WIDE_DOP3)
    (COMPILE_WIDE_DOP4, COMPILE_WIDE_DOP5): New helpers.  I didn't manage to
    share implementation with COMPILE_*.
    (COMPILE_WIDE_*): New variants of compilers that take their operands
    from an array instead of parsing the inline operands, relying on
    convention for how the compiler emits these instructions.
    (parse_wide_operands): New helper to parse out "wide" operands.
    (compile1, compile_slow_path): If we see a "push", parse wide operands.
    (compile): Move label capture for the slow path into compile_slow_path,
    because wide operands may skip some instructions.
---
 libguile/jit.c | 290 ++++++++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 246 insertions(+), 44 deletions(-)

diff --git a/libguile/jit.c b/libguile/jit.c
index a4ede8921..b0aa9df4c 100644
--- a/libguile/jit.c
+++ b/libguile/jit.c
@@ -2084,59 +2084,34 @@ compile_reset_frame_slow (scm_jit_state *j, uint32_t 
nlocals)
 static void
 compile_push (scm_jit_state *j, uint32_t src)
 {
-  jit_gpr_t t = T0;
-  jit_subi (j->jit, SP, SP, sizeof (union scm_vm_stack_element));
-  add_slow_path_patch (j, emit_alloc_frame_for_sp_fast (j, t));
-  emit_mov (j, 0, src + 1, t);
-
-  clear_register_state (j, SP_CACHE_GPR | SP_CACHE_FPR);
-
-  j->frame_size_min++;
-  if (j->frame_size_max != INT32_MAX)
-    j->frame_size_max++;
+  UNREACHABLE ();
 }
 static void
 compile_push_slow (scm_jit_state *j, uint32_t src)
 {
-  jit_gpr_t t = T0;
-  emit_alloc_frame_for_sp_slow (j, t);
-  emit_mov (j, 0, src + 1, t);
-  continue_after_slow_path (j, j->next_ip);
+  UNREACHABLE ();
 }
 
 static void
 compile_pop (scm_jit_state *j, uint32_t dst)
 {
-  emit_mov (j, dst + 1, 0, T0);
-  jit_addi (j->jit, SP, SP, sizeof (union scm_vm_stack_element));
-  emit_store_sp (j);
-
-  clear_register_state (j, SP_CACHE_GPR | SP_CACHE_FPR);
-
-  j->frame_size_min--;
-  if (j->frame_size_max != INT32_MAX)
-    j->frame_size_max--;
+  UNREACHABLE ();
 }
 static void
 compile_pop_slow (scm_jit_state *j, uint32_t dst)
 {
+  UNREACHABLE ();
 }
 
 static void
 compile_drop (scm_jit_state *j, uint32_t nvalues)
 {
-  jit_addi (j->jit, SP, SP, nvalues * sizeof (union scm_vm_stack_element));
-  emit_store_sp (j);
-
-  clear_register_state (j, SP_CACHE_GPR | SP_CACHE_FPR);
-
-  j->frame_size_min -= nvalues;
-  if (j->frame_size_max != INT32_MAX)
-    j->frame_size_max -= nvalues;
+  UNREACHABLE ();
 }
 static void
 compile_drop_slow (scm_jit_state *j, uint32_t nvalues)
 {
+  UNREACHABLE ();
 }
 
 static void
@@ -5337,15 +5312,34 @@ compile_call_scm_from_scmn_scmn_slow (scm_jit_state *j, 
uint32_t dst,
 #define COMPILE_DOP4(t0, t1, t2, t3)     COMPILE_OP4(t0, t1, t2, t3)
 #define COMPILE_DOP5(t0, t1, t2, t3, t4) COMPILE_OP5(t0, t1, t2, t3, t4)
 
+#define COMPILE_WIDE_OP1(t0) \
+  COMPILE_WIDE_##t0
+#define COMPILE_WIDE_OP2(t0, t1) \
+  COMPILE_WIDE_##t0##__##t1
+#define COMPILE_WIDE_OP3(t0, t1, t2) \
+  COMPILE_WIDE_##t0##__##t1##__##t2
+#define COMPILE_WIDE_OP4(t0, t1, t2, t3) \
+  COMPILE_WIDE_##t0##__##t1##__##t2##__##t3
+#define COMPILE_WIDE_OP5(t0, t1, t2, t3, t4) \
+  COMPILE_WIDE_##t0##__##t1##__##t2##__##t3##__##t4
+
+#define COMPILE_WIDE_DOP1(t0)                 COMPILE_WIDE_OP1(t0)
+#define COMPILE_WIDE_DOP2(t0, t1)             COMPILE_WIDE_OP2(t0, t1)
+#define COMPILE_WIDE_DOP3(t0, t1, t2)         COMPILE_WIDE_OP3(t0, t1, t2)
+#define COMPILE_WIDE_DOP4(t0, t1, t2, t3)     COMPILE_WIDE_OP4(t0, t1, t2, t3)
+#define COMPILE_WIDE_DOP5(t0, t1, t2, t3, t4) COMPILE_WIDE_OP5(t0, t1, t2, t3, 
t4)
+
 #define COMPILE_NOP(j, comp)          \
   {                                   \
     bad_instruction (j);              \
   }
+#define COMPILE_WIDE_NOP(j, comp) UNREACHABLE()
 
 #define COMPILE_X32(j, comp)                                            \
   {                                                                     \
     comp (j);                                                           \
   }
+#define COMPILE_WIDE_X32(j, comp) UNREACHABLE()
 
 #define COMPILE_X8_C24(j, comp)                                         \
   {                                                                     \
@@ -5353,10 +5347,15 @@ compile_call_scm_from_scmn_scmn_slow (scm_jit_state *j, 
uint32_t dst,
     UNPACK_24 (j->ip[0], a);                                            \
     comp (j, a);                                                        \
   }
+#define COMPILE_WIDE_X8_C24(j, comp) UNREACHABLE()
+
 #define COMPILE_X8_F24(j, comp)                                         \
   COMPILE_X8_C24 (j, comp)
+#define COMPILE_WIDE_X8_F24(j, comp) UNREACHABLE()
+
 #define COMPILE_X8_S24(j, comp)                                         \
   COMPILE_X8_C24 (j, comp)
+#define COMPILE_WIDE_X8_S24(j, comp) UNREACHABLE()
 
 #define COMPILE_X8_L24(j, comp)                                         \
   {                                                                     \
@@ -5364,18 +5363,36 @@ compile_call_scm_from_scmn_scmn_slow (scm_jit_state *j, 
uint32_t dst,
     a >>= 8; /* Sign extension.  */                                     \
     comp (j, j->ip + a);                                                \
   }
+#define COMPILE_WIDE_X8_L24(j, comp) UNREACHABLE()
+
 #define COMPILE_X8_C12_C12(j, comp)                                     \
   {                                                                     \
     uint16_t a, b;                                                      \
     UNPACK_12_12 (j->ip[0], a, b);                                      \
     comp (j, a, b);                                                     \
   }
+#define COMPILE_WIDE_X8_C12_C12(j, comp) UNREACHABLE()
+
 #define COMPILE_X8_S12_C12(j, comp)                                     \
   COMPILE_X8_C12_C12 (j, comp)
+#define COMPILE_WIDE_X8_S12_C12(j, comp)                                \
+  {                                                                     \
+    SCM_UNUSED uint16_t a;                                              \
+    uint16_t b;                                                         \
+    UNPACK_12_12 (j->ip[0], a, b);                                      \
+    comp (j, wide_operands[0], b);                                      \
+  }
+
 #define COMPILE_X8_S12_S12(j, comp)                                     \
   COMPILE_X8_C12_C12 (j, comp)
+#define COMPILE_WIDE_X8_S12_S12(j, comp)                                \
+  {                                                                     \
+    comp (j, wide_operands[0], wide_operands[1]);                       \
+  }
+
 #define COMPILE_X8_F12_F12(j, comp)                                     \
   COMPILE_X8_C12_C12 (j, comp)
+#define COMPILE_WIDE_X8_F12_F12(j, comp) UNREACHABLE()
 
 #define COMPILE_X8_S12_Z12(j, comp)                                     \
   {                                                                     \
@@ -5383,6 +5400,11 @@ compile_call_scm_from_scmn_scmn_slow (scm_jit_state *j, 
uint32_t dst,
     int16_t b = ((int32_t) j->ip[0]) >> 20; /* Sign extension.  */      \
     comp (j, a, b);                                                     \
   }
+#define COMPILE_WIDE_X8_S12_Z12(j, comp)                                \
+  {                                                                     \
+    int16_t b = ((int32_t) j->ip[0]) >> 20; /* Sign extension.  */      \
+    comp (j, wide_operands[0], b);                                      \
+  }
 
 #define COMPILE_X8_S8_C8_S8(j, comp)                                    \
   {                                                                     \
@@ -5390,10 +5412,30 @@ compile_call_scm_from_scmn_scmn_slow (scm_jit_state *j, 
uint32_t dst,
     UNPACK_8_8_8 (j->ip[0], a, b, c);                                   \
     comp (j, a, b, c);                                                  \
   }
+#define COMPILE_WIDE_X8_S8_C8_S8(j, comp)                               \
+  {                                                                     \
+    SCM_UNUSED uint8_t a, c;                                            \
+    uint8_t b;                                                          \
+    UNPACK_8_8_8 (j->ip[0], a, b, c);                                   \
+    comp (j, wide_operands[0], b, wide_operands[1]);                    \
+  }
+
 #define COMPILE_X8_S8_S8_C8(j, comp)                                    \
   COMPILE_X8_S8_C8_S8 (j, comp)
+#define COMPILE_WIDE_X8_S8_S8_C8(j, comp)                               \
+  {                                                                     \
+    SCM_UNUSED uint8_t a, b;                                            \
+    uint8_t c;                                                          \
+    UNPACK_8_8_8 (j->ip[0], a, b, c);                                   \
+    comp (j, wide_operands[0], wide_operands[1], c);                    \
+  }
+
 #define COMPILE_X8_S8_S8_S8(j, comp)                                    \
   COMPILE_X8_S8_C8_S8 (j, comp)
+#define COMPILE_WIDE_X8_S8_S8_S8(j, comp)                               \
+  {                                                                     \
+    comp (j, wide_operands[0], wide_operands[1], wide_operands[2]);     \
+  }
 
 #define COMPILE_X8_S8_I16(j, comp)                                      \
   {                                                                     \
@@ -5402,6 +5444,13 @@ compile_call_scm_from_scmn_scmn_slow (scm_jit_state *j, 
uint32_t dst,
     UNPACK_8_16 (j->ip[0], a, b);                                       \
     comp (j, a, SCM_PACK (b));                                          \
   }
+#define COMPILE_WIDE_X8_S8_I16(j, comp)                                 \
+  {                                                                     \
+    SCM_UNUSED uint8_t a;                                               \
+    scm_t_bits b;                                                       \
+    UNPACK_8_16 (j->ip[0], a, b);                                       \
+    comp (j, wide_operands[0], SCM_PACK(b));                            \
+  }
 
 #define COMPILE_X8_S8_ZI16(j, comp)                                     \
   {                                                                     \
@@ -5410,19 +5459,30 @@ compile_call_scm_from_scmn_scmn_slow (scm_jit_state *j, 
uint32_t dst,
     UNPACK_8_16 (j->ip[0], a, b);                                       \
     comp (j, a, SCM_PACK ((scm_t_signed_bits) b));                      \
   }
+#define COMPILE_WIDE_X8_S8_ZI16(j, comp)                                \
+  {                                                                     \
+    SCM_UNUSED uint8_t a;                                               \
+    int16_t b;                                                          \
+    UNPACK_8_16 (j->ip[0], a, b);                                       \
+    comp (j, wide_operands[0], SCM_PACK ((scm_t_signed_bits) b));       \
+  }
 
 #define COMPILE_X32__C32(j, comp)                                       \
   {                                                                     \
     comp (j, j->ip[1]);                                                 \
   }
+#define COMPILE_WIDE_X32__C32(j, comp) UNREACHABLE()
 
 #define COMPILE_X32__L32(j, comp)                                       \
   {                                                                     \
     int32_t a = j->ip[1];                                               \
     comp (j, j->ip + a);                                                \
   }
+#define COMPILE_WIDE_X32__L32(j, comp) UNREACHABLE()
+
 #define COMPILE_X32__N32(j, comp)                                       \
   COMPILE_X32__L32 (j, comp)
+#define COMPILE_WIDE_X32__N32(j, comp) UNREACHABLE()
 
 #define COMPILE_X8_C24__L32(j, comp)                                    \
   {                                                                     \
@@ -5432,14 +5492,23 @@ compile_call_scm_from_scmn_scmn_slow (scm_jit_state *j, 
uint32_t dst,
     b = j->ip[1];                                                       \
     comp (j, a, j->ip + b);                                             \
   }
+#define COMPILE_WIDE_X8_C24__L32(j, comp) UNREACHABLE()
+
 #define COMPILE_X8_S24__L32(j, comp)                                    \
   COMPILE_X8_C24__L32 (j, comp)
+#define COMPILE_WIDE_X8_S24__L32(j, comp) UNREACHABLE()
+
 #define COMPILE_X8_S24__LO32(j, comp)                                   \
   COMPILE_X8_C24__L32 (j, comp)
+#define COMPILE_WIDE_X8_S24__LO32(j, comp) UNREACHABLE()
+
 #define COMPILE_X8_S24__N32(j, comp)                                    \
   COMPILE_X8_C24__L32 (j, comp)
+#define COMPILE_WIDE_X8_S24__N32(j, comp) UNREACHABLE()
+
 #define COMPILE_X8_S24__R32(j, comp)                                    \
   COMPILE_X8_C24__L32 (j, comp)
+#define COMPILE_WIDE_X8_S24__R32(j, comp) UNREACHABLE()
 
 #define COMPILE_X8_C24__X8_C24(j, comp)                                 \
   {                                                                     \
@@ -5448,12 +5517,19 @@ compile_call_scm_from_scmn_scmn_slow (scm_jit_state *j, 
uint32_t dst,
     UNPACK_24 (j->ip[1], b);                                            \
     comp (j, a, b);                                                     \
   }
+#define COMPILE_WIDE_X8_C24__X8_C24(j, comp) UNREACHABLE()
+
 #define COMPILE_X8_F24__X8_C24(j, comp)                                 \
   COMPILE_X8_C24__X8_C24(j, comp)
+#define COMPILE_WIDE_X8_F24__X8_C24(j, comp) UNREACHABLE()
+
 #define COMPILE_X8_F24__X8_F24(j, comp)                                 \
   COMPILE_X8_C24__X8_C24(j, comp)
+#define COMPILE_WIDE_X8_F24__X8_F24(j, comp) UNREACHABLE()
+
 #define COMPILE_X8_S24__X8_S24(j, comp)                                 \
   COMPILE_X8_C24__X8_C24(j, comp)
+#define COMPILE_WIDE_X8_S24__X8_S24(j, comp) UNREACHABLE()
 
 #define COMPILE_X8_F12_F12__X8_C24(j, comp)                             \
   {                                                                     \
@@ -5463,6 +5539,7 @@ compile_call_scm_from_scmn_scmn_slow (scm_jit_state *j, 
uint32_t dst,
     UNPACK_24 (j->ip[1], c);                                            \
     comp (j, a, b, c);                                                  \
   }
+#define COMPILE_WIDE_X8_F12_F12__X8_C24(j, comp) UNREACHABLE()
 
 #define COMPILE_X8_F24__B1_X7_C24(j, comp)                              \
   {                                                                     \
@@ -5473,6 +5550,7 @@ compile_call_scm_from_scmn_scmn_slow (scm_jit_state *j, 
uint32_t dst,
     UNPACK_24 (j->ip[1], c);                                            \
     comp (j, a, b, c);                                                  \
   }
+#define COMPILE_WIDE_X8_F24__B1_X7_C24(j, comp) UNREACHABLE()
 
 #define COMPILE_X8_S12_S12__C32(j, comp)                                \
   {                                                                     \
@@ -5482,6 +5560,11 @@ compile_call_scm_from_scmn_scmn_slow (scm_jit_state *j, 
uint32_t dst,
     c = j->ip[1];                                                       \
     comp (j, a, b, c);                                                  \
   }
+#define COMPILE_WIDE_X8_S12_S12__C32(j, comp)                           \
+  {                                                                     \
+    uint32_t c = j->ip[1];                                              \
+    comp (j, wide_operands[0], wide_operands[1], c);                    \
+  }
 
 #define COMPILE_X8_S24__C16_C16(j, comp)                                \
   {                                                                     \
@@ -5491,6 +5574,7 @@ compile_call_scm_from_scmn_scmn_slow (scm_jit_state *j, 
uint32_t dst,
     UNPACK_16_16 (j->ip[1], b, c);                                      \
     comp (j, a, b, c);                                                  \
   }
+#define COMPILE_WIDE_X8_S24__C16_C16(j, comp) UNREACHABLE()
 
 #define COMPILE_X8_S24__C32(j, comp)                                    \
   {                                                                     \
@@ -5499,6 +5583,7 @@ compile_call_scm_from_scmn_scmn_slow (scm_jit_state *j, 
uint32_t dst,
     b = j->ip[1];                                                       \
     comp (j, a, b);                                                     \
   }
+#define COMPILE_WIDE_X8_S24__C32(j, comp) UNREACHABLE()
 
 #define COMPILE_X8_S24__I32(j, comp)                                    \
   {                                                                     \
@@ -5508,19 +5593,43 @@ compile_call_scm_from_scmn_scmn_slow (scm_jit_state *j, 
uint32_t dst,
     b = j->ip[1];                                                       \
     comp (j, a, SCM_PACK (b));                                          \
   }
+#define COMPILE_WIDE_X8_S24__I32(j, comp) UNREACHABLE()
 
 #define COMPILE_X8_S8_S8_C8__C32(j, comp)                               \
   {                                                                     \
     uint8_t a, b, c;                                                    \
-    uint32_t d;                                                         \
     UNPACK_8_8_8 (j->ip[0], a, b, c);                                   \
+    uint32_t d;                                                         \
     d = j->ip[1];                                                       \
     comp (j, a, b, c, d);                                               \
   }
+#define COMPILE_WIDE_X8_S8_S8_C8__C32(j, comp)                          \
+  {                                                                     \
+    SCM_UNUSED uint16_t a, b;                                           \
+    uint8_t c;                                                          \
+    UNPACK_8_8_8 (j->ip[0], a, b, c);                                   \
+    uint32_t d = j->ip[1];                                              \
+    comp (j, wide_operands[0], wide_operands[1], c, d);                 \
+  }
+
 #define COMPILE_X8_S8_S8_S8__C32(j, comp)                               \
   COMPILE_X8_S8_S8_C8__C32(j, comp)
+#define COMPILE_WIDE_X8_S8_S8_S8__C32(j, comp)                          \
+  {                                                                     \
+    uint32_t d = j->ip[1];                                              \
+    comp (j, wide_operands[0], wide_operands[1], wide_operands[2], d);  \
+  }
+
 #define COMPILE_X8_S8_C8_S8__C32(j, comp)                               \
   COMPILE_X8_S8_S8_C8__C32(j, comp)
+#define COMPILE_WIDE_X8_S8_C8_S8__C32(j, comp)                          \
+  {                                                                     \
+    SCM_UNUSED uint8_t a, c;                                            \
+    uint8_t b;                                                          \
+    UNPACK_8_8_8 (j->ip[0], a, b, c);                                   \
+    uint32_t d = j->ip[1];                                              \
+    comp (j, wide_operands[0], b, wide_operands[1], d);                 \
+  }
 
 #define COMPILE_X8_S24__V32_X8_L24(j, comp)                             \
   {                                                                     \
@@ -5530,12 +5639,14 @@ compile_call_scm_from_scmn_scmn_slow (scm_jit_state *j, 
uint32_t dst,
     j->next_ip += len;                                                  \
     comp (j, a, len, j->ip + 2);                                        \
   }
+#define COMPILE_WIDE_X8_S24__V32_X8_L24(j, comp) UNREACHABLE()
 
 #define COMPILE_X32__LO32__L32(j, comp)                                 \
   {                                                                     \
     int32_t a = j->ip[1], b = j->ip[2];                                 \
     comp (j, j->ip + a, j->ip + b);                                     \
   }
+#define COMPILE_WIDE_X32__LO32__L32(j, comp) UNREACHABLE()
 
 #define COMPILE_X8_F24__X8_C24__L32(j, comp)                            \
   {                                                                     \
@@ -5546,6 +5657,7 @@ compile_call_scm_from_scmn_scmn_slow (scm_jit_state *j, 
uint32_t dst,
     c = j->ip[2];                                                       \
     comp (j, a, b, j->ip + c);                                          \
   }
+#define COMPILE_WIDE_X8_F24__X8_C24__L32(j, comp) UNREACHABLE()
 
 #define COMPILE_X8_S24__A32__B32(j, comp)                               \
   {                                                                     \
@@ -5556,6 +5668,7 @@ compile_call_scm_from_scmn_scmn_slow (scm_jit_state *j, 
uint32_t dst,
     ASSERT (b <= (uint64_t) UINTPTR_MAX);                               \
     comp (j, a, SCM_PACK ((uintptr_t) b));                              \
   }
+#define COMPILE_WIDE_X8_S24__A32__B32(j, comp) UNREACHABLE()
 
 #define COMPILE_X8_S24__AF32__BF32(j, comp)                             \
   {                                                                     \
@@ -5565,6 +5678,7 @@ compile_call_scm_from_scmn_scmn_slow (scm_jit_state *j, 
uint32_t dst,
     b.u = (((uint64_t) j->ip[1]) << 32) | ((uint64_t) j->ip[2]);        \
     comp (j, a, b.d);                                                   \
   }
+#define COMPILE_WIDE_X8_S24__AF32__BF32(j, comp) UNREACHABLE()
 
 #define COMPILE_X8_S24__AS32__BS32(j, comp)                             \
   {                                                                     \
@@ -5574,6 +5688,7 @@ compile_call_scm_from_scmn_scmn_slow (scm_jit_state *j, 
uint32_t dst,
     b = (((uint64_t) j->ip[1]) << 32) | ((uint64_t) j->ip[2]);          \
     comp (j, a, (int64_t) b);                                           \
   }
+#define COMPILE_WIDE_X8_S24__AS32__BS32(j, comp) UNREACHABLE()
 
 #define COMPILE_X8_S24__AU32__BU32(j, comp)                             \
   {                                                                     \
@@ -5583,6 +5698,7 @@ compile_call_scm_from_scmn_scmn_slow (scm_jit_state *j, 
uint32_t dst,
     b = (((uint64_t) j->ip[1]) << 32) | ((uint64_t) j->ip[2]);          \
     comp (j, a, b);                                                     \
   }
+#define COMPILE_WIDE_X8_S24__AU32__BU32(j, comp) UNREACHABLE()
 
 #define COMPILE_X8_S24__B1_X7_F24__X8_L24(j, comp)                      \
   {                                                                     \
@@ -5595,6 +5711,7 @@ compile_call_scm_from_scmn_scmn_slow (scm_jit_state *j, 
uint32_t dst,
     d = j->ip[2]; d >>= 8; /* Sign extension.  */                       \
     comp (j, a, b, c, j->ip + d);                                       \
   }
+#define COMPILE_WIDE_X8_S24__B1_X7_F24__X8_L24(j, comp) UNREACHABLE()
 
 #define COMPILE_X8_S24__X8_S24__C8_S24(j, comp)                         \
   {                                                                     \
@@ -5605,6 +5722,7 @@ compile_call_scm_from_scmn_scmn_slow (scm_jit_state *j, 
uint32_t dst,
     UNPACK_8_24 (j->ip[2], c, d);                                       \
     comp (j, a, b, c, d);                                               \
   }
+#define COMPILE_WIDE_X8_S24__X8_S24__C8_S24(j, comp) UNREACHABLE()
 
 #define COMPILE_X8_C24__C8_C24__X8_C24__N32(j, comp)                    \
   {                                                                     \
@@ -5617,6 +5735,7 @@ compile_call_scm_from_scmn_scmn_slow (scm_jit_state *j, 
uint32_t dst,
     e = j->ip[3];                                                       \
     comp (j, a, b, c, d, j->ip + e);                                    \
   }
+#define COMPILE_WIDE_X8_C24__C8_C24__X8_C24__N32(j, comp) UNREACHABLE()
 
 #define COMPILE_X8_S24__X8_S24__C8_S24__X8_S24(j, comp)                 \
   {                                                                     \
@@ -5628,6 +5747,7 @@ compile_call_scm_from_scmn_scmn_slow (scm_jit_state *j, 
uint32_t dst,
     UNPACK_24 (j->ip[3], e);                                            \
     comp (j, a, b, c, d, e);                                            \
   }
+#define COMPILE_WIDE_X8_S24__X8_S24__C8_S24__X8_S24(j, comp) UNREACHABLE()
 
 #define COMPILE_X8_S24__N32__N32__C32(j, comp)                          \
   {                                                                     \
@@ -5638,6 +5758,54 @@ compile_call_scm_from_scmn_scmn_slow (scm_jit_state *j, 
uint32_t dst,
     uint32_t d = j->ip[3];                                              \
     comp (j, a, j->ip + b, j->ip + c, d);                               \
   }
+#define COMPILE_WIDE_X8_S24__N32__N32__C32(j, comp) UNREACHABLE()
+
+static uint8_t
+parse_wide_operands (scm_jit_state *j, uint32_t wide_operands[3])
+{
+  uint8_t opcode = j->ip[0] & 0xff;
+  uint32_t push_count = 0;
+  while (opcode == scm_op_push)
+    {
+      ASSERT (push_count < 3);
+      UNPACK_24 (j->ip[0], wide_operands[push_count]);
+      wide_operands[push_count] -= push_count;
+      push_count++;
+      j->ip = j->next_ip;
+      opcode = j->ip[0] & 0xff;
+      j->next_ip = j->ip + op_lengths[opcode];
+    }
+  ASSERT (push_count > 0);
+
+  uint8_t finish_opcode = j->next_ip[0] & 0xff;
+  uint32_t pop_count = 0;
+  if (finish_opcode == scm_op_drop)
+    {
+      uint32_t count;
+      UNPACK_24 (j->next_ip[0], count);
+      pop_count += count;
+      ASSERT(pop_count <= push_count);
+      j->next_ip = j->next_ip + op_lengths[finish_opcode];
+      finish_opcode = j->next_ip[0] & 0xff;
+    }
+  if (finish_opcode == scm_op_pop)
+    {
+      ASSERT (push_count < 3);
+      ASSERT (push_count - pop_count == 1);
+      switch (push_count) {
+      case 2: wide_operands[2] = wide_operands[1];  /* fall through */
+      case 1: wide_operands[1] = wide_operands[0]; break;
+      default: UNREACHABLE ();
+      }
+      UNPACK_24 (j->next_ip[0], wide_operands[0]);
+      pop_count++;
+      j->next_ip = j->next_ip + op_lengths[finish_opcode];
+      finish_opcode = j->next_ip[0] & 0xff;
+    }
+
+  ASSERT (pop_count == push_count);
+  return opcode;
+}
 
 static uintptr_t opcodes_seen[256 / (SCM_SIZEOF_UINTPTR_T * 8)];
 
@@ -5683,15 +5851,30 @@ compile1 (scm_jit_state *j)
 
   j->next_ip = j->ip + op_lengths[opcode];
 
-  switch (opcode)
+  if (opcode == scm_op_push)
     {
+      uint32_t wide_operands[3];
+      opcode = parse_wide_operands (j, wide_operands);
+      switch (opcode)
+        {
 #define COMPILE1(code, cname, name, arity) \
-      case code: COMPILE_##arity(j, compile_##cname); break;
-      FOR_EACH_VM_OPERATION(COMPILE1)
+          case code: COMPILE_WIDE_##arity(j, compile_##cname); break;
+          FOR_EACH_VM_OPERATION(COMPILE1)
 #undef COMPILE1
-    default:
-      UNREACHABLE ();
+        default:
+          UNREACHABLE ();
+        }
     }
+  else
+    switch (opcode)
+      {
+#define COMPILE1(code, cname, name, arity)                      \
+        case code: COMPILE_##arity(j, compile_##cname); break;
+        FOR_EACH_VM_OPERATION(COMPILE1)
+#undef COMPILE1
+      default:
+        UNREACHABLE ();
+      }
 
   j->ip = j->next_ip;
 }
@@ -5702,14 +5885,35 @@ compile_slow_path (scm_jit_state *j)
   uint8_t opcode = j->ip[0] & 0xff;
   j->next_ip = j->ip + op_lengths[opcode];
 
-  switch (opcode)
+  if (opcode == scm_op_push)
     {
+      uint32_t wide_operands[3];
+      opcode = parse_wide_operands (j, wide_operands);
+      ptrdiff_t offset = j->ip - j->start;
+      j->labels[slow_label_offset (offset)] = jit_address (j->jit);
+      switch (opcode)
+        {
 #define COMPILE_SLOW(code, cname, name, arity) \
-      case code: COMPILE_##arity(j, compile_##cname##_slow); break;
-      FOR_EACH_VM_OPERATION(COMPILE_SLOW)
+          case code: COMPILE_WIDE_##arity(j, compile_##cname##_slow); break;
+          FOR_EACH_VM_OPERATION(COMPILE_SLOW)
 #undef COMPILE_SLOW
-    default:
-      UNREACHABLE ();
+        default:
+          UNREACHABLE ();
+        }
+    }
+  else
+    {
+      ptrdiff_t offset = j->ip - j->start;
+      j->labels[slow_label_offset (offset)] = jit_address (j->jit);
+      switch (opcode)
+        {
+#define COMPILE_SLOW(code, cname, name, arity)                          \
+          case code: COMPILE_##arity(j, compile_##cname##_slow); break;
+          FOR_EACH_VM_OPERATION(COMPILE_SLOW)
+#undef COMPILE_SLOW
+        default:
+          UNREACHABLE ();
+        }
     }
 
   j->ip = j->next_ip;
@@ -5838,8 +6042,6 @@ compile (scm_jit_state *j)
   j->ip = (uint32_t *) j->start;
   while (j->ip < j->end)
     {
-      ptrdiff_t offset = j->ip - j->start;
-      j->labels[slow_label_offset (offset)] = jit_address (j->jit);
       // set register state from j->register_states[offset] ?
       reset_register_state (j, SP_IN_REGISTER);
       compile_slow_path (j);

Reply via email to