From 666e3cebe13c86ea21f84fb5b5d6d9e1dc49a9a5 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 12 Aug 2009 16:23:12 +0000 Subject: [PATCH] tm.texi (TARGET_PROMOTE_FUNCTION_MODE): Add documentation for for_return == 2. 2009-08-12 Paolo Bonzini * doc/tm.texi (TARGET_PROMOTE_FUNCTION_MODE): Add documentation for for_return == 2. * function.c (assign_parm_setup_reg): Use for_return == 2, improve comments. * calls.c (expand_call): Fix typo. * explow.c (promote_decl_mode): Use for_return == 2 for RESULT_DECL and PARM_DECL. * stmt.c (expand_value_return): Use promote_function_mode to copy out of pseudo. * targhooks.c (default_promote_function_mode): Handle for_return == 2. * config/cris/cris.c (cris_promote_function_mode): Likewise. * config/mmix/mmix.c (mmix_promote_function_mode): Likewise. * config/pa/pa.c (pa_promote_function_mode): Likewise. From-SVN: r150700 --- gcc/ChangeLog | 16 ++++++++++++++++ gcc/calls.c | 4 ++-- gcc/config/cris/cris.c | 2 +- gcc/config/mmix/mmix.c | 2 +- gcc/config/pa/pa.c | 2 +- gcc/doc/tm.texi | 12 ++++++++---- gcc/explow.c | 8 +++----- gcc/function.c | 11 +++++------ gcc/stmt.c | 15 +++++++-------- gcc/targhooks.c | 2 ++ 10 files changed, 46 insertions(+), 28 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 13788c3e851..8cea1ba72fe 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2009-08-12 Paolo Bonzini + + * doc/tm.texi (TARGET_PROMOTE_FUNCTION_MODE): Add documentation + for for_return == 2. + * function.c (assign_parm_setup_reg): Use for_return == 2, improve + comments. + * calls.c (expand_call): Fix typo. + * explow.c (promote_decl_mode): Use for_return == 2 for RESULT_DECL + and PARM_DECL. + * stmt.c (expand_value_return): Use promote_function_mode to copy out + of pseudo. + * targhooks.c (default_promote_function_mode): Handle for_return == 2. + * config/cris/cris.c (cris_promote_function_mode): Likewise. + * config/mmix/mmix.c (mmix_promote_function_mode): Likewise. + * config/pa/pa.c (pa_promote_function_mode): Likewise. + 2009-08-11 Andrew Haley * config/arm/arm.c (arm_init_libfuncs): Add __sync_synchronize. diff --git a/gcc/calls.c b/gcc/calls.c index 7ad5b099db1..cdb934a2785 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -2353,9 +2353,9 @@ expand_call (tree exp, rtx target, int ignore) &caller_unsignedp, TREE_TYPE (current_function_decl), 1); callee_promoted_mode - = promote_function_mode (TREE_TYPE (caller_res), callee_mode, + = promote_function_mode (TREE_TYPE (funtype), callee_mode, &callee_unsignedp, - TREE_TYPE (funtype), 1); + funtype, 1); if (caller_mode != VOIDmode && (caller_promoted_mode != callee_promoted_mode || ((caller_mode != caller_promoted_mode diff --git a/gcc/config/cris/cris.c b/gcc/config/cris/cris.c index a9fe9dee52f..6b3fd0fcfca 100644 --- a/gcc/config/cris/cris.c +++ b/gcc/config/cris/cris.c @@ -3771,7 +3771,7 @@ cris_promote_function_mode (const_tree type ATTRIBUTE_UNUSED, /* Defining PROMOTE_FUNCTION_RETURN in gcc-2.7.2 uncovered bug 981110 (even when modifying FUNCTION_VALUE to return the promoted mode). Maybe pointless as of now, but let's keep the old behavior. */ - if (for_return) + if (for_return == 1) return mode; return CRIS_PROMOTED_MODE (mode, *punsignedp, type); } diff --git a/gcc/config/mmix/mmix.c b/gcc/config/mmix/mmix.c index 9e94279b85a..8521f374f81 100644 --- a/gcc/config/mmix/mmix.c +++ b/gcc/config/mmix/mmix.c @@ -2701,7 +2701,7 @@ mmix_promote_function_mode (const_tree type ATTRIBUTE_UNUSED, { /* Apparently not doing TRT if int < register-size. FIXME: Perhaps FUNCTION_VALUE and LIBCALL_VALUE needs tweaking as some ports say. */ - if (for_return) + if (for_return == 1) return mode; /* Promotion of modes currently generates slow code, extending before diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index e60ddde0535..c5543ef1195 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -9199,7 +9199,7 @@ pa_promote_function_mode (const_tree type ATTRIBUTE_UNUSED, const_tree fntype ATTRIBUTE_UNUSED, int for_return) { - if (!for_return) + if (for_return == 0) return mode; return promote_mode (type, mode, punsignedp); } diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 34c81c9e15c..df4973d8368 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -1046,13 +1046,17 @@ and possibly change @code{*@var{punsignedp}} if the promotion should change signedness. This function is called only for scalar @emph{or pointer} types. +@var{for_return} allows to distinguish the promotion of arguments and +return values. If it is @code{1}, a return value is being promoted and +@code{TARGET_FUNCTION_VALUE} must perform the same promotions done here. +If it is @code{2}, the returned mode should be that of the register in +which an incoming parameter is copied, or the outgoing result is computed; +then the hook should return the same mode as @code{promote_mode}, though +the signedness may be different. + The default is to not promote arguments and return values. You can also define the hook to @code{default_promote_function_mode_always_promote} if you would like to apply the same rules given by @code{PROMOTE_MODE}. - -@var{for_return} allows to distinguish the promotion of arguments and -return values. If this target hook promotes return values, -@code{TARGET_FUNCTION_VALUE} must perform the same promotions done here. @end deftypefn @defmac PARM_BOUNDARY diff --git a/gcc/explow.c b/gcc/explow.c index 7388a455b1d..933eac81bb1 100644 --- a/gcc/explow.c +++ b/gcc/explow.c @@ -825,12 +825,10 @@ promote_decl_mode (const_tree decl, int *punsignedp) enum machine_mode mode = DECL_MODE (decl); enum machine_mode pmode; - if (TREE_CODE (decl) == RESULT_DECL) + if (TREE_CODE (decl) == RESULT_DECL + || TREE_CODE (decl) == PARM_DECL) pmode = promote_function_mode (type, mode, &unsignedp, - TREE_TYPE (current_function_decl), 1); - else if (TREE_CODE (decl) == PARM_DECL) - pmode = promote_function_mode (type, mode, &unsignedp, - TREE_TYPE (current_function_decl), 0); + TREE_TYPE (current_function_decl), 2); else pmode = promote_mode (type, mode, &unsignedp); diff --git a/gcc/function.c b/gcc/function.c index 2294b971547..b1d467c5787 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -2770,13 +2770,11 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm, bool did_conversion = false; /* Store the parm in a pseudoregister during the function, but we may - need to do it in a wider mode. */ - - /* This is not really promoting for a call. However we need to be - consistent with assign_parm_find_data_types and expand_expr_real_1. */ + need to do it in a wider mode. Using 2 here makes the result + consistent with promote_decl_mode and thus expand_expr_real_1. */ promoted_nominal_mode = promote_function_mode (data->nominal_type, data->nominal_mode, &unsignedp, - TREE_TYPE (current_function_decl), 0); + TREE_TYPE (current_function_decl), 2); parmreg = gen_reg_rtx (promoted_nominal_mode); @@ -2796,7 +2794,8 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm, assign_parm_remove_parallels (data); - /* Copy the value into the register. */ + /* Copy the value into the register, thus bridging between + assign_parm_find_data_types and expand_expr_real_1. */ if (data->nominal_mode != data->passed_mode || promoted_nominal_mode != data->promoted_mode) { diff --git a/gcc/stmt.c b/gcc/stmt.c index 29bcf870fba..fe60ba67150 100644 --- a/gcc/stmt.c +++ b/gcc/stmt.c @@ -1511,25 +1511,24 @@ expand_naked_return (void) static void expand_value_return (rtx val) { - /* Copy the value to the return location - unless it's already there. */ + /* Copy the value to the return location unless it's already there. */ tree decl = DECL_RESULT (current_function_decl); rtx return_reg = DECL_RTL (decl); if (return_reg != val) { - int unsignedp; + tree funtype = TREE_TYPE (current_function_decl); + tree type = TREE_TYPE (decl); + int unsignedp = TYPE_UNSIGNED (type); enum machine_mode old_mode = DECL_MODE (decl); - enum machine_mode mode = promote_decl_mode (decl, &unsignedp); + enum machine_mode mode = promote_function_mode (type, old_mode, + &unsignedp, funtype, 1); if (mode != old_mode) val = convert_modes (mode, old_mode, val, unsignedp); if (GET_CODE (return_reg) == PARALLEL) - { - tree type = TREE_TYPE (decl); - emit_group_load (return_reg, val, type, int_size_in_bytes (type)); - } + emit_group_load (return_reg, val, type, int_size_in_bytes (type)); else emit_move_insn (return_reg, val); } diff --git a/gcc/targhooks.c b/gcc/targhooks.c index 58a9aeea403..7535bc10ab7 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -119,6 +119,8 @@ default_promote_function_mode (const_tree type ATTRIBUTE_UNUSED, const_tree funtype ATTRIBUTE_UNUSED, int for_return ATTRIBUTE_UNUSED) { + if (for_return == 2) + return promote_mode (type, mode, punsignedp); return mode; } -- 2.11.4.GIT