From 9fc57302f88a31ff7a42caf161ebcf7b07243a98 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Sun, 2 Feb 2014 20:29:24 +0800 Subject: [PATCH] Switch float abi to softfp for int <--> float conv This improves commit 5cbe03b9c47e676e045b4978c384087433bd6042 by avoiding a double transfer when the default float ABI is already softfp. It's also more clean by expliciting that the ABI is simply changed for runtime ABI functions. --- arm-gen.c | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/arm-gen.c b/arm-gen.c index c746e91..4465043 100644 --- a/arm-gen.c +++ b/arm-gen.c @@ -923,7 +923,7 @@ struct plan { definition of union reg_class). nb_args: number of parameters of the function for which a call is generated - corefloat: whether to pass float via core registers or not + float_abi: float ABI in use for this function call plan: the structure where the overall assignment is recorded todo: a bitmap that record which core registers hold a parameter @@ -932,7 +932,7 @@ struct plan { Note: this function allocated an array in plan->pplans with tcc_malloc. It is the responsability of the caller to free this array once used (ie not before copy_params). */ -static int assign_regs(int nb_args, int corefloat, struct plan *plan, int *todo) +static int assign_regs(int nb_args, int float_abi, struct plan *plan, int *todo) { int i, size, align; int ncrn /* next core register number */, nsaa /* next stacked argument address*/; @@ -952,7 +952,7 @@ static int assign_regs(int nb_args, int corefloat, struct plan *plan, int *todo) case VT_FLOAT: case VT_DOUBLE: case VT_LDOUBLE: - if (!corefloat) { + if (float_abi == ARM_HARD_FLOAT) { int is_hfa = 0; /* Homogeneous float aggregate */ if (is_float(vtop[-i].type.t) @@ -1183,14 +1183,15 @@ static int copy_params(int nb_args, struct plan *plan, int todo) void gfunc_call(int nb_args) { int r, args_size; - int variadic, corefloat = 1; + int variadic, def_float_abi = float_abi; int todo; struct plan plan; #ifdef TCC_ARM_EABI if (float_abi == ARM_HARD_FLOAT) { variadic = (vtop[-nb_args].type.ref->c == FUNC_ELLIPSIS); - corefloat = variadic || floats_in_core_regs(&vtop[-nb_args]); + if (variadic || floats_in_core_regs(&vtop[-nb_args])) + float_abi = ARM_SOFTFP_FLOAT; } #endif /* cannot let cpu flags if other instruction are generated. Also avoid leaving @@ -1200,7 +1201,7 @@ void gfunc_call(int nb_args) if (r == VT_CMP || (r & ~1) == VT_JMP) gv(RC_INT); - args_size = assign_regs(nb_args, corefloat, &plan, &todo); + args_size = assign_regs(nb_args, float_abi, &plan, &todo); #ifdef TCC_ARM_EABI if (args_size & 7) { /* Stack must be 8 byte aligned at fct call for EABI */ @@ -1218,8 +1219,7 @@ void gfunc_call(int nb_args) if (args_size) gadd_sp(args_size); /* pop all parameters passed on the stack */ #if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP) - if(float_abi == ARM_SOFTFP_FLOAT && corefloat && - is_float(vtop->type.ref->type.t)) { + if(float_abi == ARM_SOFTFP_FLOAT && is_float(vtop->type.ref->type.t)) { if((vtop->type.ref->type.t & VT_BTYPE) == VT_FLOAT) { o(0xEE000A10); /*vmov s0, r0 */ } else { @@ -1230,6 +1230,7 @@ void gfunc_call(int nb_args) #endif vtop -= nb_args + 1; /* Pop all params and fct address from value stack */ leaffunc = 0; /* we are calling a function, so we aren't in a leaf function */ + float_abi = def_float_abi; } /* generate function prolog of type 't' */ @@ -1979,17 +1980,8 @@ ST_FUNC void gen_cvt_itof1(int t) vpush_global_sym(func_type, func); vswap(); gfunc_call(1); -#if defined(TCC_ARM_VFP) && defined(TCC_ARM_EABI) - r=get_reg(RC_FLOAT); - r2=vfpr(r); - o(0xEE000B10|(r2<<16)); /* vmov.32 dr2[0], r0 */ - o(0xEE201B10|(r2<<16)); /* vmov.32 dr2[1], r1 */ - vpushi(0); - vtop->r=r; -#else vpushi(0); vtop->r=TREG_F0; -#endif return; } }