On 05/10/2011 06:57 PM, Joseph S. Myers wrote:
> On Tue, 10 May 2011, Bernd Schmidt wrote:
>
>> On C6X, we have PARM_BOUNDARY == 8 (one byte), but some function
>> argument slots still must be rounded to a larger value. As far as I
>> could tell there's currently no way of telling gcc about this, hence a
>> new target macro which controls this behaviour.
>
> Is there a good reason this has to be a macro rather than a hook in
> targetm.calls? Hooks are generally strongly preferred.
New version below. An adapted version of the C6X port will follow.
Bernd
* doc/tm.texi.in (FUNCTION_ARG_PADDING): Mention
TARGET_FUNCTION_ARG_ROUND_TO_ARG_BOUNDARY.
(TARGET_FUNCTION_ARG_ROUND_TO_ARG_BOUNDARY): Add hook.
* function.c (locate_and_pad_parm): Take it into account.
* target.def (function_arg_round_to_arg_boundary): New hook.
* hooks.c (hook_bool_mode_const_tree_false): New function.
* hooks.h (hook_bool_mode_const_tree_false): Declare.
* doc/tm.texi: Regenerate.
Index: gcc/doc/tm.texi
===================================================================
--- gcc/doc/tm.texi.orig
+++ gcc/doc/tm.texi
@@ -4163,9 +4163,11 @@ to pad out an argument with extra space.
@code{enum direction}: either @code{upward} to pad above the argument,
@code{downward} to pad below, or @code{none} to inhibit padding.
-The @emph{amount} of padding is always just enough to reach the next
-multiple of @code{TARGET_FUNCTION_ARG_BOUNDARY}; this macro does not
-control it.
+The @emph{amount} of padding is not controlled by this macro. It is
+always just enough to reach the next multiple of the alignment boundary,
+which is usually @code{PARM_BOUNDARY}, or @code{FUNCTION_ARG_BOUNDARY}
+if @code{TARGET_FUNCTION_ARG_ROUND_TO_ARG_BOUNDARY} is overridden to
+return true.
This macro has a default definition which is right for most systems.
For little-endian machines, the default is to pad upward. For
@@ -4198,6 +4200,12 @@ with the specified mode and type. The d
@code{PARM_BOUNDARY} for all arguments.
@end deftypefn
+@deftypefn {Target Hook} bool TARGET_FUNCTION_ARG_ROUND_TO_ARG_BOUNDARY (enum
machine_mode @var{mode}, const_tree @var{type})
+Normally, the size of an argument is rounded up to @code{PARM_BOUNDARY}.
+Define this macro if you want the value of @code{FUNCTION_ARG_BOUNDARY}
+to be used for this rounding instead.
+@end deftypefn
+
@defmac FUNCTION_ARG_REGNO_P (@var{regno})
A C expression that is nonzero if @var{regno} is the number of a hard
register in which function arguments are sometimes passed. This does
Index: gcc/doc/tm.texi.in
===================================================================
--- gcc/doc/tm.texi.in.orig
+++ gcc/doc/tm.texi.in
@@ -4151,9 +4151,11 @@ to pad out an argument with extra space.
@code{enum direction}: either @code{upward} to pad above the argument,
@code{downward} to pad below, or @code{none} to inhibit padding.
-The @emph{amount} of padding is always just enough to reach the next
-multiple of @code{TARGET_FUNCTION_ARG_BOUNDARY}; this macro does not
-control it.
+The @emph{amount} of padding is not controlled by this macro. It is
+always just enough to reach the next multiple of the alignment boundary,
+which is usually @code{PARM_BOUNDARY}, or @code{FUNCTION_ARG_BOUNDARY}
+if @code{TARGET_FUNCTION_ARG_ROUND_TO_ARG_BOUNDARY} is overridden to
+return true.
This macro has a default definition which is right for most systems.
For little-endian machines, the default is to pad upward. For
@@ -4186,6 +4188,8 @@ with the specified mode and type. The d
@code{PARM_BOUNDARY} for all arguments.
@end deftypefn
+@hook TARGET_FUNCTION_ARG_ROUND_TO_ARG_BOUNDARY
+
@defmac FUNCTION_ARG_REGNO_P (@var{regno})
A C expression that is nonzero if @var{regno} is the number of a hard
register in which function arguments are sometimes passed. This does
Index: gcc/function.c
===================================================================
--- gcc/function.c.orig
+++ gcc/function.c
@@ -3709,7 +3709,7 @@ locate_and_pad_parm (enum machine_mode p
{
tree sizetree;
enum direction where_pad;
- unsigned int boundary;
+ unsigned int boundary, round_boundary;
int reg_parm_stack_space = 0;
int part_size_in_regs;
@@ -3741,6 +3741,10 @@ locate_and_pad_parm (enum machine_mode p
= type ? size_in_bytes (type) : size_int (GET_MODE_SIZE (passed_mode));
where_pad = FUNCTION_ARG_PADDING (passed_mode, type);
boundary = targetm.calls.function_arg_boundary (passed_mode, type);
+ if (targetm.calls.function_arg_round_to_arg_boundary (passed_mode, type))
+ round_boundary = boundary;
+ else
+ round_boundary = PARM_BOUNDARY;
locate->where_pad = where_pad;
/* Alignment can't exceed MAX_SUPPORTED_STACK_ALIGNMENT. */
@@ -3787,8 +3791,8 @@ locate_and_pad_parm (enum machine_mode p
tree s2 = sizetree;
if (where_pad != none
&& (!host_integerp (sizetree, 1)
- || (tree_low_cst (sizetree, 1) * BITS_PER_UNIT) % PARM_BOUNDARY))
- s2 = round_up (s2, PARM_BOUNDARY / BITS_PER_UNIT);
+ || (tree_low_cst (sizetree, 1) * BITS_PER_UNIT) % round_boundary))
+ s2 = round_up (s2, round_boundary / BITS_PER_UNIT);
SUB_PARM_SIZE (locate->slot_offset, s2);
}
@@ -3840,8 +3844,8 @@ locate_and_pad_parm (enum machine_mode p
if (where_pad != none
&& (!host_integerp (sizetree, 1)
- || (tree_low_cst (sizetree, 1) * BITS_PER_UNIT) % PARM_BOUNDARY))
- sizetree = round_up (sizetree, PARM_BOUNDARY / BITS_PER_UNIT);
+ || (tree_low_cst (sizetree, 1) * BITS_PER_UNIT) % round_boundary))
+ sizetree = round_up (sizetree, round_boundary / BITS_PER_UNIT);
ADD_PARM_SIZE (locate->size, sizetree);
Index: gcc/hooks.c
===================================================================
--- gcc/hooks.c.orig
+++ gcc/hooks.c
@@ -85,6 +85,14 @@ hook_bool_mode_true (enum machine_mode m
return true;
}
+/* Generic hook that takes (enum machine_mode, const_tree) and returns false.
*/
+bool
+hook_bool_mode_const_tree_false (enum machine_mode mode ATTRIBUTE_UNUSED,
+ const_tree value ATTRIBUTE_UNUSED)
+{
+ return false;
+}
+
/* Generic hook that takes (enum machine_mode, const_rtx) and returns false.
*/
bool
hook_bool_mode_const_rtx_false (enum machine_mode mode ATTRIBUTE_UNUSED,
Index: gcc/target.def
===================================================================
--- gcc/target.def.orig
+++ gcc/target.def
@@ -2053,6 +2053,14 @@ DEFHOOK
unsigned int, (enum machine_mode mode, const_tree type),
default_function_arg_boundary)
+DEFHOOK
+(function_arg_round_to_arg_boundary,
+ "Normally, the size of an argument is rounded up to @code{PARM_BOUNDARY}.\n\
+Define this macro if you want the value of @code{FUNCTION_ARG_BOUNDARY}\n\
+to be used for this rounding instead.",
+ bool, (enum machine_mode mode, const_tree type),
+ hook_bool_mode_const_tree_false)
+
/* Return the diagnostic message string if function without a prototype
is not allowed for this 'val' argument; NULL otherwise. */
DEFHOOK
Index: gcc/hooks.h
===================================================================
--- gcc/hooks.h.orig
+++ gcc/hooks.h
@@ -32,6 +32,7 @@ extern bool hook_bool_bool_gcc_optionsp_
extern bool hook_bool_const_int_const_int_true (const int, const int);
extern bool hook_bool_mode_false (enum machine_mode);
extern bool hook_bool_mode_true (enum machine_mode);
+extern bool hook_bool_mode_const_tree_false (enum machine_mode, const_tree);
extern bool hook_bool_mode_const_rtx_false (enum machine_mode, const_rtx);
extern bool hook_bool_mode_const_rtx_true (enum machine_mode, const_rtx);
extern bool hook_bool_mode_rtx_false (enum machine_mode, rtx);