[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Guile-commits] 02/02: Improve handling of push/pop/drop in jit
From: |
Andy Wingo |
Subject: |
[Guile-commits] 02/02: Improve handling of push/pop/drop in jit |
Date: |
Mon, 2 Oct 2023 08:06:30 -0400 (EDT) |
wingo pushed a commit to branch main
in repository guile.
commit 624dd8a17a377a7ab38ca5068006fbdb14af6731
Author: Andy Wingo <wingo@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);