summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog16
-rw-r--r--gcc/calls.c4
-rw-r--r--gcc/config/cris/cris.c2
-rw-r--r--gcc/config/mmix/mmix.c2
-rw-r--r--gcc/config/pa/pa.c2
-rw-r--r--gcc/doc/tm.texi12
-rw-r--r--gcc/explow.c8
-rw-r--r--gcc/function.c11
-rw-r--r--gcc/stmt.c15
-rw-r--r--gcc/targhooks.c2
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 <bonzini@gnu.org>
+
+ * 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 <aph@redhat.com>
* 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;
}