diff options
author | Andy Wingo <wingo@pobox.com> | 2019-04-28 18:44:13 +0200 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2019-04-28 18:44:13 +0200 |
commit | 8f695c058a28fa9e540db1f631f190ec5fdfdf92 (patch) | |
tree | 1aa4689b43ba5d97c48b33d47f0c73bdddd86eee | |
parent | 983af3be3b1e84e537a218d5aceee600783f0170 (diff) | |
parent | 483e880b10fbc85bcac36facc3933a22e14b7510 (diff) | |
download | guile-8f695c058a28fa9e540db1f631f190ec5fdfdf92.tar.gz |
Merge from upstream lightening
-rw-r--r-- | libguile/lightening/lightening/x86-cpu.c | 32 | ||||
-rw-r--r-- | libguile/lightening/lightening/x86.h | 5 |
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 |