===================================================================
@@ -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
===================================================================
@@ -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
===================================================================
@@ -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);
===================================================================
@@ -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,
===================================================================
@@ -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
===================================================================
@@ -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);