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.
Unified · Split
| @@ -923,7 +923,7 @@ struct plan { · 922 unmodified lines | ||
| 923 | 923 | definition of union reg_class). |
| 924 | 924 | |
| 925 | 925 | nb_args: number of parameters of the function for which a call is generated |
| 926 | − corefloat: whether to pass float via core registers or not | |
| 926 | + float_abi: float ABI in use for this function call | |
| 927 | 927 | plan: the structure where the overall assignment is recorded |
| 928 | 928 | todo: a bitmap that record which core registers hold a parameter |
| 929 | 929 | |
| @@ -932,7 +932,7 @@ struct plan { · 2 unmodified lines | ||
| 932 | 932 | Note: this function allocated an array in plan->pplans with tcc_malloc. It |
| 933 | 933 | is the responsability of the caller to free this array once used (ie not |
| 934 | 934 | before copy_params). */ |
| 935 | −static int assign_regs(int nb_args, int corefloat, struct plan *plan, int *todo) | |
| 935 | +static int assign_regs(int nb_args, int float_abi, struct plan *plan, int *todo) | |
| 936 | 936 | { |
| 937 | 937 | int i, size, align; |
| 938 | 938 | 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) · 13 unmodified lines | ||
| 952 | 952 | case VT_FLOAT: |
| 953 | 953 | case VT_DOUBLE: |
| 954 | 954 | case VT_LDOUBLE: |
| 955 | − if (!corefloat) { | |
| 955 | + if (float_abi == ARM_HARD_FLOAT) { | |
| 956 | 956 | int is_hfa = 0; /* Homogeneous float aggregate */ |
| 957 | 957 | |
| 958 | 958 | if (is_float(vtop[-i].type.t) |
| @@ -1183,14 +1183,15 @@ static int copy_params(int nb_args, struct plan *plan, int todo) · 224 unmodified lines | ||
| 1183 | 1183 | void gfunc_call(int nb_args) |
| 1184 | 1184 | { |
| 1185 | 1185 | int r, args_size; |
| 1186 | − int variadic, corefloat = 1; | |
| 1186 | + int variadic, def_float_abi = float_abi; | |
| 1187 | 1187 | int todo; |
| 1188 | 1188 | struct plan plan; |
| 1189 | 1189 | |
| 1190 | 1190 | #ifdef TCC_ARM_EABI |
| 1191 | 1191 | if (float_abi == ARM_HARD_FLOAT) { |
| 1192 | 1192 | variadic = (vtop[-nb_args].type.ref->c == FUNC_ELLIPSIS); |
| 1193 | − corefloat = variadic || floats_in_core_regs(&vtop[-nb_args]); | |
| 1193 | + if (variadic || floats_in_core_regs(&vtop[-nb_args])) | |
| 1194 | + float_abi = ARM_SOFTFP_FLOAT; | |
| 1194 | 1195 | } |
| 1195 | 1196 | #endif |
| 1196 | 1197 | /* cannot let cpu flags if other instruction are generated. Also avoid leaving |
| @@ -1200,7 +1201,7 @@ void gfunc_call(int nb_args) · 3 unmodified lines | ||
| 1200 | 1201 | if (r == VT_CMP || (r & ~1) == VT_JMP) |
| 1201 | 1202 | gv(RC_INT); |
| 1202 | 1203 | |
| 1203 | − args_size = assign_regs(nb_args, corefloat, &plan, &todo); | |
| 1204 | + args_size = assign_regs(nb_args, float_abi, &plan, &todo); | |
| 1204 | 1205 | |
| 1205 | 1206 | #ifdef TCC_ARM_EABI |
| 1206 | 1207 | 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) · 11 unmodified lines | ||
| 1218 | 1219 | if (args_size) |
| 1219 | 1220 | gadd_sp(args_size); /* pop all parameters passed on the stack */ |
| 1220 | 1221 | #if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP) |
| 1221 | − if(float_abi == ARM_SOFTFP_FLOAT && corefloat && | |
| 1222 | − is_float(vtop->type.ref->type.t)) { | |
| 1222 | + if(float_abi == ARM_SOFTFP_FLOAT && is_float(vtop->type.ref->type.t)) { | |
| 1223 | 1223 | if((vtop->type.ref->type.t & VT_BTYPE) == VT_FLOAT) { |
| 1224 | 1224 | o(0xEE000A10); /*vmov s0, r0 */ |
| 1225 | 1225 | } else { |
| @@ -1230,6 +1230,7 @@ void gfunc_call(int nb_args) · 4 unmodified lines | ||
| 1230 | 1230 | #endif |
| 1231 | 1231 | vtop -= nb_args + 1; /* Pop all params and fct address from value stack */ |
| 1232 | 1232 | leaffunc = 0; /* we are calling a function, so we aren't in a leaf function */ |
| 1233 | + float_abi = def_float_abi; | |
| 1233 | 1234 | } |
| 1234 | 1235 | |
| 1235 | 1236 | /* generate function prolog of type 't' */ |
| @@ -1979,17 +1980,8 @@ ST_FUNC void gen_cvt_itof1(int t) · 743 unmodified lines | ||
| 1979 | 1980 | vpush_global_sym(func_type, func); |
| 1980 | 1981 | vswap(); |
| 1981 | 1982 | gfunc_call(1); |
| 1982 | −#if defined(TCC_ARM_VFP) && defined(TCC_ARM_EABI) | |
| 1983 | − r=get_reg(RC_FLOAT); | |
| 1984 | − r2=vfpr(r); | |
| 1985 | − o(0xEE000B10|(r2<<16)); /* vmov.32 dr2[0], r0 */ | |
| 1986 | − o(0xEE201B10|(r2<<16)); /* vmov.32 dr2[1], r1 */ | |
| 1987 | − vpushi(0); | |
| 1988 | − vtop->r=r; | |
| 1989 | −#else | |
| 1990 | 1983 | vpushi(0); |
| 1991 | 1984 | vtop->r=TREG_F0; |
| 1992 | −#endif | |
| 1993 | 1985 | return; |
| 1994 | 1986 | } |
| 1995 | 1987 | } |