summaryrefslogtreecommitdiff
path: root/libguile/lightening
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2019-04-28 18:44:13 +0200
committerAndy Wingo <wingo@pobox.com>2019-04-28 18:44:13 +0200
commit8f695c058a28fa9e540db1f631f190ec5fdfdf92 (patch)
tree1aa4689b43ba5d97c48b33d47f0c73bdddd86eee /libguile/lightening
parent983af3be3b1e84e537a218d5aceee600783f0170 (diff)
parent483e880b10fbc85bcac36facc3933a22e14b7510 (diff)
downloadguile-8f695c058a28fa9e540db1f631f190ec5fdfdf92.tar.gz
Merge from upstream lightening
Diffstat (limited to 'libguile/lightening')
-rw-r--r--libguile/lightening/lightening/x86-cpu.c32
-rw-r--r--libguile/lightening/lightening/x86.h5
2 files changed, 23 insertions, 14 deletions
diff --git a/libguile/lightening/lightening/x86-cpu.c b/libguile/lightening/lightening/x86-cpu.c
index fab06c7f4..041c54906 100644
--- a/libguile/lightening/lightening/x86-cpu.c
+++ b/libguile/lightening/lightening/x86-cpu.c
@@ -1886,6 +1886,8 @@ ldxi_l(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
}
#endif
+static void stxi_c(jit_state_t *_jit, jit_word_t i0, int32_t r0, int32_t r1);
+
static void
str_c(jit_state_t *_jit, int32_t r0, int32_t r1)
{
@@ -1894,12 +1896,8 @@ str_c(jit_state_t *_jit, int32_t r0, int32_t r1)
ic(_jit, 0x88);
rx(_jit, r1, 0, r0, _NOREG, _SCL1);
} else {
- jit_gpr_t reg = get_temp_gpr(_jit);
- movr(_jit, jit_gpr_regno(reg), r1);
- rex(_jit, 0, 0, jit_gpr_regno(reg), _NOREG, r0);
- ic(_jit, 0x88);
- rx(_jit, jit_gpr_regno(reg), 0, r0, _NOREG, _SCL1);
- unget_temp_gpr(_jit);
+ // See comment in stxi_c.
+ return stxi_c(_jit, 0, r0, r1);
}
}
@@ -2026,12 +2024,24 @@ stxi_c(jit_state_t *_jit, jit_word_t i0, int32_t r0, int32_t r1)
ic(_jit, 0x88);
rx(_jit, r1, i0, r0, _NOREG, _SCL1);
} else {
- jit_gpr_t reg = get_temp_gpr(_jit);
- movr(_jit, jit_gpr_regno(reg), r1);
- rex(_jit, 0, 0, jit_gpr_regno(reg), _NOREG, r0);
+ // Here we have a hack. Normally tmp registers are just for the
+ // backend's use, but there are cases in which jit_move_operands
+ // can use a temp register too. In a move of an operand to memory
+ // this would result in two simultaneous uses of a temp register.
+ // Oddly this situation only applies on 32-bit x86 with byte
+ // stores -- this is the only platform on which reg8_p can be
+ // false -- so we just make a special case here.
+ ASSERT(r0 != r1);
+ int32_t tmp = r0 == _RAX_REGNO ? _RCX_REGNO : _RAX_REGNO;
+ ASSERT(reg8_p(tmp));
+ pushr(_jit, tmp);
+ movr(_jit, tmp, r1);
+ if (r0 == _RSP_REGNO)
+ i0 += __WORDSIZE / 8;
+ rex(_jit, 0, 0, tmp, _NOREG, r0);
ic(_jit, 0x88);
- rx(_jit, jit_gpr_regno(reg), i0, r0, _NOREG, _SCL1);
- unget_temp_gpr(_jit);
+ rx(_jit, tmp, i0, r0, _NOREG, _SCL1);
+ popr(_jit, tmp);
}
} else {
jit_gpr_t reg = get_temp_gpr(_jit);
diff --git a/libguile/lightening/lightening/x86.h b/libguile/lightening/lightening/x86.h
index db5072273..6e029d631 100644
--- a/libguile/lightening/lightening/x86.h
+++ b/libguile/lightening/lightening/x86.h
@@ -125,15 +125,14 @@ jit_fpr_is_callee_save (jit_fpr_t reg)
}
#define JIT_SP _RSP
-#define JIT_FP _RBP
#if __X32
# define JIT_R0 _RAX
# define JIT_R1 _RCX
# define JIT_R2 _RDX
-# define JIT_V0 _RBX
+# define JIT_V0 _RBP
# define JIT_V1 _RSI
# define JIT_V2 _RDI
-# define JIT_VTMP _RBP
+# define JIT_VTMP _RBX
# define JIT_F0 _XMM0
# define JIT_F1 _XMM1
# define JIT_F2 _XMM2