Turn FUNCTION_ARG_PADDING into a target hook

This involved renaming the rather general-sounding "enum direction" to
"enum pad_direction" to avoid a conflict with the Fortran frontend.

2017-09-04  Richard Sandiford  <richard.sandiford@linaro.org>
	    Alan Hayward  <alan.hayward@arm.com>
	    David Sherwood  <david.sherwood@arm.com>

gcc/
	* coretypes.h (pad_direction): New enum.
	* defaults.h (DEFAULT_FUNCTION_ARG_PADDING): Delete.
	(FUNCTION_ARG_PADDING): Likewise.
	* target.def (function_arg_padding): New hook.
	* targhooks.h (default_function_arg_padding): Declare.
	* targhooks.c (default_function_arg_padding): New function.
	* doc/tm.texi.in (FUNCTION_ARG_PADDING): Replace with...
	(TARGET_FUNCTION_ARG_PADDING): ...this.
	* doc/tm.texi: Regenerate.
	* calls.c (store_unaligned_arguments_into_pseudos): Use pad_direction
	instead of direction.
	(compute_argument_addresses): Likewise.
	(load_register_parameters): Likewise.
	(emit_library_call_value_1): Likewise.
	(store_one_arg): Use targetm.calls.function_arg_padding instead
	of FUNCTION_ARG_PADDING.
	(must_pass_in_stack_var_size_or_pad): Likewise.
	* expr.c (emit_group_load_1): Use pad_direction instead of direction.
	(emit_group_store): Likewise.
	(emit_single_push_insn_1): Use targetm.calls.function_arg_padding
	instead of FUNCTION_ARG_PADDING.
	(emit_push_insn): Likewise, and propagate enum change throughout
	function.
	* function.h (direction): Delete.
	(locate_and_pad_arg_data::where_pad): Use pad_direction instead
	of direction.
	* function.c (assign_parm_find_stack_rtl): Likewise.
	(assign_parm_setup_block_p): Likewise.
	(assign_parm_setup_block): Likewise.
	(gimplify_parameters): Likewise.
	(locate_and_pad_parm): Use targetm.calls.function_arg_padding
	instead of FUNCTION_ARG_PADDING, and propagate enum change throughout
	function.
	* config/aarch64/aarch64.h (FUNCTION_ARG_PADDING): Delete.
	(BLOCK_REG_PADDING): Use pad_direction instead of direction.
	* config/aarch64/aarch64-protos.h (aarch64_pad_arg_upward): Delete.
	* config/aarch64/aarch64.c (aarch64_pad_arg_upward): Replace with...
	(aarch64_function_arg_padding): ...this new function.
	(aarch64_gimplify_va_arg_expr): Use pad_direction instead of direction.
	(TARGET_FUNCTION_ARG_PADDING): Redefine.
	* config/arm/arm.h (FUNCTION_ARG_PADDING): Delete.
	(BLOCK_REG_PADDING): Use pad_direction instead of direction.
	* config/arm/arm-protos.h (arm_pad_arg_upward): Delete.
	* config/arm/arm.c (TARGET_FUNCTION_ARG_PADDING): Redefine.
	(arm_pad_arg_upward): Replace with...
	(arm_function_arg_padding): ...this new function.
	* config/c6x/c6x.h (BLOCK_REG_PADDING): Use pad_direction instead
	of direction.
	* config/ia64/hpux.h (FUNCTION_ARG_PADDING): Delete.
	* config/ia64/ia64-protos.h (ia64_hpux_function_arg_padding): Delete.
	* config/ia64/ia64.c (TARGET_FUNCTION_ARG_PADDING): Redefine.
	(ia64_hpux_function_arg_padding): Replace with...
	(ia64_function_arg_padding): ...this new function.  Use pad_direction
	instead of direction.  Check for TARGET_HPUX.
	* config/iq2000/iq2000.h (FUNCTION_ARG_PADDING): Delete.
	* config/iq2000/iq2000.c (TARGET_FUNCTION_ARG_PADDING): Redefine.
	(iq2000_function_arg_padding): New function.
	* config/mips/mips-protos.h (mips_pad_arg_upward): Delete.
	* config/mips/mips.c (mips_pad_arg_upward): Replace with...
	(mips_function_arg_padding): ...this new function.
	(mips_pad_reg_upward): Update accordingly.
	(TARGET_FUNCTION_ARG_PADDING): Redefine.
	* config/mips/mips.h (PAD_VARARGS_DOWN): Use
	targetm.calls.function_arg_padding.
	(FUNCTION_ARG_PADDING): Delete.
	(BLOCK_REG_PADDING): Use pad_direction instead of direction.
	* config/nios2/nios2.h (FUNCTION_ARG_PADDING): Delete.
	(PAD_VARARGS_DOWN): Use targetm.calls.function_arg_padding.
	* config/nios2/nios2-protos.h (nios2_function_arg_padding): Delete.
	(nios2_block_reg_padding): Return pad_direction instead of direction.
	* config/nios2/nios2.c (nios2_block_reg_padding): Return pad_direction
	instead of direction.
	(nios2_function_arg_padding): Likewise.  Make static.
	(TARGET_FUNCTION_ARG_PADDING): Redefine.
	* config/pa/pa.h (FUNCTION_ARG_PADDING): Delete.
	(BLOCK_REG_PADDING): Use targetm.calls.function_arg_padding.
	* config/pa/pa-protos.h (pa_function_arg_padding): Delete.
	* config/pa/pa.c (TARGET_FUNCTION_ARG_PADDING): Redefine.
	(pa_function_arg_padding): Make static.  Return pad_direction instead
	of direction.
	* config/powerpcspe/powerpcspe.h (FUNCTION_ARG_PADDING): Delete.
	(PAD_VARARGS_DOWN): Use targetm.calls.function_arg_padding.
	* config/powerpcspe/aix.h (BLOCK_REG_PADDING): Use pad_direction
	instead of direction.  Use targetm.calls.function_arg_padding.
	* config/powerpcspe/darwin.h (BLOCK_REG_PADDING): Likewise.
	* config/powerpcspe/freebsd64.h (BLOCK_REG_PADDING): Likewise.
	* config/powerpcspe/linux64.h (BLOCK_REG_PADDING): Likewise.
	* config/powerpcspe/powerpcspe-protos.h (function_arg_padding): Delete.
	* config/powerpcspe/powerpcspe.c (TARGET_FUNCTION_ARG_PADDING):
	Redefine.
	(function_arg_padding): Rename to...
	(rs6000_function_arg_padding): ...this.  Make static.  Return
	pad_direction instead of direction.
	(rs6000_return_in_msb): Use rs6000_function_arg_padding.
	* config/rs6000/rs6000.h (FUNCTION_ARG_PADDING): Delete.
	(PAD_VARARGS_DOWN): Use targetm.calls.function_arg_padding.
	* config/rs6000/aix.h (BLOCK_REG_PADDING): Use pad_direction
	instead of direction.  Use targetm.calls.function_arg_padding.
	* config/rs6000/darwin.h (BLOCK_REG_PADDING): Likewise.
	* config/rs6000/freebsd64.h (BLOCK_REG_PADDING): Likewise.
	* config/rs6000/linux64.h (BLOCK_REG_PADDING): Likewise.
	* config/rs6000/rs6000-protos.h (function_arg_padding): Delete.
	* config/rs6000/rs6000.c (TARGET_FUNCTION_ARG_PADDING): Redefine.
	(function_arg_padding): Rename to...
	(rs6000_function_arg_padding): ...this.  Make static.  Return
	pad_direction instead of direction.
	(rs6000_return_in_msb): Use rs6000_function_arg_padding.
	* config/s390/s390.h (FUNCTION_ARG_PADDING): Delete.
	* config/s390/s390.c (s390_function_arg_padding): New function.
	(TARGET_FUNCTION_ARG_PADDING): Redefine.
	* config/sparc/sparc.h (FUNCTION_ARG_PADDING): Delete.
	* config/sparc/sparc-protos.h (function_arg_padding): Delete.
	* config/sparc/sparc.c (TARGET_FUNCTION_ARG_PADDING): Redefine.
	(function_arg_padding): Rename to...
	(sparc_function_arg_padding): ...this.  Make static.  Return
	pad_direction instead of direction.
	* config/spu/spu.h (FUNCTION_ARG_PADDING): Delete.
	* config/spu/spu.c (spu_function_arg_padding): New function.
	(TARGET_FUNCTION_ARG_PADDING): Redefine.
	* system.h (FUNCTION_ARG_PADDING): Poison.

Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>

From-SVN: r251648
This commit is contained in:
Richard Sandiford 2017-09-04 10:50:38 +00:00 committed by Richard Sandiford
parent 99e1629ff1
commit 76b0cbf8b6
55 changed files with 417 additions and 290 deletions

View File

@ -1,3 +1,128 @@
2017-09-04 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
* coretypes.h (pad_direction): New enum.
* defaults.h (DEFAULT_FUNCTION_ARG_PADDING): Delete.
(FUNCTION_ARG_PADDING): Likewise.
* target.def (function_arg_padding): New hook.
* targhooks.h (default_function_arg_padding): Declare.
* targhooks.c (default_function_arg_padding): New function.
* doc/tm.texi.in (FUNCTION_ARG_PADDING): Replace with...
(TARGET_FUNCTION_ARG_PADDING): ...this.
* doc/tm.texi: Regenerate.
* calls.c (store_unaligned_arguments_into_pseudos): Use pad_direction
instead of direction.
(compute_argument_addresses): Likewise.
(load_register_parameters): Likewise.
(emit_library_call_value_1): Likewise.
(store_one_arg): Use targetm.calls.function_arg_padding instead
of FUNCTION_ARG_PADDING.
(must_pass_in_stack_var_size_or_pad): Likewise.
* expr.c (emit_group_load_1): Use pad_direction instead of direction.
(emit_group_store): Likewise.
(emit_single_push_insn_1): Use targetm.calls.function_arg_padding
instead of FUNCTION_ARG_PADDING.
(emit_push_insn): Likewise, and propagate enum change throughout
function.
* function.h (direction): Delete.
(locate_and_pad_arg_data::where_pad): Use pad_direction instead
of direction.
* function.c (assign_parm_find_stack_rtl): Likewise.
(assign_parm_setup_block_p): Likewise.
(assign_parm_setup_block): Likewise.
(gimplify_parameters): Likewise.
(locate_and_pad_parm): Use targetm.calls.function_arg_padding
instead of FUNCTION_ARG_PADDING, and propagate enum change throughout
function.
* config/aarch64/aarch64.h (FUNCTION_ARG_PADDING): Delete.
(BLOCK_REG_PADDING): Use pad_direction instead of direction.
* config/aarch64/aarch64-protos.h (aarch64_pad_arg_upward): Delete.
* config/aarch64/aarch64.c (aarch64_pad_arg_upward): Replace with...
(aarch64_function_arg_padding): ...this new function.
(aarch64_gimplify_va_arg_expr): Use pad_direction instead of direction.
(TARGET_FUNCTION_ARG_PADDING): Redefine.
* config/arm/arm.h (FUNCTION_ARG_PADDING): Delete.
(BLOCK_REG_PADDING): Use pad_direction instead of direction.
* config/arm/arm-protos.h (arm_pad_arg_upward): Delete.
* config/arm/arm.c (TARGET_FUNCTION_ARG_PADDING): Redefine.
(arm_pad_arg_upward): Replace with...
(arm_function_arg_padding): ...this new function.
* config/c6x/c6x.h (BLOCK_REG_PADDING): Use pad_direction instead
of direction.
* config/ia64/hpux.h (FUNCTION_ARG_PADDING): Delete.
* config/ia64/ia64-protos.h (ia64_hpux_function_arg_padding): Delete.
* config/ia64/ia64.c (TARGET_FUNCTION_ARG_PADDING): Redefine.
(ia64_hpux_function_arg_padding): Replace with...
(ia64_function_arg_padding): ...this new function. Use pad_direction
instead of direction. Check for TARGET_HPUX.
* config/iq2000/iq2000.h (FUNCTION_ARG_PADDING): Delete.
* config/iq2000/iq2000.c (TARGET_FUNCTION_ARG_PADDING): Redefine.
(iq2000_function_arg_padding): New function.
* config/mips/mips-protos.h (mips_pad_arg_upward): Delete.
* config/mips/mips.c (mips_pad_arg_upward): Replace with...
(mips_function_arg_padding): ...this new function.
(mips_pad_reg_upward): Update accordingly.
(TARGET_FUNCTION_ARG_PADDING): Redefine.
* config/mips/mips.h (PAD_VARARGS_DOWN): Use
targetm.calls.function_arg_padding.
(FUNCTION_ARG_PADDING): Delete.
(BLOCK_REG_PADDING): Use pad_direction instead of direction.
* config/nios2/nios2.h (FUNCTION_ARG_PADDING): Delete.
(PAD_VARARGS_DOWN): Use targetm.calls.function_arg_padding.
* config/nios2/nios2-protos.h (nios2_function_arg_padding): Delete.
(nios2_block_reg_padding): Return pad_direction instead of direction.
* config/nios2/nios2.c (nios2_block_reg_padding): Return pad_direction
instead of direction.
(nios2_function_arg_padding): Likewise. Make static.
(TARGET_FUNCTION_ARG_PADDING): Redefine.
* config/pa/pa.h (FUNCTION_ARG_PADDING): Delete.
(BLOCK_REG_PADDING): Use targetm.calls.function_arg_padding.
* config/pa/pa-protos.h (pa_function_arg_padding): Delete.
* config/pa/pa.c (TARGET_FUNCTION_ARG_PADDING): Redefine.
(pa_function_arg_padding): Make static. Return pad_direction instead
of direction.
* config/powerpcspe/powerpcspe.h (FUNCTION_ARG_PADDING): Delete.
(PAD_VARARGS_DOWN): Use targetm.calls.function_arg_padding.
* config/powerpcspe/aix.h (BLOCK_REG_PADDING): Use pad_direction
instead of direction. Use targetm.calls.function_arg_padding.
* config/powerpcspe/darwin.h (BLOCK_REG_PADDING): Likewise.
* config/powerpcspe/freebsd64.h (BLOCK_REG_PADDING): Likewise.
* config/powerpcspe/linux64.h (BLOCK_REG_PADDING): Likewise.
* config/powerpcspe/powerpcspe-protos.h (function_arg_padding): Delete.
* config/powerpcspe/powerpcspe.c (TARGET_FUNCTION_ARG_PADDING):
Redefine.
(function_arg_padding): Rename to...
(rs6000_function_arg_padding): ...this. Make static. Return
pad_direction instead of direction.
(rs6000_return_in_msb): Use rs6000_function_arg_padding.
* config/rs6000/rs6000.h (FUNCTION_ARG_PADDING): Delete.
(PAD_VARARGS_DOWN): Use targetm.calls.function_arg_padding.
* config/rs6000/aix.h (BLOCK_REG_PADDING): Use pad_direction
instead of direction. Use targetm.calls.function_arg_padding.
* config/rs6000/darwin.h (BLOCK_REG_PADDING): Likewise.
* config/rs6000/freebsd64.h (BLOCK_REG_PADDING): Likewise.
* config/rs6000/linux64.h (BLOCK_REG_PADDING): Likewise.
* config/rs6000/rs6000-protos.h (function_arg_padding): Delete.
* config/rs6000/rs6000.c (TARGET_FUNCTION_ARG_PADDING): Redefine.
(function_arg_padding): Rename to...
(rs6000_function_arg_padding): ...this. Make static. Return
pad_direction instead of direction.
(rs6000_return_in_msb): Use rs6000_function_arg_padding.
* config/s390/s390.h (FUNCTION_ARG_PADDING): Delete.
* config/s390/s390.c (s390_function_arg_padding): New function.
(TARGET_FUNCTION_ARG_PADDING): Redefine.
* config/sparc/sparc.h (FUNCTION_ARG_PADDING): Delete.
* config/sparc/sparc-protos.h (function_arg_padding): Delete.
* config/sparc/sparc.c (TARGET_FUNCTION_ARG_PADDING): Redefine.
(function_arg_padding): Rename to...
(sparc_function_arg_padding): ...this. Make static. Return
pad_direction instead of direction.
* config/spu/spu.h (FUNCTION_ARG_PADDING): Delete.
* config/spu/spu.c (spu_function_arg_padding): New function.
(TARGET_FUNCTION_ARG_PADDING): Redefine.
* system.h (FUNCTION_ARG_PADDING): Poison.
2017-09-04 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>

View File

@ -1154,7 +1154,7 @@ store_unaligned_arguments_into_pseudos (struct arg_data *args, int num_actuals)
#ifdef BLOCK_REG_PADDING
&& (BLOCK_REG_PADDING (args[i].mode,
TREE_TYPE (args[i].tree_value), 1)
== downward)
== PAD_DOWNWARD)
#else
&& BYTES_BIG_ENDIAN
#endif
@ -2222,7 +2222,7 @@ compute_argument_addresses (struct arg_data *args, rtx argblock, int num_actuals
}
align = BITS_PER_UNIT;
boundary = args[i].locate.boundary;
if (args[i].locate.where_pad != downward)
if (args[i].locate.where_pad != PAD_DOWNWARD)
align = boundary;
else if (CONST_INT_P (offset))
{
@ -2519,7 +2519,7 @@ load_register_parameters (struct arg_data *args, int num_actuals,
upward on a BYTES_BIG_ENDIAN machine. */
if (size < UNITS_PER_WORD
&& (args[i].locate.where_pad
== (BYTES_BIG_ENDIAN ? upward : downward)))
== (BYTES_BIG_ENDIAN ? PAD_UPWARD : PAD_DOWNWARD)))
{
rtx x;
int shift = (UNITS_PER_WORD - size) * BITS_PER_UNIT;
@ -2580,7 +2580,7 @@ load_register_parameters (struct arg_data *args, int num_actuals,
/* Handle a BLKmode that needs shifting. */
if (nregs == 1 && size < UNITS_PER_WORD
#ifdef BLOCK_REG_PADDING
&& args[i].locate.where_pad == downward
&& args[i].locate.where_pad == PAD_DOWNWARD
#else
&& BYTES_BIG_ENDIAN
#endif
@ -4919,7 +4919,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
upward on a BYTES_BIG_ENDIAN machine. */
if (size < UNITS_PER_WORD
&& (argvec[argnum].locate.where_pad
== (BYTES_BIG_ENDIAN ? upward : downward)))
== (BYTES_BIG_ENDIAN ? PAD_UPWARD : PAD_DOWNWARD)))
{
rtx x;
int shift = (UNITS_PER_WORD - size) * BITS_PER_UNIT;
@ -5397,14 +5397,16 @@ store_one_arg (struct arg_data *arg, rtx argblock, int flags,
/* Compute how much space the argument should get:
round up to a multiple of the alignment for arguments. */
if (none != FUNCTION_ARG_PADDING (arg->mode, TREE_TYPE (pval)))
if (targetm.calls.function_arg_padding (arg->mode, TREE_TYPE (pval))
!= PAD_NONE)
used = (((size + PARM_BOUNDARY / BITS_PER_UNIT - 1)
/ (PARM_BOUNDARY / BITS_PER_UNIT))
* (PARM_BOUNDARY / BITS_PER_UNIT));
/* Compute the alignment of the pushed argument. */
parm_align = arg->locate.boundary;
if (FUNCTION_ARG_PADDING (arg->mode, TREE_TYPE (pval)) == downward)
if (targetm.calls.function_arg_padding (arg->mode, TREE_TYPE (pval))
== PAD_DOWNWARD)
{
int pad = used - size;
if (pad)
@ -5463,7 +5465,8 @@ store_one_arg (struct arg_data *arg, rtx argblock, int flags,
/* When an argument is padded down, the block is aligned to
PARM_BOUNDARY, but the actual argument isn't. */
if (FUNCTION_ARG_PADDING (arg->mode, TREE_TYPE (pval)) == downward)
if (targetm.calls.function_arg_padding (arg->mode, TREE_TYPE (pval))
== PAD_DOWNWARD)
{
if (arg->locate.size.var)
parm_align = BITS_PER_UNIT;
@ -5614,8 +5617,8 @@ must_pass_in_stack_var_size_or_pad (machine_mode mode, const_tree type)
a register would put it into the wrong part of the register. */
if (mode == BLKmode
&& int_size_in_bytes (type) % (PARM_BOUNDARY / BITS_PER_UNIT)
&& (FUNCTION_ARG_PADDING (mode, type)
== (BYTES_BIG_ENDIAN ? upward : downward)))
&& (targetm.calls.function_arg_padding (mode, type)
== (BYTES_BIG_ENDIAN ? PAD_UPWARD : PAD_DOWNWARD)))
return true;
return false;

View File

@ -347,7 +347,6 @@ rtx aarch64_reverse_mask (machine_mode);
bool aarch64_offset_7bit_signed_scaled_p (machine_mode, HOST_WIDE_INT);
char *aarch64_output_scalar_simd_mov_immediate (rtx, machine_mode);
char *aarch64_output_simd_mov_immediate (rtx, machine_mode, unsigned);
bool aarch64_pad_arg_upward (machine_mode, const_tree);
bool aarch64_pad_reg_upward (machine_mode, const_tree, bool);
bool aarch64_regno_ok_for_base_p (int, bool);
bool aarch64_regno_ok_for_index_p (int, bool);

View File

@ -2593,22 +2593,19 @@ aarch64_function_arg_boundary (machine_mode mode, const_tree type)
return MIN (MAX (alignment, PARM_BOUNDARY), STACK_BOUNDARY);
}
/* For use by FUNCTION_ARG_PADDING (MODE, TYPE).
Return true if an argument passed on the stack should be padded upwards,
i.e. if the least-significant byte of the stack slot has useful data.
/* Implement TARGET_FUNCTION_ARG_PADDING.
Small aggregate types are placed in the lowest memory address.
The related parameter passing rules are B.4, C.3, C.5 and C.14. */
bool
aarch64_pad_arg_upward (machine_mode mode, const_tree type)
static pad_direction
aarch64_function_arg_padding (machine_mode mode, const_tree type)
{
/* On little-endian targets, the least significant byte of every stack
argument is passed at the lowest byte address of the stack slot. */
if (!BYTES_BIG_ENDIAN)
return true;
return PAD_UPWARD;
/* Otherwise, integral, floating-point and pointer types are padded downward:
the least significant byte of a stack argument is passed at the highest
@ -2617,10 +2614,10 @@ aarch64_pad_arg_upward (machine_mode mode, const_tree type)
? (INTEGRAL_TYPE_P (type) || SCALAR_FLOAT_TYPE_P (type)
|| POINTER_TYPE_P (type))
: (SCALAR_INT_MODE_P (mode) || SCALAR_FLOAT_MODE_P (mode)))
return false;
return PAD_DOWNWARD;
/* Everything else padded upward, i.e. data in first byte of stack slot. */
return true;
return PAD_UPWARD;
}
/* Similarly, for use by BLOCK_REG_PADDING (MODE, TYPE, FIRST).
@ -10633,7 +10630,7 @@ aarch64_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
if (BYTES_BIG_ENDIAN && GET_MODE_SIZE (ag_mode) < UNITS_PER_VREG)
adjust = UNITS_PER_VREG - GET_MODE_SIZE (ag_mode);
}
else if (BLOCK_REG_PADDING (mode, type, 1) == downward
else if (BLOCK_REG_PADDING (mode, type, 1) == PAD_DOWNWARD
&& size < UNITS_PER_VREG)
{
adjust = UNITS_PER_VREG - size;
@ -10652,7 +10649,7 @@ aarch64_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
if (align > 8)
dw_align = true;
if (BLOCK_REG_PADDING (mode, type, 1) == downward
if (BLOCK_REG_PADDING (mode, type, 1) == PAD_DOWNWARD
&& size < UNITS_PER_WORD)
{
adjust = UNITS_PER_WORD - size;
@ -10727,7 +10724,7 @@ aarch64_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
/* String up with arg */
on_stack = build2 (COMPOUND_EXPR, TREE_TYPE (arg), t, arg);
/* Big-endianness related address adjustment. */
if (BLOCK_REG_PADDING (mode, type, 1) == downward
if (BLOCK_REG_PADDING (mode, type, 1) == PAD_DOWNWARD
&& size < UNITS_PER_WORD)
{
t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (arg), arg,
@ -15385,6 +15382,9 @@ aarch64_run_selftests (void)
#undef TARGET_FUNCTION_ARG_BOUNDARY
#define TARGET_FUNCTION_ARG_BOUNDARY aarch64_function_arg_boundary
#undef TARGET_FUNCTION_ARG_PADDING
#define TARGET_FUNCTION_ARG_PADDING aarch64_function_arg_padding
#undef TARGET_FUNCTION_OK_FOR_SIBCALL
#define TARGET_FUNCTION_OK_FOR_SIBCALL aarch64_function_ok_for_sibcall

View File

@ -668,11 +668,8 @@ typedef struct
} CUMULATIVE_ARGS;
#endif
#define FUNCTION_ARG_PADDING(MODE, TYPE) \
(aarch64_pad_arg_upward (MODE, TYPE) ? upward : downward)
#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
(aarch64_pad_reg_upward (MODE, TYPE, FIRST) ? upward : downward)
(aarch64_pad_reg_upward (MODE, TYPE, FIRST) ? PAD_UPWARD : PAD_DOWNWARD)
#define PAD_VARARGS_DOWN 0

View File

@ -177,7 +177,6 @@ extern bool arm_coproc_ldc_stc_legitimate_address (rtx);
#if defined TREE_CODE
extern void arm_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree);
extern bool arm_pad_arg_upward (machine_mode, const_tree);
extern bool arm_pad_reg_upward (machine_mode, tree, int);
#endif
extern int arm_apply_result_size (void);

View File

@ -186,6 +186,7 @@ static rtx arm_function_arg (cumulative_args_t, machine_mode,
const_tree, bool);
static void arm_function_arg_advance (cumulative_args_t, machine_mode,
const_tree, bool);
static pad_direction arm_function_arg_padding (machine_mode, const_tree);
static unsigned int arm_function_arg_boundary (machine_mode, const_tree);
static rtx aapcs_allocate_return_reg (machine_mode, const_tree,
const_tree);
@ -536,6 +537,8 @@ static const struct attribute_spec arm_attribute_table[] =
#define TARGET_FUNCTION_ARG arm_function_arg
#undef TARGET_FUNCTION_ARG_ADVANCE
#define TARGET_FUNCTION_ARG_ADVANCE arm_function_arg_advance
#undef TARGET_FUNCTION_ARG_PADDING
#define TARGET_FUNCTION_ARG_PADDING arm_function_arg_padding
#undef TARGET_FUNCTION_ARG_BOUNDARY
#define TARGET_FUNCTION_ARG_BOUNDARY arm_function_arg_boundary
@ -15155,22 +15158,21 @@ arm_must_pass_in_stack (machine_mode mode, const_tree type)
}
/* For use by FUNCTION_ARG_PADDING (MODE, TYPE).
Return true if an argument passed on the stack should be padded upwards,
i.e. if the least-significant byte has useful data.
For legacy APCS ABIs we use the default. For AAPCS based ABIs small
aggregate types are placed in the lowest memory address. */
/* Implement TARGET_FUNCTION_ARG_PADDING; return PAD_UPWARD if the lowest
byte of a stack argument has useful data. For legacy APCS ABIs we use
the default. For AAPCS based ABIs small aggregate types are placed
in the lowest memory address. */
bool
arm_pad_arg_upward (machine_mode mode ATTRIBUTE_UNUSED, const_tree type)
static pad_direction
arm_function_arg_padding (machine_mode mode, const_tree type)
{
if (!TARGET_AAPCS_BASED)
return DEFAULT_FUNCTION_ARG_PADDING(mode, type) == upward;
return default_function_arg_padding (mode, type);
if (type && BYTES_BIG_ENDIAN && INTEGRAL_TYPE_P (type))
return false;
return PAD_DOWNWARD;
return true;
return PAD_UPWARD;
}

View File

@ -1480,11 +1480,8 @@ typedef struct
} CUMULATIVE_ARGS;
#endif
#define FUNCTION_ARG_PADDING(MODE, TYPE) \
(arm_pad_arg_upward (MODE, TYPE) ? upward : downward)
#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
(arm_pad_reg_upward (MODE, TYPE, FIRST) ? upward : downward)
(arm_pad_reg_upward (MODE, TYPE, FIRST) ? PAD_UPWARD : PAD_DOWNWARD)
/* For AAPCS, padding should never be below the argument. For other ABIs,
* mimic the default. */

View File

@ -345,7 +345,7 @@ struct c6x_args {
c6x_init_cumulative_args (&cum, fntype, libname, n_named_args)
#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
(c6x_block_reg_pad_upward (MODE, TYPE, FIRST) ? upward : downward)
(c6x_block_reg_pad_upward (MODE, TYPE, FIRST) ? PAD_UPWARD : PAD_DOWNWARD)
#define FUNCTION_ARG_REGNO_P(r) \
(((r) >= REG_A4 && (r) <= REG_A13) || ((r) >= REG_B4 && (r) <= REG_B13))

View File

@ -125,10 +125,6 @@ do { \
ASM_OUTPUT_TYPE_DIRECTIVE (FILE, XSTR (FUN, 0), "function"); \
} while (0)
#undef FUNCTION_ARG_PADDING
#define FUNCTION_ARG_PADDING(MODE, TYPE) \
ia64_hpux_function_arg_padding ((MODE), (TYPE))
#undef PAD_VARARGS_DOWN
#define PAD_VARARGS_DOWN (!AGGREGATE_TYPE_P (type))

View File

@ -89,11 +89,6 @@ extern int ia64_dbx_register_number (int);
extern rtx ia64_return_addr_rtx (HOST_WIDE_INT, rtx);
extern void ia64_split_return_addr_rtx (rtx);
#ifdef ARGS_SIZE_RTX
/* expr.h defines ARGS_SIZE_RTX and `enum direction'. */
extern enum direction ia64_hpux_function_arg_padding (machine_mode, const_tree);
#endif /* ARGS_SIZE_RTX */
extern void ia64_hpux_handle_builtin_pragma (struct cpp_reader *);
extern void ia64_output_function_profiler (FILE *, int);
extern void ia64_profile_hook (int);

View File

@ -209,6 +209,7 @@ static rtx ia64_function_incoming_arg (cumulative_args_t,
machine_mode, const_tree, bool);
static void ia64_function_arg_advance (cumulative_args_t, machine_mode,
const_tree, bool);
static pad_direction ia64_function_arg_padding (machine_mode, const_tree);
static unsigned int ia64_function_arg_boundary (machine_mode,
const_tree);
static bool ia64_function_ok_for_sibcall (tree, tree);
@ -509,6 +510,8 @@ static const struct attribute_spec ia64_attribute_table[] =
#define TARGET_FUNCTION_INCOMING_ARG ia64_function_incoming_arg
#undef TARGET_FUNCTION_ARG_ADVANCE
#define TARGET_FUNCTION_ARG_ADVANCE ia64_function_arg_advance
#undef TARGET_FUNCTION_ARG_PADDING
#define TARGET_FUNCTION_ARG_PADDING ia64_function_arg_padding
#undef TARGET_FUNCTION_ARG_BOUNDARY
#define TARGET_FUNCTION_ARG_BOUNDARY ia64_function_arg_boundary
@ -10608,20 +10611,23 @@ ia64_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
return ia64_builtins[code];
}
/* For the HP-UX IA64 aggregate parameters are passed stored in the
/* Implement TARGET_FUNCTION_ARG_PADDING.
For the HP-UX IA64 aggregate parameters are passed stored in the
most significant bits of the stack slot. */
enum direction
ia64_hpux_function_arg_padding (machine_mode mode, const_tree type)
static pad_direction
ia64_function_arg_padding (machine_mode mode, const_tree type)
{
/* Exception to normal case for structures/unions/etc. */
/* Exception to normal case for structures/unions/etc. */
if (TARGET_HPUX
&& type
&& AGGREGATE_TYPE_P (type)
&& int_size_in_bytes (type) < UNITS_PER_WORD)
return PAD_UPWARD;
if (type && AGGREGATE_TYPE_P (type)
&& int_size_in_bytes (type) < UNITS_PER_WORD)
return upward;
/* Fall back to the default. */
return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
/* Fall back to the default. */
return default_function_arg_padding (mode, type);
}
/* Emit text to declare externally defined variables and functions, because

View File

@ -165,6 +165,7 @@ static rtx iq2000_function_arg (cumulative_args_t,
machine_mode, const_tree, bool);
static void iq2000_function_arg_advance (cumulative_args_t,
machine_mode, const_tree, bool);
static pad_direction iq2000_function_arg_padding (machine_mode, const_tree);
static unsigned int iq2000_function_arg_boundary (machine_mode,
const_tree);
static void iq2000_va_start (tree, rtx);
@ -231,6 +232,8 @@ static bool iq2000_modes_tieable_p (machine_mode, machine_mode);
#define TARGET_FUNCTION_ARG iq2000_function_arg
#undef TARGET_FUNCTION_ARG_ADVANCE
#define TARGET_FUNCTION_ARG_ADVANCE iq2000_function_arg_advance
#undef TARGET_FUNCTION_ARG_PADDING
#define TARGET_FUNCTION_ARG_PADDING iq2000_function_arg_padding
#undef TARGET_FUNCTION_ARG_BOUNDARY
#define TARGET_FUNCTION_ARG_BOUNDARY iq2000_function_arg_boundary
@ -1376,6 +1379,22 @@ iq2000_function_arg (cumulative_args_t cum_v, machine_mode mode,
return ret;
}
/* Implement TARGET_FUNCTION_ARG_PADDING. */
static pad_direction
iq2000_function_arg_padding (machine_mode mode, const_tree type)
{
return (! BYTES_BIG_ENDIAN
? PAD_UPWARD
: ((mode == BLKmode
? (type
&& TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
&& int_size_in_bytes (type) < (PARM_BOUNDARY / BITS_PER_UNIT))
: (GET_MODE_BITSIZE (mode) < PARM_BOUNDARY
&& GET_MODE_CLASS (mode) == MODE_INT))
? PAD_DOWNWARD : PAD_UPWARD));
}
static unsigned int
iq2000_function_arg_boundary (machine_mode mode, const_tree type)
{

View File

@ -308,16 +308,6 @@ typedef struct iq2000_args
#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
init_cumulative_args (& CUM, FNTYPE, LIBNAME) \
#define FUNCTION_ARG_PADDING(MODE, TYPE) \
(! BYTES_BIG_ENDIAN \
? upward \
: (((MODE) == BLKmode \
? ((TYPE) && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \
&& int_size_in_bytes (TYPE) < (PARM_BOUNDARY / BITS_PER_UNIT))\
: (GET_MODE_BITSIZE (MODE) < PARM_BOUNDARY \
&& (GET_MODE_CLASS (MODE) == MODE_INT))) \
? downward : upward))
#define FUNCTION_ARG_REGNO_P(N) \
(((N) >= GP_ARG_FIRST && (N) <= GP_ARG_LAST))

View File

@ -246,7 +246,6 @@ extern bool mips_expand_block_move (rtx, rtx, rtx);
extern void mips_expand_synci_loop (rtx, rtx);
extern void mips_init_cumulative_args (CUMULATIVE_ARGS *, tree);
extern bool mips_pad_arg_upward (machine_mode, const_tree);
extern bool mips_pad_reg_upward (machine_mode, tree);
extern bool mips_expand_ext_as_unaligned_load (rtx, rtx, HOST_WIDE_INT,

View File

@ -6117,18 +6117,17 @@ mips_get_reg_raw_mode (int regno)
return default_get_reg_raw_mode (regno);
}
/* Return true if FUNCTION_ARG_PADDING (MODE, TYPE) should return
upward rather than downward. In other words, return true if the
first byte of the stack slot has useful data, false if the last
byte does. */
/* Implement TARGET_FUNCTION_ARG_PADDING; return PAD_UPWARD if the first
byte of the stack slot has useful data, PAD_DOWNWARD if the last byte
does. */
bool
mips_pad_arg_upward (machine_mode mode, const_tree type)
static pad_direction
mips_function_arg_padding (machine_mode mode, const_tree type)
{
/* On little-endian targets, the first byte of every stack argument
is passed in the first byte of the stack slot. */
if (!BYTES_BIG_ENDIAN)
return true;
return PAD_UPWARD;
/* Otherwise, integral types are padded downward: the last byte of a
stack argument is passed in the last byte of the stack slot. */
@ -6138,22 +6137,24 @@ mips_pad_arg_upward (machine_mode mode, const_tree type)
|| FIXED_POINT_TYPE_P (type))
: (SCALAR_INT_MODE_P (mode)
|| ALL_SCALAR_FIXED_POINT_MODE_P (mode)))
return false;
return PAD_DOWNWARD;
/* Big-endian o64 pads floating-point arguments downward. */
if (mips_abi == ABI_O64)
if (type != 0 ? FLOAT_TYPE_P (type) : GET_MODE_CLASS (mode) == MODE_FLOAT)
return false;
return PAD_DOWNWARD;
/* Other types are padded upward for o32, o64, n32 and n64. */
if (mips_abi != ABI_EABI)
return true;
return PAD_UPWARD;
/* Arguments smaller than a stack slot are padded downward. */
if (mode != BLKmode)
return GET_MODE_BITSIZE (mode) >= PARM_BOUNDARY;
else
return int_size_in_bytes (type) >= (PARM_BOUNDARY / BITS_PER_UNIT);
if (mode != BLKmode
? GET_MODE_BITSIZE (mode) >= PARM_BOUNDARY
: int_size_in_bytes (type) >= (PARM_BOUNDARY / BITS_PER_UNIT))
return PAD_UPWARD;
return PAD_DOWNWARD;
}
/* Likewise BLOCK_REG_PADDING (MODE, TYPE, ...). Return !BYTES_BIG_ENDIAN
@ -6169,7 +6170,7 @@ mips_pad_reg_upward (machine_mode mode, tree type)
/* Otherwise, apply the same padding to register arguments as we do
to stack arguments. */
return mips_pad_arg_upward (mode, type);
return mips_function_arg_padding (mode, type) == PAD_UPWARD;
}
/* Return nonzero when an argument must be passed by reference. */
@ -22459,6 +22460,8 @@ mips_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
#define TARGET_FUNCTION_ARG mips_function_arg
#undef TARGET_FUNCTION_ARG_ADVANCE
#define TARGET_FUNCTION_ARG_ADVANCE mips_function_arg_advance
#undef TARGET_FUNCTION_ARG_PADDING
#define TARGET_FUNCTION_ARG_PADDING mips_function_arg_padding
#undef TARGET_FUNCTION_ARG_BOUNDARY
#define TARGET_FUNCTION_ARG_BOUNDARY mips_function_arg_boundary
#undef TARGET_GET_RAW_RESULT_MODE

View File

@ -1679,7 +1679,7 @@ FP_ASM_SPEC "\
DATA_ALIGNMENT (TYPE, ALIGN)
#define PAD_VARARGS_DOWN \
(FUNCTION_ARG_PADDING (TYPE_MODE (type), type) == downward)
(targetm.calls.function_arg_padding (TYPE_MODE (type), type) == PAD_DOWNWARD)
/* Define if operations between registers always perform the operation
on the full register even if a narrower mode is specified. */
@ -2521,11 +2521,8 @@ typedef struct mips_args {
#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
mips_init_cumulative_args (&CUM, FNTYPE)
#define FUNCTION_ARG_PADDING(MODE, TYPE) \
(mips_pad_arg_upward (MODE, TYPE) ? upward : downward)
#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
(mips_pad_reg_upward (MODE, TYPE) ? upward : downward)
(mips_pad_reg_upward (MODE, TYPE) ? PAD_UPWARD : PAD_DOWNWARD)
/* True if using EABI and varargs can be passed in floating-point
registers. Under these conditions, we need a more complex form

View File

@ -59,14 +59,8 @@ extern bool gen_ldstwm_peep (bool, int, rtx, rtx *);
extern void nios2_adjust_reg_alloc_order (void);
#ifdef TREE_CODE
#ifdef ARGS_SIZE_RTX
/* expr.h defines both ARGS_SIZE_RTX and `enum direction' */
extern enum direction nios2_function_arg_padding (machine_mode, const_tree);
extern enum direction nios2_block_reg_padding (machine_mode, tree, int);
#endif /* ARGS_SIZE_RTX */
extern pad_direction nios2_block_reg_padding (machine_mode, tree, int);
#endif /* TREE_CODE */
#endif /* RTX_CODE */
#endif /* GCC_NIOS2_PROTOS_H */

View File

@ -2983,30 +2983,31 @@ nios2_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
cum->regs_used += param_size;
}
enum direction
static pad_direction
nios2_function_arg_padding (machine_mode mode, const_tree type)
{
/* On little-endian targets, the first byte of every stack argument
is passed in the first byte of the stack slot. */
if (!BYTES_BIG_ENDIAN)
return upward;
return PAD_UPWARD;
/* Otherwise, integral types are padded downward: the last byte of a
stack argument is passed in the last byte of the stack slot. */
if (type != 0
? INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type)
: GET_MODE_CLASS (mode) == MODE_INT)
return downward;
return PAD_DOWNWARD;
/* Arguments smaller than a stack slot are padded downward. */
if (mode != BLKmode)
return (GET_MODE_BITSIZE (mode) >= PARM_BOUNDARY) ? upward : downward;
return (GET_MODE_BITSIZE (mode) >= PARM_BOUNDARY
? PAD_UPWARD : PAD_DOWNWARD);
return ((int_size_in_bytes (type) >= (PARM_BOUNDARY / BITS_PER_UNIT))
? upward : downward);
? PAD_UPWARD : PAD_DOWNWARD);
}
enum direction
pad_direction
nios2_block_reg_padding (machine_mode mode, tree type,
int first ATTRIBUTE_UNUSED)
{
@ -5009,6 +5010,9 @@ nios2_adjust_reg_alloc_order (void)
#undef TARGET_FUNCTION_ARG_ADVANCE
#define TARGET_FUNCTION_ARG_ADVANCE nios2_function_arg_advance
#undef TARGET_FUNCTION_ARG_PADDING
#define TARGET_FUNCTION_ARG_PADDING nios2_function_arg_padding
#undef TARGET_ARG_PARTIAL_BYTES
#define TARGET_ARG_PARTIAL_BYTES nios2_arg_partial_bytes

View File

@ -294,11 +294,8 @@ typedef struct nios2_args
#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS) \
do { (CUM).regs_used = 0; } while (0)
#define FUNCTION_ARG_PADDING(MODE, TYPE) \
(nios2_function_arg_padding ((MODE), (TYPE)))
#define PAD_VARARGS_DOWN \
(FUNCTION_ARG_PADDING (TYPE_MODE (type), type) == downward)
(targetm.calls.function_arg_padding (TYPE_MODE (type), type) == PAD_DOWNWARD)
#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
(nios2_block_reg_padding ((MODE), (TYPE), (FIRST)))

View File

@ -71,12 +71,6 @@ extern rtx pa_legitimize_reload_address (rtx, machine_mode,
extern rtx pa_return_addr_rtx (int, rtx);
#ifdef ARGS_SIZE_RTX
/* expr.h defines ARGS_SIZE_RTX and `enum direction' */
#ifdef TREE_CODE
extern enum direction pa_function_arg_padding (machine_mode, const_tree);
#endif
#endif /* ARGS_SIZE_RTX */
extern int pa_insn_refs_are_delayed (rtx_insn *);
extern rtx pa_get_deferred_plabel (rtx);
extern rtx pa_maybe_emit_compare_and_swap_exchange_loop (rtx, rtx, rtx);

View File

@ -172,6 +172,7 @@ static void pa_function_arg_advance (cumulative_args_t, machine_mode,
const_tree, bool);
static rtx pa_function_arg (cumulative_args_t, machine_mode,
const_tree, bool);
static pad_direction pa_function_arg_padding (machine_mode, const_tree);
static unsigned int pa_function_arg_boundary (machine_mode, const_tree);
static struct machine_function * pa_init_machine_status (void);
static reg_class_t pa_secondary_reload (bool, rtx, reg_class_t,
@ -355,6 +356,8 @@ static size_t n_deferred_plabels = 0;
#define TARGET_FUNCTION_ARG pa_function_arg
#undef TARGET_FUNCTION_ARG_ADVANCE
#define TARGET_FUNCTION_ARG_ADVANCE pa_function_arg_advance
#undef TARGET_FUNCTION_ARG_PADDING
#define TARGET_FUNCTION_ARG_PADDING pa_function_arg_padding
#undef TARGET_FUNCTION_ARG_BOUNDARY
#define TARGET_FUNCTION_ARG_BOUNDARY pa_function_arg_boundary
@ -6241,7 +6244,9 @@ pa_pass_by_reference (cumulative_args_t ca ATTRIBUTE_UNUSED,
return size <= 0 || size > 8;
}
enum direction
/* Implement TARGET_FUNCTION_ARG_PADDING. */
static pad_direction
pa_function_arg_padding (machine_mode mode, const_tree type)
{
if (mode == BLKmode
@ -6251,11 +6256,11 @@ pa_function_arg_padding (machine_mode mode, const_tree type)
|| TREE_CODE (type) == COMPLEX_TYPE
|| TREE_CODE (type) == VECTOR_TYPE)))
{
/* Return none if justification is not required. */
/* Return PAD_NONE if justification is not required. */
if (type
&& TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
&& (int_size_in_bytes (type) * BITS_PER_UNIT) % PARM_BOUNDARY == 0)
return none;
return PAD_NONE;
/* The directions set here are ignored when a BLKmode argument larger
than a word is placed in a register. Different code is used for
@ -6265,18 +6270,18 @@ pa_function_arg_padding (machine_mode mode, const_tree type)
the stack and in registers should be identical. */
if (TARGET_64BIT)
/* The 64-bit runtime specifies left justification for aggregates. */
return upward;
return PAD_UPWARD;
else
/* The 32-bit runtime architecture specifies right justification.
When the argument is passed on the stack, the argument is padded
with garbage on the left. The HP compiler pads with zeros. */
return downward;
return PAD_DOWNWARD;
}
if (GET_MODE_BITSIZE (mode) < PARM_BOUNDARY)
return downward;
return PAD_DOWNWARD;
else
return none;
return PAD_NONE;
}

View File

@ -663,11 +663,6 @@ struct hppa_args {int words, nargs_prototype, incoming, indirect; };
the standard parameter passing conventions on the RS6000. That's why
you'll see lots of similar code in rs6000.h. */
/* If defined, a C expression which determines whether, and in which
direction, to pad out an argument with extra space. */
#define FUNCTION_ARG_PADDING(MODE, TYPE) \
pa_function_arg_padding ((MODE), (TYPE))
/* Specify padding for the last element of a block move between registers
and memory.
@ -678,7 +673,7 @@ struct hppa_args {int words, nargs_prototype, incoming, indirect; };
so that there is only one element. This allows the object to be
correctly padded. */
#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
pa_function_arg_padding ((MODE), (TYPE))
targetm.calls.function_arg_padding ((MODE), (TYPE))
/* On HPPA, we emit profiling code as rtl via PROFILE_HOOK rather than

View File

@ -248,7 +248,7 @@
registers and memory. FIRST is nonzero if this is the only
element. */
#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
(!(FIRST) ? upward : FUNCTION_ARG_PADDING (MODE, TYPE))
(!(FIRST) ? PAD_UPWARD : targetm.calls.function_arg_padding (MODE, TYPE))
/* Indicate that jump tables go in the text section. */

View File

@ -344,7 +344,7 @@ extern int darwin_emit_branch_islands;
registers and memory. FIRST is nonzero if this is the only
element. */
#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
(!(FIRST) ? upward : FUNCTION_ARG_PADDING (MODE, TYPE))
(!(FIRST) ? PAD_UPWARD : targetm.calls.function_arg_padding (MODE, TYPE))
#define DOUBLE_INT_ASM_OP "\t.quad\t"

View File

@ -225,7 +225,7 @@ extern int dot_symbols;
registers and memory. FIRST is nonzero if this is the only
element. */
#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
(!(FIRST) ? upward : FUNCTION_ARG_PADDING (MODE, TYPE))
(!(FIRST) ? PAD_UPWARD : targetm.calls.function_arg_padding (MODE, TYPE))
/* FreeBSD doesn't support saving and restoring 64-bit regs with a 32-bit
kernel. This is supported when running on a 64-bit kernel with

View File

@ -340,7 +340,7 @@ extern int dot_symbols;
registers and memory. FIRST is nonzero if this is the only
element. */
#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
(!(FIRST) ? upward : FUNCTION_ARG_PADDING (MODE, TYPE))
(!(FIRST) ? PAD_UPWARD : targetm.calls.function_arg_padding (MODE, TYPE))
/* Linux doesn't support saving and restoring 64-bit regs in a 32-bit
process. */

View File

@ -196,10 +196,6 @@ extern void rs6000_xcoff_asm_output_aligned_decl_common (FILE *, tree,
unsigned HOST_WIDE_INT);
extern void rs6000_elf_declare_function_name (FILE *, const char *, tree);
extern bool rs6000_elf_in_small_data_p (const_tree);
#ifdef ARGS_SIZE_RTX
/* expr.h defines ARGS_SIZE_RTX and `enum direction' */
extern enum direction function_arg_padding (machine_mode, const_tree);
#endif /* ARGS_SIZE_RTX */
#endif /* TREE_CODE */

View File

@ -88,6 +88,8 @@
#define min(A,B) ((A) < (B) ? (A) : (B))
#define max(A,B) ((A) > (B) ? (A) : (B))
static pad_direction rs6000_function_arg_padding (machine_mode, const_tree);
/* Structure used to define the rs6000 stack */
typedef struct rs6000_stack {
int reload_completed; /* stack info won't change from here on */
@ -1809,6 +1811,8 @@ static const struct attribute_spec rs6000_attribute_table[] =
#define TARGET_FUNCTION_ARG_ADVANCE rs6000_function_arg_advance
#undef TARGET_FUNCTION_ARG
#define TARGET_FUNCTION_ARG rs6000_function_arg
#undef TARGET_FUNCTION_ARG_PADDING
#define TARGET_FUNCTION_ARG_PADDING rs6000_function_arg_padding
#undef TARGET_FUNCTION_ARG_BOUNDARY
#define TARGET_FUNCTION_ARG_BOUNDARY rs6000_function_arg_boundary
@ -11813,7 +11817,8 @@ rs6000_return_in_msb (const_tree valtype)
return (DEFAULT_ABI == ABI_ELFv2
&& BYTES_BIG_ENDIAN
&& AGGREGATE_TYPE_P (valtype)
&& FUNCTION_ARG_PADDING (TYPE_MODE (valtype), valtype) == upward);
&& rs6000_function_arg_padding (TYPE_MODE (valtype),
valtype) == PAD_UPWARD);
}
#ifdef HAVE_AS_GNU_ATTRIBUTE
@ -12030,17 +12035,13 @@ abi_v4_pass_in_fpr (machine_mode mode)
return false;
}
/* If defined, a C expression which determines whether, and in which
direction, to pad out an argument with extra space. The value
should be of type `enum direction': either `upward' to pad above
the argument, `downward' to pad below, or `none' to inhibit
padding.
/* Implement TARGET_FUNCTION_ARG_PADDING
For the AIX ABI structs are always stored left shifted in their
argument slot. */
enum direction
function_arg_padding (machine_mode mode, const_tree type)
static pad_direction
rs6000_function_arg_padding (machine_mode mode, const_tree type)
{
#ifndef AGGREGATE_PADDING_FIXED
#define AGGREGATE_PADDING_FIXED 0
@ -12052,7 +12053,7 @@ function_arg_padding (machine_mode mode, const_tree type)
if (!AGGREGATE_PADDING_FIXED)
{
/* GCC used to pass structures of the same size as integer types as
if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
if they were in fact integers, ignoring TARGET_FUNCTION_ARG_PADDING.
i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
passed padded downward, except that -mstrict-align further
muddied the water in that multi-component structures of 2 and 4
@ -12073,19 +12074,19 @@ function_arg_padding (machine_mode mode, const_tree type)
size = GET_MODE_SIZE (mode);
if (size == 1 || size == 2 || size == 4)
return downward;
return PAD_DOWNWARD;
}
return upward;
return PAD_UPWARD;
}
if (AGGREGATES_PAD_UPWARD_ALWAYS)
{
if (type != 0 && AGGREGATE_TYPE_P (type))
return upward;
return PAD_UPWARD;
}
/* Fall back to the default. */
return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
return default_function_arg_padding (mode, type);
}
/* If defined, a C expression that gives the alignment boundary, in bits,

View File

@ -1901,16 +1901,8 @@ typedef struct rs6000_args
init_cumulative_args (&CUM, NULL_TREE, LIBNAME, FALSE, TRUE, \
0, NULL_TREE, MODE)
/* If defined, a C expression which determines whether, and in which
direction, to pad out an argument with extra space. The value
should be of type `enum direction': either `upward' to pad above
the argument, `downward' to pad below, or `none' to inhibit
padding. */
#define FUNCTION_ARG_PADDING(MODE, TYPE) function_arg_padding (MODE, TYPE)
#define PAD_VARARGS_DOWN \
(FUNCTION_ARG_PADDING (TYPE_MODE (type), type) == downward)
(targetm.calls.function_arg_padding (TYPE_MODE (type), type) == PAD_DOWNWARD)
/* Output assembler code to FILE to increment profiler label # LABELNO
for profiling a function entry. */

View File

@ -248,7 +248,7 @@
registers and memory. FIRST is nonzero if this is the only
element. */
#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
(!(FIRST) ? upward : FUNCTION_ARG_PADDING (MODE, TYPE))
(!(FIRST) ? PAD_UPWARD : targetm.calls.function_arg_padding (MODE, TYPE))
/* Indicate that jump tables go in the text section. */

View File

@ -339,7 +339,7 @@ extern int darwin_emit_branch_islands;
registers and memory. FIRST is nonzero if this is the only
element. */
#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
(!(FIRST) ? upward : FUNCTION_ARG_PADDING (MODE, TYPE))
(!(FIRST) ? PAD_UPWARD : targetm.calls.function_arg_padding (MODE, TYPE))
#define DOUBLE_INT_ASM_OP "\t.quad\t"

View File

@ -225,7 +225,7 @@ extern int dot_symbols;
registers and memory. FIRST is nonzero if this is the only
element. */
#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
(!(FIRST) ? upward : FUNCTION_ARG_PADDING (MODE, TYPE))
(!(FIRST) ? PAD_UPWARD : targetm.calls.function_arg_padding (MODE, TYPE))
/* FreeBSD doesn't support saving and restoring 64-bit regs with a 32-bit
kernel. This is supported when running on a 64-bit kernel with

View File

@ -340,7 +340,7 @@ extern int dot_symbols;
registers and memory. FIRST is nonzero if this is the only
element. */
#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
(!(FIRST) ? upward : FUNCTION_ARG_PADDING (MODE, TYPE))
(!(FIRST) ? PAD_UPWARD : targetm.calls.function_arg_padding (MODE, TYPE))
/* Linux doesn't support saving and restoring 64-bit regs in a 32-bit
process. */

View File

@ -197,10 +197,6 @@ extern void rs6000_xcoff_asm_output_aligned_decl_common (FILE *, tree,
unsigned HOST_WIDE_INT);
extern void rs6000_elf_declare_function_name (FILE *, const char *, tree);
extern bool rs6000_elf_in_small_data_p (const_tree);
#ifdef ARGS_SIZE_RTX
/* expr.h defines ARGS_SIZE_RTX and `enum direction' */
extern enum direction function_arg_padding (machine_mode, const_tree);
#endif /* ARGS_SIZE_RTX */
#endif /* TREE_CODE */

View File

@ -89,6 +89,8 @@
#define min(A,B) ((A) < (B) ? (A) : (B))
#define max(A,B) ((A) > (B) ? (A) : (B))
static pad_direction rs6000_function_arg_padding (machine_mode, const_tree);
/* Structure used to define the rs6000 stack */
typedef struct rs6000_stack {
int reload_completed; /* stack info won't change from here on */
@ -1794,6 +1796,8 @@ static const struct attribute_spec rs6000_attribute_table[] =
#define TARGET_FUNCTION_ARG_ADVANCE rs6000_function_arg_advance
#undef TARGET_FUNCTION_ARG
#define TARGET_FUNCTION_ARG rs6000_function_arg
#undef TARGET_FUNCTION_ARG_PADDING
#define TARGET_FUNCTION_ARG_PADDING rs6000_function_arg_padding
#undef TARGET_FUNCTION_ARG_BOUNDARY
#define TARGET_FUNCTION_ARG_BOUNDARY rs6000_function_arg_boundary
@ -11247,7 +11251,8 @@ rs6000_return_in_msb (const_tree valtype)
return (DEFAULT_ABI == ABI_ELFv2
&& BYTES_BIG_ENDIAN
&& AGGREGATE_TYPE_P (valtype)
&& FUNCTION_ARG_PADDING (TYPE_MODE (valtype), valtype) == upward);
&& (rs6000_function_arg_padding (TYPE_MODE (valtype), valtype)
== PAD_UPWARD));
}
#ifdef HAVE_AS_GNU_ATTRIBUTE
@ -11464,17 +11469,13 @@ abi_v4_pass_in_fpr (machine_mode mode)
return false;
}
/* If defined, a C expression which determines whether, and in which
direction, to pad out an argument with extra space. The value
should be of type `enum direction': either `upward' to pad above
the argument, `downward' to pad below, or `none' to inhibit
padding.
/* Implement TARGET_FUNCTION_ARG_PADDING.
For the AIX ABI structs are always stored left shifted in their
argument slot. */
enum direction
function_arg_padding (machine_mode mode, const_tree type)
static pad_direction
rs6000_function_arg_padding (machine_mode mode, const_tree type)
{
#ifndef AGGREGATE_PADDING_FIXED
#define AGGREGATE_PADDING_FIXED 0
@ -11486,7 +11487,7 @@ function_arg_padding (machine_mode mode, const_tree type)
if (!AGGREGATE_PADDING_FIXED)
{
/* GCC used to pass structures of the same size as integer types as
if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
if they were in fact integers, ignoring TARGET_FUNCTION_ARG_PADDING.
i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
passed padded downward, except that -mstrict-align further
muddied the water in that multi-component structures of 2 and 4
@ -11507,19 +11508,19 @@ function_arg_padding (machine_mode mode, const_tree type)
size = GET_MODE_SIZE (mode);
if (size == 1 || size == 2 || size == 4)
return downward;
return PAD_DOWNWARD;
}
return upward;
return PAD_UPWARD;
}
if (AGGREGATES_PAD_UPWARD_ALWAYS)
{
if (type != 0 && AGGREGATE_TYPE_P (type))
return upward;
return PAD_UPWARD;
}
/* Fall back to the default. */
return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
return default_function_arg_padding (mode, type);
}
/* If defined, a C expression that gives the alignment boundary, in bits,

View File

@ -1803,16 +1803,8 @@ typedef struct rs6000_args
init_cumulative_args (&CUM, NULL_TREE, LIBNAME, FALSE, TRUE, \
0, NULL_TREE, MODE)
/* If defined, a C expression which determines whether, and in which
direction, to pad out an argument with extra space. The value
should be of type `enum direction': either `upward' to pad above
the argument, `downward' to pad below, or `none' to inhibit
padding. */
#define FUNCTION_ARG_PADDING(MODE, TYPE) function_arg_padding (MODE, TYPE)
#define PAD_VARARGS_DOWN \
(FUNCTION_ARG_PADDING (TYPE_MODE (type), type) == downward)
(targetm.calls.function_arg_padding (TYPE_MODE (type), type) == PAD_DOWNWARD)
/* Output assembler code to FILE to increment profiler label # LABELNO
for profiling a function entry. */

View File

@ -12124,6 +12124,18 @@ s390_function_arg (cumulative_args_t cum_v, machine_mode mode,
gcc_unreachable ();
}
/* Implement TARGET_FUNCTION_ARG_BOUNDARY. Vector arguments are
left-justified when placed on the stack during parameter passing. */
static pad_direction
s390_function_arg_padding (machine_mode mode, const_tree type)
{
if (s390_function_arg_vector (mode, type))
return PAD_UPWARD;
return default_function_arg_padding (mode, type);
}
/* Return true if return values of type TYPE should be returned
in a memory buffer whose address is passed by the caller as
hidden first argument. */
@ -15886,6 +15898,8 @@ s390_asan_shadow_offset (void)
#define TARGET_FUNCTION_ARG s390_function_arg
#undef TARGET_FUNCTION_ARG_ADVANCE
#define TARGET_FUNCTION_ARG_ADVANCE s390_function_arg_advance
#undef TARGET_FUNCTION_ARG_PADDING
#define TARGET_FUNCTION_ARG_PADDING s390_function_arg_padding
#undef TARGET_FUNCTION_VALUE
#define TARGET_FUNCTION_VALUE s390_function_value
#undef TARGET_LIBCALL_VALUE

View File

@ -273,13 +273,6 @@ extern const char *s390_host_detect_local_cpu (int argc, const char **argv);
#define STACK_SIZE_MODE (Pmode)
/* Vector arguments are left-justified when placed on the stack during
parameter passing. */
#define FUNCTION_ARG_PADDING(MODE, TYPE) \
(s390_function_arg_vector ((MODE), (TYPE)) \
? upward \
: DEFAULT_FUNCTION_ARG_PADDING ((MODE), (TYPE)))
#ifndef IN_LIBGCC2
/* Width of a word, in units (bytes). */

View File

@ -28,10 +28,6 @@ along with GCC; see the file COPYING3. If not see
extern void init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree);
#endif
extern unsigned long sparc_type_code (tree);
#ifdef ARGS_SIZE_RTX
/* expr.h defines ARGS_SIZE_RTX and `enum direction' */
extern enum direction function_arg_padding (machine_mode, const_tree);
#endif /* ARGS_SIZE_RTX */
#endif /* TREE_CODE */
extern void order_regs_for_local_alloc (void);

View File

@ -648,6 +648,7 @@ static rtx sparc_function_arg (cumulative_args_t,
machine_mode, const_tree, bool);
static rtx sparc_function_incoming_arg (cumulative_args_t,
machine_mode, const_tree, bool);
static pad_direction sparc_function_arg_padding (machine_mode, const_tree);
static unsigned int sparc_function_arg_boundary (machine_mode,
const_tree);
static int sparc_arg_partial_bytes (cumulative_args_t,
@ -796,6 +797,8 @@ char sparc_hard_reg_printed[8];
#define TARGET_FUNCTION_ARG sparc_function_arg
#undef TARGET_FUNCTION_INCOMING_ARG
#define TARGET_FUNCTION_INCOMING_ARG sparc_function_incoming_arg
#undef TARGET_FUNCTION_ARG_PADDING
#define TARGET_FUNCTION_ARG_PADDING sparc_function_arg_padding
#undef TARGET_FUNCTION_ARG_BOUNDARY
#define TARGET_FUNCTION_ARG_BOUNDARY sparc_function_arg_boundary
@ -7315,18 +7318,17 @@ sparc_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
}
}
/* Handle the FUNCTION_ARG_PADDING macro.
For the 64-bit ABI structs are always stored left shifted in their
argument slot. */
/* Implement TARGET_FUNCTION_ARG_PADDING. For the 64-bit ABI structs
are always stored left shifted in their argument slot. */
enum direction
function_arg_padding (machine_mode mode, const_tree type)
static pad_direction
sparc_function_arg_padding (machine_mode mode, const_tree type)
{
if (TARGET_ARCH64 && type && AGGREGATE_TYPE_P (type))
return upward;
return PAD_UPWARD;
/* Fall back to the default. */
return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
return default_function_arg_padding (mode, type);
}
/* Handle the TARGET_RETURN_IN_MEMORY target hook.

View File

@ -1215,14 +1215,6 @@ struct sparc_args {
#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS) \
init_cumulative_args (& (CUM), (FNTYPE), (LIBNAME), (FNDECL));
/* If defined, a C expression which determines whether, and in which direction,
to pad out an argument with extra space. The value should be of type
`enum direction': either `upward' to pad above the argument,
`downward' to pad below, or `none' to inhibit padding. */
#define FUNCTION_ARG_PADDING(MODE, TYPE) \
function_arg_padding ((MODE), (TYPE))
/* Generate the special assembly code needed to tell the assembler whatever
it might need to know about the return value of a function.

View File

@ -3873,6 +3873,14 @@ spu_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
: HARD_REGNO_NREGS (cum, mode));
}
/* Implement TARGET_FUNCTION_ARG_PADDING. */
static pad_direction
spu_function_arg_padding (machine_mode, const_tree)
{
return PAD_UPWARD;
}
/* Variable sized types are passed by reference. */
static bool
spu_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED,
@ -7265,6 +7273,9 @@ static const struct attribute_spec spu_attribute_table[] =
#undef TARGET_FUNCTION_ARG_ADVANCE
#define TARGET_FUNCTION_ARG_ADVANCE spu_function_arg_advance
#undef TARGET_FUNCTION_ARG_PADDING
#define TARGET_FUNCTION_ARG_PADDING spu_function_arg_padding
#undef TARGET_MUST_PASS_IN_STACK
#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size

View File

@ -329,8 +329,6 @@ targetm.resolve_overloaded_builtin = spu_resolve_overloaded_builtin; \
? (4 - GET_MODE_SIZE (MODE)) \
: 0)
#define FUNCTION_ARG_PADDING(MODE,TYPE) upward
#define PAD_VARARGS_DOWN 0
#define FUNCTION_ARG_REGNO_P(N) ((N) >= (FIRST_ARG_REGNUM) && (N) <= (LAST_ARG_REGNUM))

View File

@ -230,6 +230,22 @@ enum optimization_type {
OPTIMIZE_FOR_SIZE
};
/* Enumerates a padding direction. */
enum pad_direction {
/* No padding is required. */
PAD_NONE,
/* Insert padding above the data, i.e. at higher memeory addresses
when dealing with memory, and at the most significant end when
dealing with registers. */
PAD_UPWARD,
/* Insert padding below the data, i.e. at lower memeory addresses
when dealing with memory, and at the least significant end when
dealing with registers. */
PAD_DOWNWARD
};
/* Possible initialization status of a variable. When requested
by the user, this information is tracked and recorded in the DWARF
debug information, along with the variable's location. */

View File

@ -1355,24 +1355,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define SET_RATIO(speed) MOVE_RATIO (speed)
#endif
/* Supply a default definition for FUNCTION_ARG_PADDING:
usually pad upward, but pad short args downward on
big-endian machines. */
#define DEFAULT_FUNCTION_ARG_PADDING(MODE, TYPE) \
(! BYTES_BIG_ENDIAN \
? upward \
: (((MODE) == BLKmode \
? ((TYPE) && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \
&& int_size_in_bytes (TYPE) < (PARM_BOUNDARY / BITS_PER_UNIT)) \
: GET_MODE_BITSIZE (MODE) < PARM_BOUNDARY) \
? downward : upward))
#ifndef FUNCTION_ARG_PADDING
#define FUNCTION_ARG_PADDING(MODE, TYPE) \
DEFAULT_FUNCTION_ARG_PADDING ((MODE), (TYPE))
#endif
/* Supply a default definition of STACK_SAVEAREA_MODE for emit_stack_save.
Normally move_insn, so Pmode stack pointer. */

View File

@ -4096,21 +4096,21 @@ slot that is in the middle of the quad word instead of starting at the
top.
@end defmac
@defmac FUNCTION_ARG_PADDING (@var{mode}, @var{type})
If defined, a C expression which determines whether, and in which direction,
to pad out an argument with extra space. The value should be of type
@code{enum direction}: either @code{upward} to pad above the argument,
@code{downward} to pad below, or @code{none} to inhibit padding.
@deftypefn {Target Hook} pad_direction TARGET_FUNCTION_ARG_PADDING (machine_mode @var{mode}, const_tree @var{type})
This hook determines whether, and in which direction, to pad out
an argument of mode @var{mode} and type @var{type}. It returns
@code{PAD_UPWARD} to insert padding above the argument, @code{PAD_DOWNWARD}
to insert padding below the argument, or @code{PAD_NONE} to inhibit padding.
The @emph{amount} of padding is not controlled by this macro, but by the
target hook @code{TARGET_FUNCTION_ARG_ROUND_BOUNDARY}. It is
always just enough to reach the next multiple of that boundary.
The @emph{amount} of padding is not controlled by this hook, but by
@code{TARGET_FUNCTION_ARG_ROUND_BOUNDARY}. It is always just enough
to reach the next multiple of that boundary.
This macro has a default definition which is right for most systems.
This hook has a default definition that is right for most systems.
For little-endian machines, the default is to pad upward. For
big-endian machines, the default is to pad downward for an argument of
constant size shorter than an @code{int}, and upward otherwise.
@end defmac
@end deftypefn
@defmac PAD_VARARGS_DOWN
If defined, a C expression which determines whether the default

View File

@ -3363,21 +3363,7 @@ slot that is in the middle of the quad word instead of starting at the
top.
@end defmac
@defmac FUNCTION_ARG_PADDING (@var{mode}, @var{type})
If defined, a C expression which determines whether, and in which direction,
to pad out an argument with extra space. The value should be of type
@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 not controlled by this macro, but by the
target hook @code{TARGET_FUNCTION_ARG_ROUND_BOUNDARY}. It is
always just enough to reach the next multiple of that boundary.
This macro has a default definition which is right for most systems.
For little-endian machines, the default is to pad upward. For
big-endian machines, the default is to pad downward for an argument of
constant size shorter than an @code{int}, and upward otherwise.
@end defmac
@hook TARGET_FUNCTION_ARG_PADDING
@defmac PAD_VARARGS_DOWN
If defined, a C expression which determines whether the default

View File

@ -2150,7 +2150,7 @@ emit_group_load_1 (rtx *tmps, rtx dst, rtx orig_src, tree type, int ssize)
if (
#ifdef BLOCK_REG_PADDING
BLOCK_REG_PADDING (GET_MODE (orig_src), type, i == start)
== (BYTES_BIG_ENDIAN ? upward : downward)
== (BYTES_BIG_ENDIAN ? PAD_UPWARD : PAD_DOWNWARD)
#else
BYTES_BIG_ENDIAN
#endif
@ -2564,7 +2564,7 @@ emit_group_store (rtx orig_dst, rtx src, tree type ATTRIBUTE_UNUSED, int ssize)
if (
#ifdef BLOCK_REG_PADDING
BLOCK_REG_PADDING (GET_MODE (orig_dst), type, i == start)
== (BYTES_BIG_ENDIAN ? upward : downward)
== (BYTES_BIG_ENDIAN ? PAD_UPWARD : PAD_DOWNWARD)
#else
BYTES_BIG_ENDIAN
#endif
@ -4130,7 +4130,7 @@ emit_single_push_insn_1 (machine_mode mode, rtx x, tree type)
then store X into the stack location using an offset. This is
because emit_move_insn does not know how to pad; it does not have
access to type. */
else if (FUNCTION_ARG_PADDING (mode, type) == downward)
else if (targetm.calls.function_arg_padding (mode, type) == PAD_DOWNWARD)
{
unsigned padding_size = rounded_size - GET_MODE_SIZE (mode);
HOST_WIDE_INT offset;
@ -4274,18 +4274,19 @@ emit_push_insn (rtx x, machine_mode mode, tree type, rtx size,
rtx alignment_pad, bool sibcall_p)
{
rtx xinner;
enum direction stack_direction = STACK_GROWS_DOWNWARD ? downward : upward;
pad_direction stack_direction
= STACK_GROWS_DOWNWARD ? PAD_DOWNWARD : PAD_UPWARD;
/* Decide where to pad the argument: `downward' for below,
`upward' for above, or `none' for don't pad it.
/* Decide where to pad the argument: PAD_DOWNWARD for below,
PAD_UPWARD for above, or PAD_NONE for don't pad it.
Default is below for small data on big-endian machines; else above. */
enum direction where_pad = FUNCTION_ARG_PADDING (mode, type);
pad_direction where_pad = targetm.calls.function_arg_padding (mode, type);
/* Invert direction if stack is post-decrement.
FIXME: why? */
if (STACK_PUSH_CODE == POST_DEC)
if (where_pad != none)
where_pad = (where_pad == downward ? upward : downward);
if (where_pad != PAD_NONE)
where_pad = (where_pad == PAD_DOWNWARD ? PAD_UPWARD : PAD_DOWNWARD);
xinner = x;
@ -4357,7 +4358,7 @@ emit_push_insn (rtx x, machine_mode mode, tree type, rtx size,
or if padding below and stack grows up.
But if space already allocated, this has already been done. */
if (extra && args_addr == 0
&& where_pad != none && where_pad != stack_direction)
&& where_pad != PAD_NONE && where_pad != stack_direction)
anti_adjust_stack (GEN_INT (extra));
move_by_pieces (NULL, xinner, INTVAL (size) - used, align, 0);
@ -4386,7 +4387,7 @@ emit_push_insn (rtx x, machine_mode mode, tree type, rtx size,
A single stack adjust will do. */
if (! args_addr)
{
temp = push_block (size, extra, where_pad == downward);
temp = push_block (size, extra, where_pad == PAD_DOWNWARD);
extra = 0;
}
else if (CONST_INT_P (args_so_far))
@ -4480,7 +4481,7 @@ emit_push_insn (rtx x, machine_mode mode, tree type, rtx size,
or if padding below and stack grows up.
But if space already allocated, this has already been done. */
if (extra && args_addr == 0
&& where_pad != none && where_pad != stack_direction)
&& where_pad != PAD_NONE && where_pad != stack_direction)
anti_adjust_stack (GEN_INT (extra));
/* If we make space by pushing it, we might as well push
@ -4531,7 +4532,7 @@ emit_push_insn (rtx x, machine_mode mode, tree type, rtx size,
or if padding below and stack grows up.
But if space already allocated, this has already been done. */
if (extra && args_addr == 0
&& where_pad != none && where_pad != stack_direction)
&& where_pad != PAD_NONE && where_pad != stack_direction)
anti_adjust_stack (GEN_INT (extra));
#ifdef PUSH_ROUNDING

View File

@ -2713,7 +2713,7 @@ assign_parm_find_stack_rtl (tree parm, struct assign_parm_data_one *data)
is TARGET_FUNCTION_ARG_BOUNDARY. If we're using slot_offset, we're
intentionally forcing upward padding. Otherwise we have to come
up with a guess at the alignment based on OFFSET_RTX. */
if (data->locate.where_pad != downward || data->entry_parm)
if (data->locate.where_pad != PAD_DOWNWARD || data->entry_parm)
align = boundary;
else if (CONST_INT_P (offset_rtx))
{
@ -2867,7 +2867,7 @@ assign_parm_setup_block_p (struct assign_parm_data_one *data)
if (REG_P (data->entry_parm)
&& GET_MODE_SIZE (data->promoted_mode) < UNITS_PER_WORD
&& (BLOCK_REG_PADDING (data->passed_mode, data->passed_type, 1)
== (BYTES_BIG_ENDIAN ? upward : downward)))
== (BYTES_BIG_ENDIAN ? PAD_UPWARD : PAD_DOWNWARD)))
return true;
#endif
@ -2985,7 +2985,7 @@ assign_parm_setup_block (struct assign_parm_data_all *all,
#ifdef BLOCK_REG_PADDING
&& (size == UNITS_PER_WORD
|| (BLOCK_REG_PADDING (mode, data->passed_type, 1)
!= (BYTES_BIG_ENDIAN ? upward : downward)))
!= (BYTES_BIG_ENDIAN ? PAD_UPWARD : PAD_DOWNWARD)))
#endif
)
{
@ -3025,7 +3025,7 @@ assign_parm_setup_block (struct assign_parm_data_all *all,
gcc_checking_assert (BYTES_BIG_ENDIAN
&& (BLOCK_REG_PADDING (mode,
data->passed_type, 1)
== upward));
== PAD_UPWARD));
int by = (UNITS_PER_WORD - size) * BITS_PER_UNIT;
@ -3046,7 +3046,7 @@ assign_parm_setup_block (struct assign_parm_data_all *all,
else if (size != UNITS_PER_WORD
#ifdef BLOCK_REG_PADDING
&& (BLOCK_REG_PADDING (mode, data->passed_type, 1)
== downward)
== PAD_DOWNWARD)
#else
&& BYTES_BIG_ENDIAN
#endif
@ -3070,7 +3070,7 @@ assign_parm_setup_block (struct assign_parm_data_all *all,
#ifdef BLOCK_REG_PADDING
gcc_checking_assert (BLOCK_REG_PADDING (GET_MODE (mem),
data->passed_type, 0)
== upward);
== PAD_UPWARD);
#endif
emit_move_insn (mem, entry_parm);
}
@ -4098,7 +4098,7 @@ gimplify_parameters (void)
rounding affects the initial and starting offsets, but not the argument
size.
The second, controlled by FUNCTION_ARG_PADDING and PARM_BOUNDARY,
The second, controlled by TARGET_FUNCTION_ARG_PADDING and PARM_BOUNDARY,
optionally rounds the size of the parm to PARM_BOUNDARY. The
initial offset is not affected by this rounding, while the size always
is and the starting offset may be. */
@ -4116,7 +4116,7 @@ locate_and_pad_parm (machine_mode passed_mode, tree type, int in_regs,
struct locate_and_pad_arg_data *locate)
{
tree sizetree;
enum direction where_pad;
pad_direction where_pad;
unsigned int boundary, round_boundary;
int part_size_in_regs;
@ -4142,7 +4142,7 @@ locate_and_pad_parm (machine_mode passed_mode, tree type, int in_regs,
sizetree
= type ? size_in_bytes (type) : size_int (GET_MODE_SIZE (passed_mode));
where_pad = FUNCTION_ARG_PADDING (passed_mode, type);
where_pad = targetm.calls.function_arg_padding (passed_mode, type);
boundary = targetm.calls.function_arg_boundary (passed_mode, type);
round_boundary = targetm.calls.function_arg_round_boundary (passed_mode,
type);
@ -4191,7 +4191,7 @@ locate_and_pad_parm (machine_mode passed_mode, tree type, int in_regs,
{
tree s2 = sizetree;
if (where_pad != none
if (where_pad != PAD_NONE
&& (!tree_fits_uhwi_p (sizetree)
|| (tree_to_uhwi (sizetree) * BITS_PER_UNIT) % round_boundary))
s2 = round_up (s2, round_boundary / BITS_PER_UNIT);
@ -4216,7 +4216,7 @@ locate_and_pad_parm (machine_mode passed_mode, tree type, int in_regs,
/* Pad_below needs the pre-rounded size to know how much to pad
below. */
locate->offset = locate->slot_offset;
if (where_pad == downward)
if (where_pad == PAD_DOWNWARD)
pad_below (&locate->offset, passed_mode, sizetree);
}
@ -4235,10 +4235,10 @@ locate_and_pad_parm (machine_mode passed_mode, tree type, int in_regs,
/* Pad_below needs the pre-rounded size to know how much to pad below
so this must be done before rounding up. */
locate->offset = locate->slot_offset;
if (where_pad == downward)
if (where_pad == PAD_DOWNWARD)
pad_below (&locate->offset, passed_mode, sizetree);
if (where_pad != none
if (where_pad != PAD_NONE
&& (!tree_fits_uhwi_p (sizetree)
|| (tree_to_uhwi (sizetree) * BITS_PER_UNIT) % round_boundary))
sizetree = round_up (sizetree, round_boundary / BITS_PER_UNIT);

View File

@ -469,8 +469,6 @@ set_loops_for_fn (struct function *fn, struct loops *loops)
data structures. */
extern struct machine_function * (*init_machine_status) (void);
enum direction {none, upward, downward};
/* Structure to record the size of a sequence of arguments
as the sum of a tree-expression and a constant. This structure is
also used to store offsets from the stack, which might be negative,
@ -499,7 +497,7 @@ struct locate_and_pad_arg_data
force alignment for the next argument. */
struct args_size alignment_pad;
/* Which way we should pad this arg. */
enum direction where_pad;
pad_direction where_pad;
/* slot_offset is at least this aligned. */
unsigned int boundary;
};

View File

@ -912,7 +912,7 @@ extern void fancy_abort (const char *, int, const char *)
CLEAR_BY_PIECES_P MOVE_BY_PIECES_P SET_BY_PIECES_P \
STORE_BY_PIECES_P TARGET_FLT_EVAL_METHOD \
HARD_REGNO_CALL_PART_CLOBBERED HARD_REGNO_MODE_OK \
MODES_TIEABLE_P
MODES_TIEABLE_P FUNCTION_ARG_PADDING
/* Target macros only used for code built for the target, that have
moved to libgcc-tm.h or have never been present elsewhere. */

View File

@ -4533,6 +4533,24 @@ used for arguments without any special help.",
(cumulative_args_t ca, machine_mode mode, const_tree type, bool named),
default_function_arg_advance)
DEFHOOK
(function_arg_padding,
"This hook determines whether, and in which direction, to pad out\n\
an argument of mode @var{mode} and type @var{type}. It returns\n\
@code{PAD_UPWARD} to insert padding above the argument, @code{PAD_DOWNWARD}\n\
to insert padding below the argument, or @code{PAD_NONE} to inhibit padding.\n\
\n\
The @emph{amount} of padding is not controlled by this hook, but by\n\
@code{TARGET_FUNCTION_ARG_ROUND_BOUNDARY}. It is always just enough\n\
to reach the next multiple of that boundary.\n\
\n\
This hook has a default definition that is right for most systems.\n\
For little-endian machines, the default is to pad upward. For\n\
big-endian machines, the default is to pad downward for an argument of\n\
constant size shorter than an @code{int}, and upward otherwise.",
pad_direction, (machine_mode mode, const_tree type),
default_function_arg_padding)
/* Return zero if the argument described by the state of CA should
be placed on a stack, or a hard register in which to store the
argument. The values MODE, TYPE, and NAMED describe that

View File

@ -734,6 +734,31 @@ default_function_arg_advance (cumulative_args_t ca ATTRIBUTE_UNUSED,
gcc_unreachable ();
}
/* Default implementation of TARGET_FUNCTION_ARG_PADDING: usually pad
upward, but pad short args downward on big-endian machines. */
pad_direction
default_function_arg_padding (machine_mode mode, const_tree type)
{
if (!BYTES_BIG_ENDIAN)
return PAD_UPWARD;
unsigned HOST_WIDE_INT size;
if (mode == BLKmode)
{
if (!type || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
return PAD_UPWARD;
size = int_size_in_bytes (type);
}
else
size = GET_MODE_SIZE (mode);
if (size < (PARM_BOUNDARY / BITS_PER_UNIT))
return PAD_DOWNWARD;
return PAD_UPWARD;
}
rtx
default_function_arg (cumulative_args_t ca ATTRIBUTE_UNUSED,
machine_mode mode ATTRIBUTE_UNUSED,

View File

@ -132,6 +132,7 @@ extern const char *hook_invalid_arg_for_unprototyped_fn
(const_tree, const_tree, const_tree);
extern void default_function_arg_advance
(cumulative_args_t, machine_mode, const_tree, bool);
extern pad_direction default_function_arg_padding (machine_mode, const_tree);
extern rtx default_function_arg
(cumulative_args_t, machine_mode, const_tree, bool);
extern rtx default_function_incoming_arg