diff --git a/ChangeLog b/ChangeLog index 898caa9de..479d99e72 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2012-12-20 Paulo Andrade + + * include/lightning/jit_ppc.h: Correct mismatch of JIT_F{1,5} + with enum codes, that were correct, and returned by jit_f(). + + * lib/jit_ppc-cpu.c, lib/jit_ppc-fpu.c, lib/jit_ppc.c: Properly + implement and better describe values when generating stack + frames. + 2012-12-18 Paulo Andrade * check/stack.ok, check/stack.tst: New files to test data diff --git a/include/lightning/jit_ppc.h b/include/lightning/jit_ppc.h index d42b8cc55..ee076480f 100644 --- a/include/lightning/jit_ppc.h +++ b/include/lightning/jit_ppc.h @@ -74,11 +74,11 @@ typedef enum { #define JIT_RA7 _R10 _R10, _R9, _R8, _R7, _R6, _R5, _R4, _R3, # define JIT_F0 _F0 -# define JIT_F1 _F8 -# define JIT_F2 _F9 -# define JIT_F3 _F10 -# define JIT_F4 _F11 -# define JIT_F5 _F12 +# define JIT_F1 _F9 +# define JIT_F2 _F10 +# define JIT_F3 _F11 +# define JIT_F4 _F12 +# define JIT_F5 _F13 _F0, _F9, _F10, _F11, _F12, _F13, #define JIT_FS0 _F14 #define JIT_FS1 _F15 diff --git a/lib/jit_ppc-cpu.c b/lib/jit_ppc-cpu.c index 0f9b34348..868fcc1fa 100644 --- a/lib/jit_ppc-cpu.c +++ b/lib/jit_ppc-cpu.c @@ -16,7 +16,11 @@ */ #if PROTO -# define stack_framesize 80 +# define gpr_save_area 72 /* r14~r31 = 18 * 4 */ +# define fpr_save_area 0 /* FIXME extra fpr registers + * not used */ +# define alloca_offset -(gpr_save_area + fpr_save_area) +# define params_offset 56 # define ii(i) *_jit->pc.ui++ = i # define can_sign_extend_short_p(im) ((im) >= -32768 && (im) <= 32767) # define can_zero_extend_short_p(im) ((im) >= 0 && (im) <= 65535) @@ -2363,7 +2367,7 @@ _prolog(jit_state_t *_jit, jit_node_t *node) { unsigned long regno; - _jit->function->stack = ((_jit->function->self.alen - + _jit->function->stack = ((_jit->function->self.alen + params_offset - _jit->function->self.aoff) + 15) & -16; /* return address */ @@ -2376,8 +2380,12 @@ _prolog(jit_state_t *_jit, jit_node_t *node) STMW(rn(regno), _SP_REGNO, -(32 * 4) + rn(regno) * 4); stxi(8, _SP_REGNO, _R0_REGNO); - STWU(_SP_REGNO, _SP_REGNO, -(stack_framesize + _jit->function->stack + 16)); - addi(_FP_REGNO, _SP_REGNO, _jit->function->stack + 16); + + /* params >= %r31+56 + * alloca < %r31-80 */ + movr(_FP_REGNO, _SP_REGNO); + + STWU(_SP_REGNO, _SP_REGNO, -_jit->function->stack); } static void @@ -2385,7 +2393,6 @@ _epilog(jit_state_t *_jit, jit_node_t *node) { unsigned long regno; - //ldxi(_SP_REGNO, _SP_REGNO, 0); LWZ(_SP_REGNO, _SP_REGNO, 0); ldxi(_R0_REGNO, _SP_REGNO, 8); diff --git a/lib/jit_ppc-fpu.c b/lib/jit_ppc-fpu.c index d22d5870b..bb4964180 100644 --- a/lib/jit_ppc-fpu.c +++ b/lib/jit_ppc-fpu.c @@ -440,10 +440,10 @@ _extr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) reg = jit_get_reg(jit_class_gpr); rshi(rn(reg), r1, 31); /* use reserved 8 bytes area */ - stxi(-4, _FP_REGNO, r1); - stxi(-8, _FP_REGNO, rn(reg)); + stxi(alloca_offset - 4, _FP_REGNO, r1); + stxi(alloca_offset - 8, _FP_REGNO, rn(reg)); jit_unget_reg(reg); - ldxi_d(r0, _FP_REGNO, -8); + ldxi_d(r0, _FP_REGNO, alloca_offset - 8); FCFID(r0, r0); } @@ -454,8 +454,8 @@ _truncr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) reg = jit_get_reg(jit_class_fpr); FCTIWZ(rn(reg), r1); /* use reserved 8 bytes area */ - stxi_d(-8, _FP_REGNO, rn(reg)); - ldxi(r0, _FP_REGNO, -4); + stxi_d(alloca_offset - 8, _FP_REGNO, rn(reg)); + ldxi(r0, _FP_REGNO, alloca_offset - 4); jit_unget_reg(reg); } diff --git a/lib/jit_ppc.c b/lib/jit_ppc.c index 9fdc10d29..ddb6ad019 100644 --- a/lib/jit_ppc.c +++ b/lib/jit_ppc.c @@ -136,11 +136,11 @@ _jit_prolog(jit_state_t *_jit) _jit->functions.length += 16; } _jit->function = _jit->functions.ptr + _jit->functions.offset++; - _jit->function->self.size = stack_framesize; + _jit->function->self.size = params_offset; _jit->function->self.argi = _jit->function->self.argf = - _jit->function->self.aoff = _jit->function->self.alen = 0; + _jit->function->self.alen = 0; /* float conversion */ - _jit->function->self.aoff = -8; + _jit->function->self.aoff = alloca_offset - 8; _jit->function->self.call = jit_call_default; _jit->function->regoff = calloc(_jit->reglen, sizeof(jit_int32_t)); @@ -372,9 +372,7 @@ _jit_pushargr(jit_state_t *_jit, jit_int32_t u) ++_jit->function->call.argi; } else { - if (!_jit->function->call.size) - _jit->function->call.size = 56; - jit_stxi(_jit->function->call.size, JIT_SP, u); + jit_stxi(_jit->function->call.size + params_offset, JIT_SP, u); _jit->function->call.size += sizeof(jit_word_t); } } @@ -389,11 +387,9 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u) ++_jit->function->call.argi; } else { - if (!_jit->function->call.size) - _jit->function->call.size = 56; regno = jit_get_reg(jit_class_gpr); jit_movi(regno, u); - jit_stxi(_jit->function->call.size, JIT_SP, regno); + jit_stxi(_jit->function->call.size + params_offset, JIT_SP, regno); _jit->function->call.size += sizeof(jit_word_t); jit_unget_reg(regno); } @@ -418,20 +414,24 @@ _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) if (_jit->function->call.argf < 8) { jit_movr_d(JIT_FA0 - _jit->function->call.argf, u); ++_jit->function->call.argf; - if (!(_jit->function->call.call & jit_call_varargs)) + if (!(_jit->function->call.call & jit_call_varargs)) { + /* in case of excess arguments */ + ++_jit->function->call.argi; return; + } } if (_jit->function->call.argi < 8) { - jit_stxi_d(-8, JIT_FP, u); - jit_ldxi(JIT_RA0 - _jit->function->call.argi, JIT_FP, -8); + /* use reserved 8 bytes area */ + jit_stxi_d(alloca_offset - 8, JIT_FP, u); + jit_ldxi(JIT_RA0 - _jit->function->call.argi, JIT_FP, + alloca_offset - 8); _jit->function->call.argi++; - jit_ldxi(JIT_RA0 - _jit->function->call.argi, JIT_FP, -4); + jit_ldxi(JIT_RA0 - _jit->function->call.argi, JIT_FP, + alloca_offset - 4); _jit->function->call.argi++; } else { - if (!_jit->function->call.size) - _jit->function->call.size = 56; - jit_stxi_d(_jit->function->call.size, JIT_SP, u); + jit_stxi_d(_jit->function->call.size + params_offset, JIT_SP, u); _jit->function->call.size += sizeof(jit_float64_t); } } @@ -445,22 +445,26 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) if (_jit->function->call.argf < 8) { jit_movi_d(JIT_FA0 - _jit->function->call.argf, u); ++_jit->function->call.argf; - if (!(_jit->function->call.call & jit_call_varargs)) + if (!(_jit->function->call.call & jit_call_varargs)) { + /* in case of excess arguments */ + ++_jit->function->call.argi; return; + } } regno = jit_get_reg(jit_class_fpr); jit_movi_d(regno, u); if (_jit->function->call.argi < 8) { - jit_stxi_d(-8, JIT_FP, regno); - jit_ldxi(JIT_RA0 - _jit->function->call.argi, JIT_FP, -8); + /* use reserved 8 bytes area */ + jit_stxi_d(alloca_offset - 8, JIT_FP, regno); + jit_ldxi(JIT_RA0 - _jit->function->call.argi, JIT_FP, + alloca_offset - 8); _jit->function->call.argi++; - jit_ldxi(JIT_RA0 - _jit->function->call.argi, JIT_FP, -4); + jit_ldxi(JIT_RA0 - _jit->function->call.argi, JIT_FP, + alloca_offset - 4); _jit->function->call.argi++; } else { - if (!_jit->function->call.size) - _jit->function->call.size = 56; - jit_stxi_d(_jit->function->call.size, JIT_SP, regno); + jit_stxi_d(_jit->function->call.size + params_offset, JIT_SP, regno); _jit->function->call.size += sizeof(jit_float64_t); } jit_unget_reg(regno); @@ -496,8 +500,7 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0) call = jit_callr(r0); call->v.w = _jit->function->call.argi; call->w.w = _jit->function->call.argf; - _jit->function->call.argi = _jit->function->call.argf = - _jit->function->call.size = 0; + _jit->function->call.argi = _jit->function->call.argf = 0; _jit->prepare = 0; } @@ -511,8 +514,7 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0) node = jit_calli(i0); node->v.w = _jit->function->call.argi; node->w.w = _jit->function->call.argf; - _jit->function->call.argi = _jit->function->call.argf = - _jit->function->call.size = 0; + _jit->function->call.argi = _jit->function->call.argf = 0; _jit->prepare = 0; return (node); }