From d7ab0e3d8dc51b19528c1453940771c32f7e3bc4 Mon Sep 17 00:00:00 2001 From: rsandifo Date: Mon, 4 Sep 2017 10:50:38 +0000 Subject: [PATCH] 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 Alan Hayward David Sherwood 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@251648 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 125 ++++++++++++++++++++++++++++++ gcc/calls.c | 23 +++--- gcc/config/aarch64/aarch64-protos.h | 1 - gcc/config/aarch64/aarch64.c | 24 +++--- gcc/config/aarch64/aarch64.h | 5 +- gcc/config/arm/arm-protos.h | 1 - gcc/config/arm/arm.c | 22 +++--- gcc/config/arm/arm.h | 5 +- gcc/config/c6x/c6x.h | 2 +- gcc/config/ia64/hpux.h | 4 - gcc/config/ia64/ia64-protos.h | 5 -- gcc/config/ia64/ia64.c | 26 ++++--- gcc/config/iq2000/iq2000.c | 19 +++++ gcc/config/iq2000/iq2000.h | 10 --- gcc/config/mips/mips-protos.h | 1 - gcc/config/mips/mips.c | 33 ++++---- gcc/config/mips/mips.h | 7 +- gcc/config/nios2/nios2-protos.h | 10 +-- gcc/config/nios2/nios2.c | 16 ++-- gcc/config/nios2/nios2.h | 5 +- gcc/config/pa/pa-protos.h | 6 -- gcc/config/pa/pa.c | 19 +++-- gcc/config/pa/pa.h | 7 +- gcc/config/powerpcspe/aix.h | 2 +- gcc/config/powerpcspe/darwin.h | 2 +- gcc/config/powerpcspe/freebsd64.h | 2 +- gcc/config/powerpcspe/linux64.h | 2 +- gcc/config/powerpcspe/powerpcspe-protos.h | 4 - gcc/config/powerpcspe/powerpcspe.c | 27 +++---- gcc/config/powerpcspe/powerpcspe.h | 10 +-- gcc/config/rs6000/aix.h | 2 +- gcc/config/rs6000/darwin.h | 2 +- gcc/config/rs6000/freebsd64.h | 2 +- gcc/config/rs6000/linux64.h | 2 +- gcc/config/rs6000/rs6000-protos.h | 4 - gcc/config/rs6000/rs6000.c | 27 +++---- gcc/config/rs6000/rs6000.h | 10 +-- gcc/config/s390/s390.c | 14 ++++ gcc/config/s390/s390.h | 7 -- gcc/config/sparc/sparc-protos.h | 4 - gcc/config/sparc/sparc.c | 16 ++-- gcc/config/sparc/sparc.h | 8 -- gcc/config/spu/spu.c | 11 +++ gcc/config/spu/spu.h | 2 - gcc/coretypes.h | 16 ++++ gcc/defaults.h | 18 ----- gcc/doc/tm.texi | 20 ++--- gcc/doc/tm.texi.in | 16 +--- gcc/expr.c | 27 +++---- gcc/function.c | 26 +++---- gcc/function.h | 4 +- gcc/system.h | 2 +- gcc/target.def | 18 +++++ gcc/targhooks.c | 25 ++++++ gcc/targhooks.h | 1 + 55 files changed, 418 insertions(+), 291 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index baac77361e5..238317ea25e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -2,6 +2,131 @@ Alan Hayward David Sherwood + * 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 + Alan Hayward + David Sherwood + * target.def (modes_tieable_p): New hook. * doc/tm.texi (MODES_TIEABLE_P): Replace with... (TARGET_MODES_TIEABLE_P): ...this. diff --git a/gcc/calls.c b/gcc/calls.c index 4b34ab23bb4..e7572343ba8 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -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; diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h index 8bd936c5f41..a2debe1bf7f 100644 --- a/gcc/config/aarch64/aarch64-protos.h +++ b/gcc/config/aarch64/aarch64-protos.h @@ -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); diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index a231bace4d3..65a8df1a1ff 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -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 diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h index 3332b33d996..8fada9ed5bf 100644 --- a/gcc/config/aarch64/aarch64.h +++ b/gcc/config/aarch64/aarch64.h @@ -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 diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index 7fc2b603ced..4538078fe60 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -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); diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index c7a45963e50..e31ab608dd3 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -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; } diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index 67b4cada8b5..5fdb65be646 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -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. */ diff --git a/gcc/config/c6x/c6x.h b/gcc/config/c6x/c6x.h index 8c0cbc927a0..d0b98f8ce8c 100644 --- a/gcc/config/c6x/c6x.h +++ b/gcc/config/c6x/c6x.h @@ -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)) diff --git a/gcc/config/ia64/hpux.h b/gcc/config/ia64/hpux.h index 9e69be3f004..5c8e43fcfbb 100644 --- a/gcc/config/ia64/hpux.h +++ b/gcc/config/ia64/hpux.h @@ -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)) diff --git a/gcc/config/ia64/ia64-protos.h b/gcc/config/ia64/ia64-protos.h index 918afbcc783..cbabbd3b757 100644 --- a/gcc/config/ia64/ia64-protos.h +++ b/gcc/config/ia64/ia64-protos.h @@ -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); diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index febadda1c74..8a3c875cd06 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -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. */ - - if (type && AGGREGATE_TYPE_P (type) - && int_size_in_bytes (type) < UNITS_PER_WORD) - return upward; + /* 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; - /* 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 diff --git a/gcc/config/iq2000/iq2000.c b/gcc/config/iq2000/iq2000.c index a792a98d227..460e38d2df1 100644 --- a/gcc/config/iq2000/iq2000.c +++ b/gcc/config/iq2000/iq2000.c @@ -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) { diff --git a/gcc/config/iq2000/iq2000.h b/gcc/config/iq2000/iq2000.h index 9855255ad2b..dfb1e1fda2b 100644 --- a/gcc/config/iq2000/iq2000.h +++ b/gcc/config/iq2000/iq2000.h @@ -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)) diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h index 1ec9669b0cd..139209c44a5 100644 --- a/gcc/config/mips/mips-protos.h +++ b/gcc/config/mips/mips-protos.h @@ -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, diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 7c70c6727b8..4f7d5bd6f41 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -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 diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index 45dd41df665..f598c32bb43 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -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 diff --git a/gcc/config/nios2/nios2-protos.h b/gcc/config/nios2/nios2-protos.h index a660241b70d..4478334970c 100644 --- a/gcc/config/nios2/nios2-protos.h +++ b/gcc/config/nios2/nios2-protos.h @@ -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 */ - -#endif /* TREE_CODE */ +extern pad_direction nios2_block_reg_padding (machine_mode, tree, int); + #endif /* RTX_CODE */ #endif /* GCC_NIOS2_PROTOS_H */ diff --git a/gcc/config/nios2/nios2.c b/gcc/config/nios2/nios2.c index fa7f14e0f55..893ddd19e59 100644 --- a/gcc/config/nios2/nios2.c +++ b/gcc/config/nios2/nios2.c @@ -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 diff --git a/gcc/config/nios2/nios2.h b/gcc/config/nios2/nios2.h index 04c78b7ba2e..3e26cb67247 100644 --- a/gcc/config/nios2/nios2.h +++ b/gcc/config/nios2/nios2.h @@ -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))) diff --git a/gcc/config/pa/pa-protos.h b/gcc/config/pa/pa-protos.h index 3d128341d6b..ba496f966d5 100644 --- a/gcc/config/pa/pa-protos.h +++ b/gcc/config/pa/pa-protos.h @@ -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); diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index 0c49cf0c0c4..3ce8b3c141f 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -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; } diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h index 513051c0c84..37881dcfb67 100644 --- a/gcc/config/pa/pa.h +++ b/gcc/config/pa/pa.h @@ -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 diff --git a/gcc/config/powerpcspe/aix.h b/gcc/config/powerpcspe/aix.h index b90e2b06519..6c91a90cc00 100644 --- a/gcc/config/powerpcspe/aix.h +++ b/gcc/config/powerpcspe/aix.h @@ -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. */ diff --git a/gcc/config/powerpcspe/darwin.h b/gcc/config/powerpcspe/darwin.h index 61e5e836de0..51474ae00c7 100644 --- a/gcc/config/powerpcspe/darwin.h +++ b/gcc/config/powerpcspe/darwin.h @@ -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" diff --git a/gcc/config/powerpcspe/freebsd64.h b/gcc/config/powerpcspe/freebsd64.h index d75ac2b9a5d..f1987918bf8 100644 --- a/gcc/config/powerpcspe/freebsd64.h +++ b/gcc/config/powerpcspe/freebsd64.h @@ -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 diff --git a/gcc/config/powerpcspe/linux64.h b/gcc/config/powerpcspe/linux64.h index 71e35b709ad..88cbeca6fe9 100644 --- a/gcc/config/powerpcspe/linux64.h +++ b/gcc/config/powerpcspe/linux64.h @@ -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. */ diff --git a/gcc/config/powerpcspe/powerpcspe-protos.h b/gcc/config/powerpcspe/powerpcspe-protos.h index 0f3e492a8a1..20587ba17a6 100644 --- a/gcc/config/powerpcspe/powerpcspe-protos.h +++ b/gcc/config/powerpcspe/powerpcspe-protos.h @@ -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 */ diff --git a/gcc/config/powerpcspe/powerpcspe.c b/gcc/config/powerpcspe/powerpcspe.c index 0b220361a58..7dd2170f0a8 100644 --- a/gcc/config/powerpcspe/powerpcspe.c +++ b/gcc/config/powerpcspe/powerpcspe.c @@ -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, diff --git a/gcc/config/powerpcspe/powerpcspe.h b/gcc/config/powerpcspe/powerpcspe.h index c008b5f6a7c..548e615ab37 100644 --- a/gcc/config/powerpcspe/powerpcspe.h +++ b/gcc/config/powerpcspe/powerpcspe.h @@ -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. */ diff --git a/gcc/config/rs6000/aix.h b/gcc/config/rs6000/aix.h index b90e2b06519..6c91a90cc00 100644 --- a/gcc/config/rs6000/aix.h +++ b/gcc/config/rs6000/aix.h @@ -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. */ diff --git a/gcc/config/rs6000/darwin.h b/gcc/config/rs6000/darwin.h index 90fc757532a..aeb4762387f 100644 --- a/gcc/config/rs6000/darwin.h +++ b/gcc/config/rs6000/darwin.h @@ -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" diff --git a/gcc/config/rs6000/freebsd64.h b/gcc/config/rs6000/freebsd64.h index d75ac2b9a5d..f1987918bf8 100644 --- a/gcc/config/rs6000/freebsd64.h +++ b/gcc/config/rs6000/freebsd64.h @@ -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 diff --git a/gcc/config/rs6000/linux64.h b/gcc/config/rs6000/linux64.h index f119457ffe7..1dbb3d94a73 100644 --- a/gcc/config/rs6000/linux64.h +++ b/gcc/config/rs6000/linux64.h @@ -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. */ diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h index 95fb3ad3149..f9be5d3ff93 100644 --- a/gcc/config/rs6000/rs6000-protos.h +++ b/gcc/config/rs6000/rs6000-protos.h @@ -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 */ diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 09c7f133e42..773745e5930 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -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, diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index a462da76968..9bf32dbe9b9 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -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. */ diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index fa45c1927ea..3fd1ff618d9 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -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 diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h index f9df2efbd57..34fffb4a277 100644 --- a/gcc/config/s390/s390.h +++ b/gcc/config/s390/s390.h @@ -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). */ diff --git a/gcc/config/sparc/sparc-protos.h b/gcc/config/sparc/sparc-protos.h index 311688faf7e..507f0b1bd41 100644 --- a/gcc/config/sparc/sparc-protos.h +++ b/gcc/config/sparc/sparc-protos.h @@ -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); diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 23584124158..2fa22b8ebf1 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -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. diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index 1aa46d33b66..36f7667100e 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -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. diff --git a/gcc/config/spu/spu.c b/gcc/config/spu/spu.c index 9d9b103ea0d..d9a0435a1b6 100644 --- a/gcc/config/spu/spu.c +++ b/gcc/config/spu/spu.c @@ -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 diff --git a/gcc/config/spu/spu.h b/gcc/config/spu/spu.h index d5d43529dc7..c995d5303a8 100644 --- a/gcc/config/spu/spu.h +++ b/gcc/config/spu/spu.h @@ -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)) diff --git a/gcc/coretypes.h b/gcc/coretypes.h index 21ea8d97a0d..410583e1ce2 100644 --- a/gcc/coretypes.h +++ b/gcc/coretypes.h @@ -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. */ diff --git a/gcc/defaults.h b/gcc/defaults.h index 072ef6b6d17..d27eddf55b0 100644 --- a/gcc/defaults.h +++ b/gcc/defaults.h @@ -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. */ diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 6697ddd343c..2e22047d8f7 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -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 diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 274f79ed5a2..8c35a0a0261 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -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 diff --git a/gcc/expr.c b/gcc/expr.c index 7fcf2f7eea4..b825f49fb49 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -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 diff --git a/gcc/function.c b/gcc/function.c index 7d952e7994b..f221d6ca7db 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -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); diff --git a/gcc/function.h b/gcc/function.h index 0f34bcd6123..91e01383252 100644 --- a/gcc/function.h +++ b/gcc/function.h @@ -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; }; diff --git a/gcc/system.h b/gcc/system.h index 1e6c17cfa57..672fe2d3ceb 100644 --- a/gcc/system.h +++ b/gcc/system.h @@ -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. */ diff --git a/gcc/target.def b/gcc/target.def index b6bcb86a995..a94175781aa 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -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 diff --git a/gcc/targhooks.c b/gcc/targhooks.c index 78657fbd410..0a427478536 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -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, diff --git a/gcc/targhooks.h b/gcc/targhooks.h index fa3dfac6981..a7fb83a24bf 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -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 -- 2.11.4.GIT