+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.
&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
/* 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);
}
{
/* 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
const_tree fntype ATTRIBUTE_UNUSED,
int for_return)
{
- if (!for_return)
+ if (for_return == 0)
return mode;
return promote_mode (type, mode, punsignedp);
}
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
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);
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);
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)
{
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);
}
const_tree funtype ATTRIBUTE_UNUSED,
int for_return ATTRIBUTE_UNUSED)
{
+ if (for_return == 2)
+ return promote_mode (type, mode, punsignedp);
return mode;
}