diff --git a/ChangeLog b/ChangeLog index 0af9b4673..0d3dece39 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2015-07-03 Paulo Andrade + + * lib/jit_mips-cpu.c: Correct definition of htonr_ul. + Correct prolog/epilog/va* routines to work on o64 abi. + + * lib/jit_mips-fpu.c: Correct load of double literal + argument when not using a data buffer. + Remove alignment correction in vaarg_d if using the + new mips abi. + + * lib/jit_mips.c: Correct code to allow creating variadic + jit functions when using the new mips abi. + + * lib/jit_rewind.c: Minor adjust for rewind when using + the new mips abi, if there are varargs arguments in + registers. + 2015-06-06 Paulo Andrade * lib/jit_ia64-cpu.c: Search backward for the last output diff --git a/lib/jit_mips-cpu.c b/lib/jit_mips-cpu.c index f9a256862..37687f36a 100644 --- a/lib/jit_mips-cpu.c +++ b/lib/jit_mips-cpu.c @@ -1716,7 +1716,7 @@ _htonr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) } static void -_htonr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) +_htonr_ul(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) { jit_int32_t reg; reg = jit_get_reg(jit_class_gpr); @@ -2929,7 +2929,13 @@ _prolog(jit_state_t *_jit, jit_node_t *node) _jitc->function->self.aoff) + 7) & -8; #endif /* callee save registers */ - subi(_SP_REGNO, _SP_REGNO, stack_framesize); +#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 +#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])) @@ -2956,10 +2962,14 @@ _prolog(jit_state_t *_jit, jit_node_t *node) } if (_jitc->function->self.call & jit_call_varargs) { +#if NEW_ABI + index = _jitc->function->vagp; +#else index = (_jitc->function->self.size - stack_framesize) >> STACK_SHIFT; - offset = stack_framesize + index * sizeof(jit_word_t); - for (; jit_arg_reg_p(index); ++index, offset += sizeof(jit_word_t)) - stxi(offset, _BP_REGNO, rn(_A0 - index)); +#endif + offset = stack_framesize + index * STACK_SLOT; + for (; jit_arg_reg_p(index); ++index, offset += STACK_SLOT) + stxi(offset + WORD_ADJUST, _BP_REGNO, rn(_A0 - index)); } } @@ -2987,7 +2997,13 @@ _epilog(jit_state_t *_jit, jit_node_t *node) ldxi(_BP_REGNO, _SP_REGNO, 0); JR(_RA_REGNO); /* delay slot */ - addi(_SP_REGNO, _SP_REGNO, stack_framesize); +#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); + else +#endif + addi(_SP_REGNO, _SP_REGNO, stack_framesize); } static void @@ -2995,17 +3011,27 @@ _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. */ - addi(r0, _BP_REGNO, _jitc->function->self.size); +#if NEW_ABI + if (jit_arg_reg_p(_jitc->function->vagp)) + addi(r0, _BP_REGNO, stack_framesize + _jitc->function->vagp * + sizeof(jit_word_t)); + else +#endif + addi(r0, _BP_REGNO, _jitc->function->self.size); } static void _vaarg(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) { /* Load argument. */ +#if WORD_ADJUST + ldxi(r0, r1, WORD_ADJUST); +#else ldr(r0, r1); +#endif /* Update va_list. */ - addi(r1, r1, sizeof(jit_word_t)); + addi(r1, r1, STACK_SLOT); } static void diff --git a/lib/jit_mips-fpu.c b/lib/jit_mips-fpu.c index e995985a3..f91a6e636 100644 --- a/lib/jit_mips-fpu.c +++ b/lib/jit_mips-fpu.c @@ -217,9 +217,7 @@ static void _divi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*); # define negr_d(r0,r1) NEG_D(r0,r1) # define sqrtr_f(r0,r1) SQRT_S(r0,r1) # define sqrtr_d(r0,r1) SQRT_D(r0,r1) -# if !NEW_ABI -# define movr_w_f(r0, r1) MTC1(r1, r0) -# endif +# define movr_w_f(r0, r1) MTC1(r1, r0) # define movr_f_w(r0, r1) MFC1(r1, r0) # define movi_f_w(r0, i0) _movi_f_w(_jit, r0, i0) static void _movi_f_w(jit_state_t*,jit_int32_t,jit_float32_t*); @@ -251,6 +249,7 @@ static void _movr_f(jit_state_t*,jit_int32_t,jit_int32_t); # define movi_f(r0, i0) _movi_f(_jit, r0, i0) static void _movi_f(jit_state_t*,jit_int32_t,jit_float32_t*); # if NEW_ABI +# define movr_w_d(r0, r1) DMTC1(r1, r0) # define movr_d_w(r0, r1) DMFC1(r0, r1) # define movi_d_w(r0, i0) _movi_d_w(_jit,r0,i0) static void _movi_d_w(jit_state_t*,jit_int32_t,jit_float64_t*); @@ -764,12 +763,22 @@ static void _movi_d_w(jit_state_t *_jit, jit_int32_t r0, jit_float64_t *i0) { jit_word_t w; - w = (jit_word_t)i0; - if (can_sign_extend_short_p(w)) - LD(r0, w, _ZERO_REGNO); + union { + jit_word_t w; + jit_float64_t d; + } data; + if (_jitc->no_data) { + data.d = *i0; + movi(r0, data.w); + } else { - movi(r0, w); - LD(r0, 0, r0); + w = (jit_word_t)i0; + if (can_sign_extend_short_p(w)) + LD(r0, w, _ZERO_REGNO); + else { + movi(r0, w); + LD(r0, 0, r0); + } } } @@ -1780,13 +1789,17 @@ dbopi(unord) static void _vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1) { +#if !NEW_ABI jit_int32_t reg; +#endif assert(_jitc->function->self.call & jit_call_varargs); +#if !NEW_ABI /* Align, if required. */ reg = jit_get_reg(jit_class_gpr); andi(rn(reg), r1, 7); addr(r1, r1, rn(reg)); jit_unget_reg(reg); +#endif /* Load argument. */ ldr_d(r0, r1); diff --git a/lib/jit_mips.c b/lib/jit_mips.c index eac92a014..7b4b41228 100644 --- a/lib/jit_mips.c +++ b/lib/jit_mips.c @@ -380,8 +380,11 @@ _jit_make_arg_f(jit_state_t *_jit, jit_node_t *node) { jit_int32_t offset; #if NEW_ABI - if (jit_arg_reg_p(_jitc->function->self.argi)) + if (jit_arg_reg_p(_jitc->function->self.argi)) { offset = _jitc->function->self.argi++; + if (_jitc->function->self.call & jit_call_varargs) + offset += 8; + } else { offset = _jitc->function->self.size; _jitc->function->self.size += STACK_SLOT; @@ -420,8 +423,11 @@ _jit_make_arg_d(jit_state_t *_jit, jit_node_t *node) { jit_int32_t offset; #if NEW_ABI - if (jit_arg_reg_p(_jitc->function->self.argi)) + if (jit_arg_reg_p(_jitc->function->self.argi)) { offset = _jitc->function->self.argi++; + if (_jitc->function->self.call & jit_call_varargs) + offset += 8; + } else { offset = _jitc->function->self.size; _jitc->function->self.size += STACK_SLOT; @@ -460,14 +466,25 @@ _jit_ellipsis(jit_state_t *_jit) if (_jitc->prepare) { assert(!(_jitc->function->call.call & jit_call_varargs)); _jitc->function->call.call |= jit_call_varargs; +#if !NEW_ABI if (_jitc->function->call.argf) rewind_prepare(); +#endif } 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. */ + _jitc->function->self.call |= jit_call_varargs; +#else _jitc->function->self.call |= jit_call_varargs; if (_jitc->function->self.argf) rewind_prolog(); +#endif + _jitc->function->vagp = _jitc->function->self.argi; } jit_inc_synth(ellipsis); if (_jitc->prepare) @@ -626,6 +643,8 @@ _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) #if NEW_ABI if (jit_arg_reg_p(v->u.w)) jit_movr_f(u, _F12 - v->u.w); + else if (jit_arg_reg_p(v->u.w - 8)) + jit_movr_w_f(u, _A0 - v->u.w - 8); #else if (v->u.w < 4) jit_movr_w_f(u, _A0 - v->u.w); @@ -645,6 +664,8 @@ _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) #if NEW_ABI if (jit_arg_reg_p(v->u.w)) jit_movr_f(_F12 - v->u.w, u); + else if (jit_arg_reg_p(v->u.w - 8)) + jit_movr_f_w(_A0 - v->u.w - 8, u); #else if (v->u.w < 4) jit_movr_f_w(_A0 - v->u.w, u); @@ -665,6 +686,12 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v) #if NEW_ABI if (jit_arg_reg_p(v->u.w)) jit_movi_f(_F12 - v->u.w, u); + else if (jit_arg_reg_p(v->u.w - 8)) { + regno = jit_get_reg(jit_class_fpr); + jit_movi_f(regno, u); + jit_movr_f_w(_A0 - v->u.w - 8, u); + jit_unget_reg(regno); + } #else if (v->u.w < 4) { regno = jit_get_reg(jit_class_fpr); @@ -692,6 +719,8 @@ _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) #if NEW_ABI if (jit_arg_reg_p(v->u.w)) jit_movr_d(u, _F12 - v->u.w); + else if (jit_arg_reg_p(v->u.w - 8)) + jit_movr_d_w(_A0 - v->u.w - 8, u); #else if (v->u.w < 4) jit_movr_ww_d(u, _A0 - v->u.w, _A0 - (v->u.w + 1)); @@ -711,6 +740,8 @@ _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) #if NEW_ABI if (jit_arg_reg_p(v->u.w)) jit_movr_d(_F12 - v->u.w, u); + else if (jit_arg_reg_p(v->u.w - 8)) + jit_movr_d_w(_A0 - v->u.w - 8, u); #else if (v->u.w < 4) jit_movr_d_ww(_A0 - v->u.w, _A0 - (v->u.w + 1), u); @@ -731,6 +762,12 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v) #if NEW_ABI if (jit_arg_reg_p(v->u.w)) jit_movi_d(_F12 - v->u.w, u); + else if (jit_arg_reg_p(v->u.w - 8)) { + regno = jit_get_reg(jit_class_fpr); + jit_movi_d(regno, u); + jit_movr_d_w(_A0 - v->u.w - 8, u); + jit_unget_reg(regno); + } #else if (v->u.w < 4) { regno = jit_get_reg(jit_class_fpr); @@ -1053,7 +1090,7 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0) jit_node_t *call; jit_node_t *node; assert(_jitc->function); - jit_inc_synth_w(finishr, (jit_word_t)i0); + 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; node = jit_movi(_T9, (jit_word_t)i0); diff --git a/lib/jit_rewind.c b/lib/jit_rewind.c index f796d0fad..57f6ea863 100644 --- a/lib/jit_rewind.c +++ b/lib/jit_rewind.c @@ -55,6 +55,12 @@ _rewind_prolog(jit_state_t *_jit) #if __arm__ 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; #endif _jitc->function->self.argi = _jitc->function->self.argf = _jitc->function->self.argn = 0;