author | pcpa <paulo.cesar.pereira.de.andrade@gmail.com> | 2023年01月20日 15:05:34 -0300 |
---|---|---|
committer | pcpa <paulo.cesar.pereira.de.andrade@gmail.com> | 2023年01月20日 15:05:34 -0300 |
commit | 7e919226dd8c8d6b74bcb9564dc2c6f8454ed2cb (patch) | |
tree | a5328e00d17e57a1f0458bc04be3aec9b6389013 | |
parent | 11ff6d4e62491732cb5f122b55de500cb056307b (diff) | |
download | lightning-7e919226dd8c8d6b74bcb9564dc2c6f8454ed2cb.tar.gz |
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | lib/jit_mips-cpu.c | 158 | ||||
-rw-r--r-- | lib/jit_mips.c | 246 | ||||
-rw-r--r-- | lib/jit_rewind.c | 7 |
@@ -1,3 +1,9 @@ +2023年01月20日 Paulo Andrade <pcpa@gnu.org> + + * lib/jit_mips-cpu.c, lib/jit_mips.c, lib/jit_rewind.c: Adapt + code to implement a variable framesize and optimize frame pointer + for simple leaf functions. + 2023年01月19日 Paulo Andrade <pcpa@gnu.org> * lib/jit_riscv.c, lib/jit_riscv-cpu.c: Adapt code to use a diff --git a/lib/jit_mips-cpu.c b/lib/jit_mips-cpu.c index 3e82524..f4472c7 100644 --- a/lib/jit_mips-cpu.c +++ b/lib/jit_mips-cpu.c @@ -91,18 +91,12 @@ typedef union { # define _F28_REGNO 28 # define _F30_REGNO 30 # if __WORDSIZE == 32 -# if NEW_ABI -# define stack_framesize 144 -# else -# define stack_framesize 112 -# endif # define ldr(u,v) ldr_i(u,v) # define ldi(u,v) ldi_i(u,v) # define ldxi(u,v,w) ldxi_i(u,v,w) # define sti(u,v) sti_i(u,v) # define stxi(u,v,w) stxi_i(u,v,w) # else -# define stack_framesize 144 # define ldr(u,v) ldr_l(u,v) # define ldi(u,v) ldi_l(u,v) # define ldxi(u,v,w) ldxi_l(u,v,w) @@ -2236,7 +2230,8 @@ static jit_bool_t _can_swap_ds(jit_state_t *_jit, jit_node_t *prev, { jit_int32_t offset; - if (!prev) + /* FIXME this fixes tramp.tst and ctramp.c tests */ + if (1||!prev) return 0; switch (prev->code) { @@ -3284,24 +3279,13 @@ _calli_p(jit_state_t *_jit, jit_word_t i0) return (word); } -static jit_int32_t fregs[] = { - _F30, _F28, _F26, _F24, _F22, _F20, -#if !NEW_ABI - _F18, _F16, -#endif -}; - -static jit_int32_t iregs[] = { - _S7, _S6, _S5, _S4, _S3, _S2, _S1, _S0, -}; - static void _prolog(jit_state_t *_jit, jit_node_t *node) { - jit_int32_t index; - jit_int32_t offset; + jit_int32_t reg, offs; if (_jitc->function->define_frame || _jitc->function->assume_frame) { jit_int32_t frame = -_jitc->function->frame; + CHECK_FRAME(); assert(_jitc->function->self.aoff >= frame); if (_jitc->function->assume_frame) return; @@ -3320,51 +3304,65 @@ _prolog(jit_state_t *_jit, jit_node_t *node) /* align stack at 8 bytes */ _jitc->function->self.aoff) + 7) & -8; #endif - /* callee save registers */ + #if NEW_ABI - if ((_jitc->function->self.call & jit_call_varargs) && - jit_arg_reg_p(_jitc->function->vagp)) - subi(_SP_REGNO, _SP_REGNO, stack_framesize + 64); - else + if (_jitc->function->stack) + _jitc->function->need_stack = 1; + if (!_jitc->function->need_frame && !_jitc->function->need_stack) { + /* check if any callee save register needs to be saved */ + for (reg = 0; reg < _jitc->reglen; ++reg) + if (jit_regset_tstbit(&_jitc->function->regset, reg) && + (_rvs[reg].spec & jit_class_sav)) { + _jitc->function->need_stack = 1; + break; + } + } +#else + /* Need always a frame due to the need to always allocate 16 bytes */ + CHECK_FRAME(); #endif - subi(_SP_REGNO, _SP_REGNO, stack_framesize); - offset = stack_framesize - (sizeof(jit_word_t) << 1); - for (index = 0; index < jit_size(fregs); index++, offset -= 8) { - if (jit_regset_tstbit(&_jitc->function->regset, fregs[index])) - stxi_d(offset, _SP_REGNO, rn(fregs[index])); - } - for (index = 0; index < jit_size(iregs); - index++, offset -= sizeof(jit_word_t)) { - if (jit_regset_tstbit(&_jitc->function->regset, iregs[index])) - stxi(offset, _SP_REGNO, rn(iregs[index])); - } - assert(offset >= sizeof(jit_word_t)); - stxi(offset, _SP_REGNO, _RA_REGNO); - stxi(0, _SP_REGNO, _BP_REGNO); - movr(_BP_REGNO, _SP_REGNO); + + if (_jitc->function->need_frame || _jitc->function->need_stack) + subi(_SP_REGNO, _SP_REGNO, FRAMESIZE()); + if (_jitc->function->need_frame) { + stxi(0, _SP_REGNO, _RA_REGNO); + stxi(STACK_SLOT, _SP_REGNO, _BP_REGNO); + } + /* callee save registers */ + for (reg = 0, offs = STACK_SLOT << 1; reg < jit_size(iregs); reg++) { + if (jit_regset_tstbit(&_jitc->function->regset, iregs[reg])) { + stxi(offs, _SP_REGNO, rn(iregs[reg])); + offs += STACK_SLOT; + } + } + for (reg = 0; reg < jit_size(fregs); reg++) { + if (jit_regset_tstbit(&_jitc->function->regset, fregs[reg])) { + stxi_d(offs, _SP_REGNO, rn(fregs[reg])); + offs += sizeof(jit_float64_t); + } + } + + if (_jitc->function->need_frame) + movr(_BP_REGNO, _SP_REGNO); /* alloca */ if (_jitc->function->stack) subi(_SP_REGNO, _SP_REGNO, _jitc->function->stack); if (_jitc->function->allocar) { - index = jit_get_reg(jit_class_gpr); - movi(rn(index), _jitc->function->self.aoff); - stxi_i(_jitc->function->aoffoff, _BP_REGNO, rn(index)); - jit_unget_reg(index); + reg = jit_get_reg(jit_class_gpr); + movi(rn(reg), _jitc->function->self.aoff); + stxi_i(_jitc->function->aoffoff, _BP_REGNO, rn(reg)); + jit_unget_reg(reg); } if (_jitc->function->self.call & jit_call_varargs) { + for (reg = _jitc->function->vagp; jit_arg_reg_p(reg); ++reg) { + offs = FRAMESIZE() - ((NUM_WORD_ARGS - reg) * STACK_SLOT); #if NEW_ABI - index = _jitc->function->vagp; -#else - index = (_jitc->function->self.size - stack_framesize) >> STACK_SHIFT; -#endif - offset = stack_framesize + index * STACK_SLOT; - for (; jit_arg_reg_p(index); ++index, offset += STACK_SLOT) { -#if NEW_ABI - SD(rn(_A0 - index), offset, _BP_REGNO); + SD(rn(_A0 - reg), offs, _BP_REGNO); #else - stxi(offset + WORD_ADJUST, _BP_REGNO, rn(_A0 - index)); + offs += 16 + WORD_ADJUST; + stxi(offs, _BP_REGNO, rn(_A0 - reg)); #endif } } @@ -3373,48 +3371,50 @@ _prolog(jit_state_t *_jit, jit_node_t *node) static void _epilog(jit_state_t *_jit, jit_node_t *node) { - jit_int32_t index; - jit_int32_t offset; + jit_int32_t reg, offs; if (_jitc->function->assume_frame) return; + + if (_jitc->function->need_frame) { + movr(_SP_REGNO, _BP_REGNO); + ldxi(_RA_REGNO, _SP_REGNO, 0); + ldxi(_BP_REGNO, _SP_REGNO, STACK_SLOT); + } + /* callee save registers */ - movr(_SP_REGNO, _BP_REGNO); - offset = stack_framesize - (sizeof(jit_word_t) << 1); - for (index = 0; index < jit_size(fregs); index++, offset -= 8) { - if (jit_regset_tstbit(&_jitc->function->regset, fregs[index])) - ldxi_d(rn(fregs[index]), _SP_REGNO, offset); - } - for (index = 0; index < jit_size(iregs); - index++, offset -= sizeof(jit_word_t)) { - if (jit_regset_tstbit(&_jitc->function->regset, iregs[index])) - ldxi(rn(iregs[index]), _SP_REGNO, offset); - } - assert(offset >= sizeof(jit_word_t)); - ldxi(_RA_REGNO, _SP_REGNO, offset); - ldxi(_BP_REGNO, _SP_REGNO, 0); + for (reg = 0, offs = STACK_SLOT << 1; reg < jit_size(iregs); reg++) { + if (jit_regset_tstbit(&_jitc->function->regset, iregs[reg])) { + ldxi(rn(iregs[reg]), _SP_REGNO, offs); + offs += sizeof(jit_word_t); + } + } + for (reg = 0; reg < jit_size(fregs); reg++) { + if (jit_regset_tstbit(&_jitc->function->regset, fregs[reg])) { + ldxi_d(rn(fregs[reg]), _SP_REGNO, offs); + offs += sizeof(jit_float64_t); + } + } JR(_RA_REGNO); /* delay slot */ -#if NEW_ABI - if ((_jitc->function->self.call & jit_call_varargs) && - jit_arg_reg_p(_jitc->function->vagp)) - addi(_SP_REGNO, _SP_REGNO, stack_framesize + 64); + if (_jitc->function->need_frame || _jitc->function->need_stack) + addi(_SP_REGNO, _SP_REGNO, FRAMESIZE()); else -#endif - addi(_SP_REGNO, _SP_REGNO, stack_framesize); + NOP(1); } static void _vastart(jit_state_t *_jit, jit_int32_t r0) { assert(_jitc->function->self.call & jit_call_varargs); - /* Initialize va_list to the first stack argument. */ #if NEW_ABI + /* Initialize va_list to the first stack argument. */ if (jit_arg_reg_p(_jitc->function->vagp)) - addi(r0, _BP_REGNO, stack_framesize + _jitc->function->vagp * - sizeof(jit_int64_t)); + addi(r0, _BP_REGNO, + FRAMESIZE() - + ((NUM_WORD_ARGS - _jitc->function->vagp) * STACK_SLOT)); else #endif - addi(r0, _BP_REGNO, _jitc->function->self.size); + addi(r0, _BP_REGNO, SELFSIZE()); } static void diff --git a/lib/jit_mips.c b/lib/jit_mips.c index 82c2f2b..7a59316 100644 --- a/lib/jit_mips.c +++ b/lib/jit_mips.c @@ -22,6 +22,32 @@ #endif #if NEW_ABI +/* callee save + variadic arguments + * align16(ra+fp+s[0-7]++f20+f22+f24+f26+f28+f30) + align16(a[0-7]) */ +# define stack_framesize (128 + 64) +#else +/* callee save + * align16(ra+fp+s[0-7]+f16+f18+f20+f22+f24+f26+f28+f30) */ +# define stack_framesize 128 +#endif +#define DIFFSIZE() (stack_framesize - _jitc->framesize) +#define FRAMESIZE() (stack_framesize - DIFFSIZE()) +#define SELFSIZE() (_jitc->function->self.size - DIFFSIZE()) +#define LINK_ALIST(node) \ + do { \ + node->link = _jitc->function->alist; \ + _jitc->function->alist = node; \ + } while (0) + +#define CHECK_FRAME() \ + do { \ + if (!_jitc->function->need_frame) { \ + _jitc->again = 1; \ + _jitc->function->need_frame = 1; \ + } \ + } while (0) + +#if NEW_ABI # define NUM_WORD_ARGS 8 # define STACK_SLOT 8 # define STACK_SHIFT 3 @@ -60,6 +86,10 @@ static jit_node_t *_jit_make_arg(jit_state_t*,jit_node_t*,jit_code_t); static jit_node_t *_jit_make_arg_f(jit_state_t*,jit_node_t*); #define jit_make_arg_d(node) _jit_make_arg_d(_jit,node) static jit_node_t *_jit_make_arg_d(jit_state_t*,jit_node_t*); +#define compute_framesize() _compute_framesize(_jit) +static void _compute_framesize(jit_state_t*); +#define patch_alist(revert) _patch_alist(_jit, revert) +static void _patch_alist(jit_state_t*, jit_bool_t); #define patch(instr, node) _patch(_jit, instr, node) static void _patch(jit_state_t*,jit_word_t,jit_node_t*); @@ -145,6 +175,17 @@ jit_register_t _rvs[] = { { _NOREG, "<none>" }, }; +static jit_int32_t iregs[] = { + _S0, _S1, _S2, _S3, _S4, _S5, _S6, _S7 +}; + +static jit_int32_t fregs[] = { +#if !NEW_ABI + _F16, _F18, +#endif + _F20, _F22, _F24, _F26, _F28, _F30 +}; + /* * Implementation */ @@ -211,6 +252,7 @@ jit_int32_t _jit_allocai(jit_state_t *_jit, jit_int32_t length) { assert(_jitc->function); + CHECK_FRAME(); switch (length) { case 0: case 1: break; case 2: _jitc->function->self.aoff &= -2; break; @@ -353,7 +395,7 @@ _jit_make_arg(jit_state_t *_jit, jit_node_t *node, jit_code_t code) } #else offset = (_jitc->function->self.size - stack_framesize) >> STACK_SHIFT; - _jitc->function->self.argi = 1; + ++_jitc->function->self.argi; if (offset >= 4) offset = _jitc->function->self.size; _jitc->function->self.size += STACK_SLOT; @@ -467,7 +509,6 @@ _jit_ellipsis(jit_state_t *_jit) else { assert(!(_jitc->function->self.call & jit_call_varargs)); #if NEW_ABI - /* If varargs start in a register, allocate extra 64 bytes. */ if (jit_arg_reg_p(_jitc->function->self.argi)) rewind_prolog(); /* Do not set during possible rewind. */ @@ -480,6 +521,7 @@ _jit_ellipsis(jit_state_t *_jit) _jitc->function->vagp = _jitc->function->self.argi; } jit_inc_synth(ellipsis); + CHECK_FRAME(); if (_jitc->prepare) jit_link_prepare(); else @@ -527,8 +569,11 @@ _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) jit_inc_synth_wp(getarg_c, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_c(u, _A0 - v->u.w); - else - jit_ldxi_c(u, _FP, v->u.w + C_DISP); + else { + jit_node_t *node = jit_ldxi_c(u, _FP, v->u.w + C_DISP); + LINK_ALIST(node); + CHECK_FRAME(); + } jit_dec_synth(); } @@ -539,8 +584,11 @@ _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) jit_inc_synth_wp(getarg_uc, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_uc(u, _A0 - v->u.w); - else - jit_ldxi_uc(u, _FP, v->u.w + C_DISP); + else { + jit_node_t *node = jit_ldxi_uc(u, _FP, v->u.w + C_DISP); + LINK_ALIST(node); + CHECK_FRAME(); + } jit_dec_synth(); } @@ -551,8 +599,11 @@ _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) jit_inc_synth_wp(getarg_s, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_s(u, _A0 - v->u.w); - else - jit_ldxi_s(u, _FP, v->u.w + S_DISP); + else { + jit_node_t *node = jit_ldxi_s(u, _FP, v->u.w + S_DISP); + LINK_ALIST(node); + CHECK_FRAME(); + } jit_dec_synth(); } @@ -563,8 +614,11 @@ _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) jit_inc_synth_wp(getarg_us, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_us(u, _A0 - v->u.w); - else - jit_ldxi_us(u, _FP, v->u.w + S_DISP); + else { + jit_node_t *node = jit_ldxi_us(u, _FP, v->u.w + S_DISP); + LINK_ALIST(node); + CHECK_FRAME(); + } jit_dec_synth(); } @@ -580,8 +634,11 @@ _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) jit_movr(u, _A0 - v->u.w); #endif } - else - jit_ldxi_i(u, _FP, v->u.w + I_DISP); + else { + jit_node_t *node = jit_ldxi_i(u, _FP, v->u.w + I_DISP); + LINK_ALIST(node); + CHECK_FRAME(); + } jit_dec_synth(); } @@ -593,8 +650,11 @@ _jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) jit_inc_synth_wp(getarg_ui, u, v); if (jit_arg_reg_p(v->u.w)) jit_extr_ui(u, _A0 - v->u.w); - else - jit_ldxi_ui(u, _FP, v->u.w + I_DISP); + else { + jit_node_t *node = jit_ldxi_ui(u, _FP, v->u.w + I_DISP); + LINK_ALIST(node); + CHECK_FRAME(); + } jit_dec_synth(); } @@ -605,8 +665,11 @@ _jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) jit_inc_synth_wp(getarg_l, u, v); if (jit_arg_reg_p(v->u.w)) jit_movr(u, _A0 - v->u.w); - else - jit_ldxi_l(u, _FP, v->u.w); + else { + jit_node_t *node = jit_ldxi_l(u, _FP, v->u.w); + LINK_ALIST(node); + CHECK_FRAME(); + } jit_dec_synth(); } #endif @@ -618,8 +681,11 @@ _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v, jit_code_t code) jit_code_inc_synth_wp(code, u, v); if (jit_arg_reg_p(v->u.w)) jit_movr(_A0 - v->u.w, u); - else - jit_stxi(v->u.w + WORD_ADJUST, _FP, u); + else { + jit_node_t *node = jit_stxi(v->u.w + WORD_ADJUST, _FP, u); + LINK_ALIST(node); + CHECK_FRAME(); + } jit_dec_synth(); } @@ -632,9 +698,12 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v, jit_code_t code) if (jit_arg_reg_p(v->u.w)) jit_movi(_A0 - v->u.w, u); else { + jit_node_t *node; regno = jit_get_reg(jit_class_gpr); jit_movi(regno, u); - jit_stxi(v->u.w + WORD_ADJUST, _FP, regno); + node = jit_stxi(v->u.w + WORD_ADJUST, _FP, regno); + LINK_ALIST(node); + CHECK_FRAME(); jit_unget_reg(regno); } jit_dec_synth(); @@ -656,8 +725,11 @@ _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) else if (v->u.w < 8) jit_movr_f(u, _F12 - ((v->u.w - 4) >> 1)); #endif - else - jit_ldxi_f(u, _FP, v->u.w); + else { + jit_node_t *node = jit_ldxi_f(u, _FP, v->u.w); + LINK_ALIST(node); + CHECK_FRAME(); + } jit_dec_synth(); } @@ -677,8 +749,11 @@ _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) else if (v->u.w < 8) jit_movr_f(_F12 - ((v->u.w - 4) >> 1), u); #endif - else - jit_stxi_f(v->u.w, _FP, u); + else { + jit_node_t *node = jit_stxi_f(v->u.w, _FP, u); + LINK_ALIST(node); + CHECK_FRAME(); + } jit_dec_synth(); } @@ -704,9 +779,12 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v) jit_movi_f(_F12 - ((v->u.w - 4) >> 1), u); #endif else { + jit_node_t *node; regno = jit_get_reg(jit_class_fpr); jit_movi_f(regno, u); - jit_stxi_f(v->u.w, _FP, regno); + node = jit_stxi_f(v->u.w, _FP, regno); + LINK_ALIST(node); + CHECK_FRAME(); jit_unget_reg(regno); } jit_dec_synth(); @@ -728,8 +806,11 @@ _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) else if (v->u.w < 8) jit_movr_d(u, _F12 - ((v->u.w - 4) >> 1)); #endif - else - jit_ldxi_d(u, _FP, v->u.w); + else { + jit_node_t *node = jit_ldxi_d(u, _FP, v->u.w); + LINK_ALIST(node); + CHECK_FRAME(); + } jit_dec_synth(); } @@ -749,8 +830,11 @@ _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) else if (v->u.w < 8) jit_movr_d(_F12 - ((v->u.w - 4) >> 1), u); #endif - else - jit_stxi_d(v->u.w, _FP, u); + else { + jit_node_t *node = jit_stxi_d(v->u.w, _FP, u); + LINK_ALIST(node); + CHECK_FRAME(); + } jit_dec_synth(); } @@ -776,9 +860,12 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v) jit_movi_d(_F12 - ((v->u.w - 4) >> 1), u); #endif else { + jit_node_t *node; regno = jit_get_reg(jit_class_fpr); jit_movi_d(regno, u); - jit_stxi_d(v->u.w, _FP, regno); + node = jit_stxi_d(v->u.w, _FP, regno); + LINK_ALIST(node); + CHECK_FRAME(); jit_unget_reg(regno); } jit_dec_synth(); @@ -796,6 +883,7 @@ _jit_pushargr(jit_state_t *_jit, jit_int32_t u, jit_code_t code) ++_jitc->function->call.argi; } else { + CHECK_FRAME(); jit_stxi(_jitc->function->call.size + WORD_ADJUST, JIT_SP, u); _jitc->function->call.size += STACK_SLOT; } @@ -803,11 +891,13 @@ _jit_pushargr(jit_state_t *_jit, jit_int32_t u, jit_code_t code) jit_word_t offset; assert(_jitc->function); offset = _jitc->function->call.size >> STACK_SHIFT; - _jitc->function->call.argi = 1; + ++_jitc->function->call.argi; if (jit_arg_reg_p(offset)) jit_movr(_A0 - offset, u); - else + else { + CHECK_FRAME(); jit_stxi(_jitc->function->call.size, JIT_SP, u); + } _jitc->function->call.size += STACK_SLOT; #endif jit_dec_synth(); @@ -829,6 +919,7 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u, jit_code_t code) ++_jitc->function->call.argi; } else { + CHECK_FRAME(); regno = jit_get_reg(jit_class_gpr); jit_movi(regno, u); jit_stxi(_jitc->function->call.size + WORD_ADJUST, JIT_SP, regno); @@ -841,6 +932,7 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u, jit_code_t code) if (jit_arg_reg_p(offset)) jit_movi(_A0 - offset, u); else { + CHECK_FRAME(); regno = jit_get_reg(jit_class_gpr); jit_movi(regno, u); jit_stxi(_jitc->function->call.size, JIT_SP, regno); @@ -869,6 +961,7 @@ _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) ++_jitc->function->call.argi; } else { + CHECK_FRAME(); jit_stxi_f(_jitc->function->call.size, JIT_SP, u); _jitc->function->call.size += STACK_SLOT; } @@ -883,8 +976,10 @@ _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) ++_jitc->function->call.argi; jit_movr_f_w(_A0 - offset, u); } - else + else { + CHECK_FRAME(); jit_stxi_f(_jitc->function->call.size, JIT_SP, u); + } _jitc->function->call.size += STACK_SLOT; #endif jit_dec_synth(); @@ -909,6 +1004,7 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) ++_jitc->function->call.argi; } else { + CHECK_FRAME(); regno = jit_get_reg(jit_class_fpr); jit_movi_f(regno, u); jit_stxi_f(_jitc->function->call.size, JIT_SP, regno); @@ -927,6 +1023,7 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) jit_movi_f_w(_A0 - offset, u); } else { + CHECK_FRAME(); regno = jit_get_reg(jit_class_fpr); jit_movi_f(regno, u); jit_stxi_f(_jitc->function->call.size, JIT_SP, regno); @@ -956,6 +1053,7 @@ _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) ++_jitc->function->call.argi; } else { + CHECK_FRAME(); jit_stxi_d(_jitc->function->call.size, JIT_SP, u); _jitc->function->call.size += STACK_SLOT; } @@ -976,8 +1074,10 @@ _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) ++_jitc->function->call.argf; } } - else + else { + CHECK_FRAME(); jit_stxi_d(_jitc->function->call.size, JIT_SP, u); + } _jitc->function->call.size += sizeof(jit_float64_t); #endif jit_dec_synth(); @@ -1003,6 +1103,7 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) ++_jitc->function->call.argi; } else { + CHECK_FRAME(); regno = jit_get_reg(jit_class_fpr); jit_movi_d(regno, u); jit_stxi_d(_jitc->function->call.size, JIT_SP, regno); @@ -1027,6 +1128,7 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) } } else { + CHECK_FRAME(); regno = jit_get_reg(jit_class_fpr); jit_movi_d(regno, u); jit_stxi_d(_jitc->function->call.size, JIT_SP, regno); @@ -1064,6 +1166,7 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0) { jit_node_t *call; assert(_jitc->function); + CHECK_FRAME(); jit_inc_synth_w(finishr, r0); if (_jitc->function->self.alen < _jitc->function->call.size) _jitc->function->self.alen = _jitc->function->call.size; @@ -1086,6 +1189,7 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0) jit_node_t *call; jit_node_t *node; assert(_jitc->function); + CHECK_FRAME(); jit_inc_synth_w(finishi, (jit_word_t)i0); if (_jitc->function->self.alen < _jitc->function->call.size) _jitc->function->self.alen = _jitc->function->call.size; @@ -1717,6 +1821,7 @@ _emit_code(jit_state_t *_jit) case_brr(bunord, _d); case_brf(bunord, _d, 64); case jit_code_jmpr: + CHECK_FRAME(); jmpr(rn(node->u.w), prev); break; case jit_code_jmpi: @@ -1731,10 +1836,13 @@ _emit_code(jit_state_t *_jit) patch(word, node); } } - else + else { + CHECK_FRAME(); jmpi(node->u.w, prev); + } break; case jit_code_callr: + CHECK_FRAME(); callr(rn(node->u.w), prev); break; case jit_code_calli: @@ -1749,8 +1857,10 @@ _emit_code(jit_state_t *_jit) patch(word, node); } } - else + else { + CHECK_FRAME(); calli(node->u.w); + } break; case jit_code_prolog: _jitc->function = _jitc->functions.ptr + node->w.w; @@ -1763,6 +1873,8 @@ _emit_code(jit_state_t *_jit) undo.patch_offset = _jitc->patches.offset; restart_function: _jitc->again = 0; + compute_framesize(); + patch_alist(0); prolog(node); break; case jit_code_epilog: @@ -1782,15 +1894,20 @@ _emit_code(jit_state_t *_jit) * the reason of the undo. */ undo.func.self.aoff = _jitc->function->frame + _jitc->function->self.aoff; + undo.func.need_frame = _jitc->function->need_frame; jit_regset_set(&undo.func.regset, &_jitc->function->regset); /* allocar information also does not need to be undone */ undo.func.aoffoff = _jitc->function->aoffoff; undo.func.allocar = _jitc->function->allocar; + /* this will be recomputed but undo anyway to have it + * better self documented.*/ + undo.func.need_stack = _jitc->function->need_stack; memcpy(_jitc->function, &undo.func, sizeof(undo.func)); #if DEVEL_DISASSEMBLER prevw = undo.prevw; #endif _jitc->patches.offset = undo.patch_offset; + patch_alist(1); goto restart_function; } /* remember label is defined */ @@ -1998,6 +2115,65 @@ _emit_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1) } static void +_compute_framesize(jit_state_t *_jit) +{ + jit_int32_t reg; + /* Save stack pointer in first slot */ + _jitc->framesize = STACK_SLOT << 1; /* ra+fp */ + for (reg = 0; reg < jit_size(iregs); reg++) + if (jit_regset_tstbit(&_jitc->function->regset, iregs[reg])) + _jitc->framesize += STACK_SLOT; + + for (reg = 0; reg < jit_size(fregs); reg++) + if (jit_regset_tstbit(&_jitc->function->regset, fregs[reg])) + _jitc->framesize += sizeof(jit_float64_t); + +#if NEW_ABI + /* Space to store variadic arguments */ + if (_jitc->function->self.call & jit_call_varargs) + _jitc->framesize += (NUM_WORD_ARGS - _jitc->function->vagp) * STACK_SLOT; +#endif + + /* Make sure functions called have a 16 byte aligned stack */ + _jitc->framesize = (_jitc->framesize + 15) & -16; +} + +static void +_patch_alist(jit_state_t *_jit, jit_bool_t revert) +{ + jit_int32_t diff; + jit_node_t *node; + diff = DIFFSIZE(); + if (diff) { + if (revert) + diff = -diff; + for (node = _jitc->function->alist; node; node = node->link) { + switch (node->code) { + case jit_code_ldxi_c: case jit_code_ldxi_uc: + case jit_code_ldxi_s: case jit_code_ldxi_us: + case jit_code_ldxi_i: +#if __WORDSIZE == 64 + case jit_code_ldxi_ui: case jit_code_ldxi_l: +#endif + case jit_code_ldxi_f: case jit_code_ldxi_d: + node->w.w -= diff; + break; + case jit_code_stxi_c: case jit_code_stxi_s: + case jit_code_stxi_i: +#if __WORDSIZE == 64 + case jit_code_stxi_l: +#endif + case jit_code_stxi_f: case jit_code_stxi_d: + node->u.w -= diff; + break; + default: + abort(); + } + } + } +} + +static void _patch(jit_state_t *_jit, jit_word_t instr, jit_node_t *node) { jit_int32_t flag; diff --git a/lib/jit_rewind.c b/lib/jit_rewind.c index e92737d..5db34e8 100644 --- a/lib/jit_rewind.c +++ b/lib/jit_rewind.c @@ -56,11 +56,8 @@ _rewind_prolog(jit_state_t *_jit) assert(jit_cpu.abi); _jitc->function->self.size += 64; #endif -#if __mips__ && NEW_ABI - /* Only add extra stack space if there are varargs - * arguments in registers. */ - assert(jit_arg_reg_p(_jitc->function->self.argi)); - _jitc->function->self.size += 64; +#if __mips__ + _jitc->function->alist = NULL; #endif _jitc->function->self.argi = _jitc->function->self.argf = _jitc->function->self.argn = 0; |