From patchwork Tue Nov 16 03:42:31 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Froyd X-Patchwork-Id: 71348 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 25C97B712D for ; Tue, 16 Nov 2010 14:43:02 +1100 (EST) Received: (qmail 6221 invoked by alias); 16 Nov 2010 03:43:00 -0000 Received: (qmail 6190 invoked by uid 22791); 16 Nov 2010 03:42:50 -0000 X-SWARE-Spam-Status: No, hits=-0.4 required=5.0 tests=AWL, BAYES_50, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (38.113.113.100) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 16 Nov 2010 03:42:39 +0000 Received: (qmail 10811 invoked from network); 16 Nov 2010 03:42:33 -0000 Received: from unknown (HELO codesourcery.com) (froydnj@127.0.0.2) by mail.codesourcery.com with ESMTPA; 16 Nov 2010 03:42:33 -0000 Date: Mon, 15 Nov 2010 22:42:31 -0500 From: Nathan Froyd To: gcc-patches@gcc.gnu.org Subject: [PATCH] hookize FUNCTION_ARG_BOUNDARY Message-ID: <20101116034229.GB24469@nightcrawler> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-06-14) X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org This patch converts FUNCTION_ARG_BOUNDARY into a target hook, hookizes the macro in all backends, and poisons the old macro. Rather straightforward: fiddling with tm.texi.in and writing the ChangeLog were the toughest parts. :) Testing ongoing on x86_64-unknown-linux-gnu; no surprises expected. OK to commit? -Nathan * builtins.c (std_gimplify_va_arg_expr): Use targetm.calls.function_arg_boundary. * function.c (assign_parms, locate_and_pad_parm): Likewise. * calls.c (struct arg_data): Update comment. * defaults.h (FUNCTION_ARG_BOUNDARY): Delete. * target.def (function_arg_boundary): Define. * targhooks.h (default_function_arg_boundary): Declare. * targhooks.c (default_function_arg_boundary): Define. * doc/tm.texi.in (FUNCTION_ARG_PADDING): Use TARGET_FUNCTION_ARG_BOUNDARY. (FUNCTION_ARG_BOUNDARY): Delete. (TARGET_FUNCTION_ARG_BOUNDARY): New. * doc/tm.texi: Regenerate. * system.h (FUNCTION_ARG_BOUNDARY): Poison. * config/arc/arc.h (FUNCTION_ARG_BOUNDARY): Delete. * config/arc/arc.c (arc_function_arg_boundary): Define. (TARGET_FUNCTION_ARG_BOUNDARY): Define. * config/arm/arm.h (FUNCTION_ARG_BOUNDARY): Delete. * config/arm/arm-protos.h (arm_needs_doubleword_align): Delete. * config/arm/arm.c (arm_needs_doubleword_align): Make static. (arm_function_arg_boundary): Define. (TARGET_FUNCTION_ARG_BOUNDARY): Define. * config/frv/frv.h (FUNCTION_ARG_BOUNDARY): Delete. * config/frv/frv-protos.h (frv_function_arg_boundary): Delete. * config/frv/frv.c (frv_function_arg_boundary): Make static. (TARGET_FUNCTION_ARG_BOUNDARY): Define. * config/i386/i386.h (FUNCTION_ARG_BOUNDARY): Delete. * config/i386/i386-protos.h (ix86_function_arg_boundary): Delete. * config/i386/i386.c (ix86_function_arg_boundary): Make static. (ix86_compat_function_arg_boundary): Take and return unsigned int. (TARGET_FUNCTION_ARG_BOUNDARY): Define. * config/ia64/ia64.h (FUNCTION_ARG_BOUNDARY): Delete. * config/ia64/ia64-protos.h (ia64_function_arg_boundary): Delete. * config/ia64/ia64.c (ia64_function_arg_boundary): Make static. (TARGET_FUNCTION_ARG_BOUNDARY): Define. * config/m32c/m32c.h (FUNCTION_ARG_BOUNDARY): Delete. * config/m32c/m32c.c (m32c_function_arg_boundary): Define. (TARGET_FUNCTION_ARG_BOUNDARY): Define. * config/m32r/m32r.h (FUNCTION_ARG_BOUNDARY): Delete. * config/mcore/mcore.h (FUNCTION_ARG_BOUNDARY): Delete. * config/mcore/mcore.c (mcore_function_arg_boundary): Define. (TARGET_FUNCTION_ARG_BOUNDARY): Define. * config/mips/mips.h (FUNCTION_ARG_BOUNDARY): Delete. * config/mips/mips-protos.h (mips_function_arg_boundary): Delete. * config/mips/mips.c (mips_function_arg_boundary): Make static. (TARGET_FUNCTION_ARG_BOUNDARY): Define. * config/pa/pa.h (FUNCTION_ARG_BOUNDARY): Delete. * config/pa/pa.c (pa_function_arg_boundary): Define. (TARGET_FUNCTION_ARG_BOUNDARY): Define. * config/picochip/picochip.h (FUNCTION_ARG_BOUNDARY): Delete. * config/picochip/picochip-protos.h (picochip_get_function_arg_boundary): Delete. * config/picochip/picochip.c (picochip_get_function_arg_boundary): Rename to... (picochip_function_arg_boundary): ...this. Make static. (picochip_function_arg, picochip_arg_partial_bytes): Adjust. (picochip_arg_advance): Adjust. (TARGET_FUNCTION_ARG_BOUNDARY): Define. * config/rs6000/rs6000.h (FUNCTION_ARG_BOUNDARY): Delete. * config/rs6000/rs6000-protos.h (function_arg_boundary): Delete. * config/rs6000/rs6000.c (function_arg_boundary): Rename to... (rs6000_function_arg_boundary): ...this. Make static. (rs6000_parm_start, rs6000_gimplify_va_arg): Adjust. (TARGET_FUNCTION_ARG_BOUNDARY): Define. * config/rx/rx.h (FUNCTION_ARG_BOUNDARY): Delete. * config/rx/rx.c (rx_function_arg_boundary): Define. (TARGET_FUNCTION_ARG_BOUNDARY): Define. * config/sparc/sparc.h (FUNCTION_ARG_BOUNDARY): Delete. * config/sparc/sparc.c (sparc_function_arg_boundary): Define. (TARGET_FUNCTION_ARG_BOUNDARY): Define. * config/xtensa/xtensa.h (FUNCTION_ARG_BOUNDARY): Delete. * config/xtensa/xtensa-protos.h (function_arg_boundary): Delete. * config/xtensa/xtensa.c (function_arg_boundary): Rename to... (xtensa_function_arg_boundary): ...this. Make static. (TARGET_FUNCTION_ARG_BOUNDARY): Define. diff --git a/gcc/builtins.c b/gcc/builtins.c index e193791..4eb7047 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -4698,7 +4698,7 @@ std_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p, type = build_pointer_type (type); align = PARM_BOUNDARY / BITS_PER_UNIT; - boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type); + boundary = targetm.calls.function_arg_boundary (TYPE_MODE (type), type); /* When we align parameter on stack for caller, if the parameter alignment is beyond MAX_SUPPORTED_STACK_ALIGNMENT, it will be diff --git a/gcc/calls.c b/gcc/calls.c index e6b0ef5..5297763 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -89,7 +89,7 @@ struct arg_data rtx stack; /* Location on the stack of the start of this argument slot. This can differ from STACK if this arg pads downward. This location is known - to be aligned to FUNCTION_ARG_BOUNDARY. */ + to be aligned to TARGET_FUNCTION_ARG_BOUNDARY. */ rtx stack_slot; /* Place that this stack area has been saved, if needed. */ rtx save_area; diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c index b12c8da..2b1c704 100644 --- a/gcc/config/arc/arc.c +++ b/gcc/config/arc/arc.c @@ -98,6 +98,7 @@ static rtx arc_function_arg (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool); static void arc_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool); +static unsigned int arc_function_arg_boundary (enum machine_mode, const_tree); static void arc_trampoline_init (rtx, tree, rtx); static void arc_option_override (void); @@ -156,6 +157,8 @@ static const struct attribute_spec arc_attribute_table[] = #define TARGET_FUNCTION_ARG arc_function_arg #undef TARGET_FUNCTION_ARG_ADVANCE #define TARGET_FUNCTION_ARG_ADVANCE arc_function_arg_advance +#undef TARGET_FUNCTION_ARG_BOUNDARY +#define TARGET_FUNCTION_ARG_BOUNDARY arc_function_arg_boundary #undef TARGET_CALLEE_COPIES #define TARGET_CALLEE_COPIES hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true @@ -2423,6 +2426,22 @@ arc_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, + ROUND_ADVANCE_ARG (mode, type)); } +/* If defined, a C expression that gives the alignment boundary, in bits, + of an argument with the specified mode and type. If it is not defined, + PARM_BOUNDARY is used for all arguments. */ +#define FUNCTION_ARG_BOUNDARY(MODE, TYPE) \ +/* Worker function for TARGET_FUNCTION_ARG_BOUNDARY. */ + +static unsigned int +arc_function_arg_boundary (enum machine_mode mode, const_tree type) +{ + return (type != NULL_TREE + ? TYPE_ALIGN (type) + : (GET_MODE_BITSIZE (mode) <= PARM_BOUNDARY + ? PARM_BOUNDARY + : 2 * PARM_BOUNDARY)); +} + /* Trampolines. */ /* ??? This doesn't work yet because GCC will use as the address of a nested function the address of the trampoline. We need to use that address diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h index 078914a..259a33a 100644 --- a/gcc/config/arc/arc.h +++ b/gcc/config/arc/arc.h @@ -520,13 +520,6 @@ extern enum reg_class arc_regno_reg_class[FIRST_PSEUDO_REGISTER]; #define FUNCTION_ARG_REGNO_P(N) \ ((unsigned) (N) < MAX_ARC_PARM_REGS) -/* If defined, a C expression that gives the alignment boundary, in bits, - of an argument with the specified mode and type. If it is not defined, - PARM_BOUNDARY is used for all arguments. */ -#define FUNCTION_ARG_BOUNDARY(MODE, TYPE) \ -(((TYPE) ? TYPE_ALIGN (TYPE) : GET_MODE_BITSIZE (MODE)) <= PARM_BOUNDARY \ - ? PARM_BOUNDARY \ - : 2 * PARM_BOUNDARY) /* Function results. */ diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index c861bb6..1b1fe12 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -155,7 +155,6 @@ extern unsigned int arm_sync_loop_insns (rtx , rtx *); extern void arm_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree); extern bool arm_pad_arg_upward (enum machine_mode, const_tree); extern bool arm_pad_reg_upward (enum machine_mode, tree, int); -extern bool arm_needs_doubleword_align (enum machine_mode, const_tree); #endif extern int arm_apply_result_size (void); extern rtx aapcs_libcall_value (enum machine_mode); diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 5baa2ca..4641940 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -65,6 +65,7 @@ typedef struct minipool_fixup Mfix; void (*arm_lang_output_object_attributes_hook)(void); /* Forward function declarations. */ +static bool arm_needs_doubleword_align (enum machine_mode, const_tree); static int arm_compute_static_chain_stack_bytes (void); static arm_stack_offsets *arm_get_frame_offsets (void); static void arm_add_gc_roots (void); @@ -168,6 +169,7 @@ static rtx arm_function_arg (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool); static void arm_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool); +static unsigned int arm_function_arg_boundary (enum machine_mode, const_tree); static rtx aapcs_allocate_return_reg (enum machine_mode, const_tree, const_tree); static int aapcs_select_return_coproc (const_tree, const_tree); @@ -415,6 +417,8 @@ static const struct default_options arm_option_optimization_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_BOUNDARY +#define TARGET_FUNCTION_ARG_BOUNDARY arm_function_arg_boundary #undef TARGET_SETUP_INCOMING_VARARGS #define TARGET_SETUP_INCOMING_VARARGS arm_setup_incoming_varargs @@ -4527,7 +4531,7 @@ arm_init_cumulative_args (CUMULATIVE_ARGS *pcum, tree fntype, /* Return true if mode/type need doubleword alignment. */ -bool +static bool arm_needs_doubleword_align (enum machine_mode mode, const_tree type) { return (GET_MODE_ALIGNMENT (mode) > PARM_BOUNDARY @@ -4606,6 +4610,14 @@ arm_function_arg (CUMULATIVE_ARGS *pcum, enum machine_mode mode, return gen_rtx_REG (mode, pcum->nregs); } +static unsigned int +arm_function_arg_boundary (enum machine_mode mode, const_tree type) +{ + return (ARM_DOUBLEWORD_ALIGN && arm_needs_doubleword_align (mode, type) + ? DOUBLEWORD_ALIGNMENT + : PARM_BOUNDARY); +} + static int arm_arg_partial_bytes (CUMULATIVE_ARGS *pcum, enum machine_mode mode, tree type, bool named) diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index c3dc3b9..483b222 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -1731,14 +1731,6 @@ typedef struct #define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS) \ arm_init_cumulative_args (&(CUM), (FNTYPE), (LIBNAME), (FNDECL)) -/* If defined, a C expression that gives the alignment boundary, in bits, of an - argument with the specified mode and type. If it is not defined, - `PARM_BOUNDARY' is used for all arguments. */ -#define FUNCTION_ARG_BOUNDARY(MODE,TYPE) \ - ((ARM_DOUBLEWORD_ALIGN && arm_needs_doubleword_align (MODE, TYPE)) \ - ? DOUBLEWORD_ALIGNMENT \ - : PARM_BOUNDARY ) - /* 1 if N is a possible register number for function argument passing. On the ARM, r0-r3 are used to pass args. */ #define FUNCTION_ARG_REGNO_P(REGNO) \ diff --git a/gcc/config/frv/frv-protos.h b/gcc/config/frv/frv-protos.h index 3fd9d0c..bba1705 100644 --- a/gcc/config/frv/frv-protos.h +++ b/gcc/config/frv/frv-protos.h @@ -52,7 +52,6 @@ extern rtx frv_find_base_term (rtx); extern void frv_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree, int); -extern int frv_function_arg_boundary (enum machine_mode, tree); extern bool frv_function_value_regno_p (const unsigned int); #endif /* TREE_CODE */ diff --git a/gcc/config/frv/frv.c b/gcc/config/frv/frv.c index fc127ac..b6b7c00 100644 --- a/gcc/config/frv/frv.c +++ b/gcc/config/frv/frv.c @@ -396,6 +396,8 @@ static rtx frv_function_incoming_arg (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool); static void frv_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool); +static unsigned int frv_function_arg_boundary (enum machine_mode, + const_tree); static void frv_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED; static reg_class_t frv_secondary_reload (bool, rtx, reg_class_t, @@ -500,6 +502,8 @@ static const struct default_options frv_option_optimization_table[] = #define TARGET_FUNCTION_INCOMING_ARG frv_function_incoming_arg #undef TARGET_FUNCTION_ARG_ADVANCE #define TARGET_FUNCTION_ARG_ADVANCE frv_function_arg_advance +#undef TARGET_FUNCTION_ARG_BOUNDARY +#define TARGET_FUNCTION_ARG_BOUNDARY frv_function_arg_boundary #undef TARGET_EXPAND_BUILTIN_SAVEREGS #define TARGET_EXPAND_BUILTIN_SAVEREGS frv_expand_builtin_saveregs @@ -3195,9 +3199,9 @@ frv_must_pass_in_stack (enum machine_mode mode, const_tree type) argument with the specified mode and type. If it is not defined, `PARM_BOUNDARY' is used for all arguments. */ -int +static unsigned int frv_function_arg_boundary (enum machine_mode mode ATTRIBUTE_UNUSED, - tree type ATTRIBUTE_UNUSED) + const_tree type ATTRIBUTE_UNUSED) { return BITS_PER_WORD; } diff --git a/gcc/config/frv/frv.h b/gcc/config/frv/frv.h index 8a2907d..b498c61 100644 --- a/gcc/config/frv/frv.h +++ b/gcc/config/frv/frv.h @@ -1561,13 +1561,6 @@ typedef struct frv_stack { #define INIT_CUMULATIVE_INCOMING_ARGS(CUM, FNTYPE, LIBNAME) \ frv_init_cumulative_args (&CUM, FNTYPE, LIBNAME, NULL, TRUE) -/* If defined, a C expression that gives the alignment boundary, in bits, of an - argument with the specified mode and type. If it is not defined, - `PARM_BOUNDARY' is used for all arguments. */ - -#define FUNCTION_ARG_BOUNDARY(MODE, TYPE) \ - frv_function_arg_boundary (MODE, TYPE) - /* A C expression that is nonzero if REGNO is the number of a hard register in which function arguments are sometimes passed. This does *not* include implicit arguments such as the static chain and the structure-value address. diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index 4dc707c..c241538 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -140,7 +140,6 @@ extern enum machine_mode ix86_fp_compare_mode (enum rtx_code); extern rtx ix86_libcall_value (enum machine_mode); extern bool ix86_function_arg_regno_p (int); extern void ix86_asm_output_function_label (FILE *, const char *, tree); -extern int ix86_function_arg_boundary (enum machine_mode, const_tree); extern rtx ix86_force_to_memory (enum machine_mode, rtx); extern void ix86_free_from_memory (enum machine_mode); extern void ix86_call_abi_override (const_tree); diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 15e8b27..c3e1de8 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -2225,6 +2225,8 @@ static bool ext_80387_constants_init = 0; static struct machine_function * ix86_init_machine_status (void); static rtx ix86_function_value (const_tree, const_tree, bool); static bool ix86_function_value_regno_p (const unsigned int); +static unsigned int ix86_function_arg_boundary (enum machine_mode, + const_tree); static rtx ix86_static_chain (const_tree, bool); static int ix86_function_regparm (const_tree, const_tree); static void ix86_compute_frame_layout (struct ix86_frame *); @@ -7062,9 +7064,9 @@ ix86_compat_aligned_value_p (const_tree type) XXX: This function is obsolete and is only used for checking psABI compatibility with previous versions of GCC. */ -static int +static unsigned int ix86_compat_function_arg_boundary (enum machine_mode mode, - const_tree type, int align) + const_tree type, unsigned int align) { /* In 32bit, only _Decimal128 and __float128 are aligned to their natural boundaries. */ @@ -7149,10 +7151,10 @@ ix86_contains_aligned_value_p (const_tree type) /* Gives the alignment boundary, in bits, of an argument with the specified mode and type. */ -int +static unsigned int ix86_function_arg_boundary (enum machine_mode mode, const_tree type) { - int align; + unsigned int align; if (type) { /* Since the main variant type is used for call, we convert it to @@ -7167,7 +7169,7 @@ ix86_function_arg_boundary (enum machine_mode mode, const_tree type) else { static bool warned; - int saved_align = align; + unsigned int saved_align = align; if (!TARGET_64BIT) { @@ -8157,7 +8159,7 @@ ix86_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p, alignment is beyond MAX_SUPPORTED_STACK_ALIGNMENT, it will be aligned at MAX_SUPPORTED_STACK_ALIGNMENT. We will match callee here with caller. */ - arg_boundary = FUNCTION_ARG_BOUNDARY (VOIDmode, type); + arg_boundary = ix86_function_arg_boundary (VOIDmode, type); if ((unsigned int) arg_boundary > MAX_SUPPORTED_STACK_ALIGNMENT) arg_boundary = MAX_SUPPORTED_STACK_ALIGNMENT; @@ -34570,6 +34572,8 @@ ix86_autovectorize_vector_sizes (void) #define TARGET_FUNCTION_ARG_ADVANCE ix86_function_arg_advance #undef TARGET_FUNCTION_ARG #define TARGET_FUNCTION_ARG ix86_function_arg +#undef TARGET_FUNCTION_ARG_BOUNDARY +#define TARGET_FUNCTION_ARG_BOUNDARY ix86_function_arg_boundary #undef TARGET_PASS_BY_REFERENCE #define TARGET_PASS_BY_REFERENCE ix86_pass_by_reference #undef TARGET_INTERNAL_ARG_POINTER diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 1bc5206..170ad50 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -844,13 +844,6 @@ enum target_cpu_default ix86_minimum_alignment (EXP, MODE, ALIGN) -/* If defined, a C expression that gives the alignment boundary, in - bits, of an argument with the specified mode and type. If it is - not defined, `PARM_BOUNDARY' is used for all arguments. */ - -#define FUNCTION_ARG_BOUNDARY(MODE, TYPE) \ - ix86_function_arg_boundary ((MODE), (TYPE)) - /* Set this nonzero if move instructions will actually fail to work when given unaligned data. */ #define STRICT_ALIGNMENT 0 diff --git a/gcc/config/ia64/ia64-protos.h b/gcc/config/ia64/ia64-protos.h index d2393bc..b841152 100644 --- a/gcc/config/ia64/ia64-protos.h +++ b/gcc/config/ia64/ia64-protos.h @@ -67,7 +67,6 @@ extern rtx ia64_expand_builtin (tree, rtx, rtx, enum machine_mode, int); extern rtx ia64_va_arg (tree, tree); #endif /* RTX_CODE */ -extern int ia64_function_arg_boundary (enum machine_mode, tree); extern void ia64_asm_output_external (FILE *, tree, const char *); extern void ia64_vms_output_aligned_decl_common (FILE *, tree, const char *, unsigned HOST_WIDE_INT, diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index 4a73809..7dd11b8 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -217,6 +217,8 @@ static rtx ia64_function_incoming_arg (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool); static void ia64_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool); +static unsigned int ia64_function_arg_boundary (enum machine_mode, + const_tree); static bool ia64_function_ok_for_sibcall (tree, tree); static bool ia64_return_in_memory (const_tree, const_tree); static rtx ia64_function_value (const_tree, const_tree, bool); @@ -496,6 +498,8 @@ static const struct default_options ia64_option_optimization_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_BOUNDARY +#define TARGET_FUNCTION_ARG_BOUNDARY ia64_function_arg_boundary #undef TARGET_ASM_OUTPUT_MI_THUNK #define TARGET_ASM_OUTPUT_MI_THUNK ia64_output_mi_thunk @@ -4666,10 +4670,9 @@ ia64_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, boundary. On ILP32 HPUX, TFmode arguments start on next even boundary even though their normal alignment is 8 bytes. See ia64_function_arg. */ -int -ia64_function_arg_boundary (enum machine_mode mode, tree type) +static unsigned int +ia64_function_arg_boundary (enum machine_mode mode, const_tree type) { - if (mode == TFmode && TARGET_HPUX && TARGET_ILP32) return PARM_BOUNDARY * 2; diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h index fdac455..2407fd8 100644 --- a/gcc/config/ia64/ia64.h +++ b/gcc/config/ia64/ia64.h @@ -1070,15 +1070,6 @@ do { \ (CUM).atypes[6] = (CUM).atypes[7] = I64; \ } while (0) -/* If defined, a C expression that gives the alignment boundary, in bits, of an - argument with the specified mode and type. */ - -/* Return the alignment boundary in bits for an argument with a specified - mode and type. */ - -#define FUNCTION_ARG_BOUNDARY(MODE, TYPE) \ - ia64_function_arg_boundary (MODE, TYPE) - /* A C expression that is nonzero if REGNO is the number of a hard register in which function arguments are sometimes passed. This does *not* include implicit arguments such as the static chain and the structure-value address. diff --git a/gcc/config/iq2000/iq2000.c b/gcc/config/iq2000/iq2000.c index 5f9049d..433af64 100644 --- a/gcc/config/iq2000/iq2000.c +++ b/gcc/config/iq2000/iq2000.c @@ -169,6 +169,8 @@ static rtx iq2000_function_arg (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool); static void iq2000_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool); +static unsigned int iq2000_function_arg_boundary (enum machine_mode, + const_tree); static void iq2000_va_start (tree, rtx); static bool iq2000_legitimate_address_p (enum machine_mode, rtx, bool); static bool iq2000_can_eliminate (const int, const int); @@ -242,6 +244,8 @@ static const struct default_options iq2000_option_optimization_table[] = #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_BOUNDARY +#define TARGET_FUNCTION_ARG_BOUNDARY iq2000_function_arg_boundary #undef TARGET_SETUP_INCOMING_VARARGS #define TARGET_SETUP_INCOMING_VARARGS iq2000_setup_incoming_varargs @@ -1374,6 +1378,18 @@ iq2000_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, return ret; } +static unsigned int +iq2000_function_arg_boundary (enum machine_mode mode, const_tree type) +{ + return (type != NULL_TREE + ? (TYPE_ALIGN (type) <= PARM_BOUNDARY + ? PARM_BOUNDARY + : TYPE_ALIGN (type)) + : (GET_MODE_ALIGNMENT (mode) <= PARM_BOUNDARY + ? PARM_BOUNDARY + : GET_MODE_ALIGNMENT (mode))); +} + static int iq2000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type ATTRIBUTE_UNUSED, diff --git a/gcc/config/iq2000/iq2000.h b/gcc/config/iq2000/iq2000.h index 87ae17a..68b700d 100644 --- a/gcc/config/iq2000/iq2000.h +++ b/gcc/config/iq2000/iq2000.h @@ -390,15 +390,6 @@ typedef struct iq2000_args && (GET_MODE_CLASS (MODE) == MODE_INT))) \ ? downward : upward)) -#define FUNCTION_ARG_BOUNDARY(MODE, TYPE) \ - (((TYPE) != 0) \ - ? ((TYPE_ALIGN(TYPE) <= PARM_BOUNDARY) \ - ? PARM_BOUNDARY \ - : TYPE_ALIGN(TYPE)) \ - : ((GET_MODE_ALIGNMENT(MODE) <= PARM_BOUNDARY) \ - ? PARM_BOUNDARY \ - : GET_MODE_ALIGNMENT(MODE))) - #define FUNCTION_ARG_REGNO_P(N) \ (((N) >= GP_ARG_FIRST && (N) <= GP_ARG_LAST)) diff --git a/gcc/config/m32c/m32c.c b/gcc/config/m32c/m32c.c index 3079f04..a555415 100644 --- a/gcc/config/m32c/m32c.c +++ b/gcc/config/m32c/m32c.c @@ -80,6 +80,7 @@ static bool m32c_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool); static void m32c_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool); +static unsigned int m32c_function_arg_boundary (enum machine_mode, const_tree); static int m32c_pushm_popm (Push_Pop_Type); static bool m32c_strict_argument_naming (CUMULATIVE_ARGS *); static rtx m32c_struct_value_rtx (tree, int); @@ -1637,6 +1638,16 @@ m32c_function_arg_advance (CUMULATIVE_ARGS * ca, ca->parm_num++; } +/* Implements TARGET_FUNCTION_ARG_BOUNDARY. */ +#undef TARGET_FUNCTION_ARG_BOUNDARY +#define TARGET_FUNCTION_ARG_BOUNDARY m32c_function_arg_boundary +static unsigned int +m32c_function_arg_boundary (enum machine_mode mode ATTRIBUTE_UNUSED, + const_tree type ATTRIBUTE_UNUSED) +{ + return (TARGET_A16 ? 8 : 16); +} + /* Implements FUNCTION_ARG_REGNO_P. */ int m32c_function_arg_regno_p (int r) diff --git a/gcc/config/m32c/m32c.h b/gcc/config/m32c/m32c.h index f88ced9..503044c 100644 --- a/gcc/config/m32c/m32c.h +++ b/gcc/config/m32c/m32c.h @@ -520,7 +520,6 @@ typedef struct m32c_cumulative_args #define CUMULATIVE_ARGS m32c_cumulative_args #define INIT_CUMULATIVE_ARGS(CA,FNTYPE,LIBNAME,FNDECL,N_NAMED_ARGS) \ m32c_init_cumulative_args (&(CA),FNTYPE,LIBNAME,FNDECL,N_NAMED_ARGS) -#define FUNCTION_ARG_BOUNDARY(MODE,TYPE) (TARGET_A16 ? 8 : 16) #define FUNCTION_ARG_REGNO_P(r) m32c_function_arg_regno_p (r) /* How Large Values Are Returned */ diff --git a/gcc/config/m32r/m32r.h b/gcc/config/m32r/m32r.h index 785d85b..d24cda6 100644 --- a/gcc/config/m32r/m32r.h +++ b/gcc/config/m32r/m32r.h @@ -780,15 +780,6 @@ extern enum reg_class m32r_regno_reg_class[FIRST_PSEUDO_REGISTER]; #define FUNCTION_ARG_REGNO_P(N) \ ((unsigned) (N) < M32R_MAX_PARM_REGS) -/* If defined, a C expression that gives the alignment boundary, in bits, - of an argument with the specified mode and type. If it is not defined, - PARM_BOUNDARY is used for all arguments. */ -#if 0 -/* We assume PARM_BOUNDARY == UNITS_PER_WORD here. */ -#define FUNCTION_ARG_BOUNDARY(MODE, TYPE) \ - (((TYPE) ? TYPE_ALIGN (TYPE) : GET_MODE_BITSIZE (MODE)) <= PARM_BOUNDARY \ - ? PARM_BOUNDARY : 2 * PARM_BOUNDARY) -#endif /* Function results. */ diff --git a/gcc/config/mcore/mcore.c b/gcc/config/mcore/mcore.c index 62ab41c..3c3e1bb 100644 --- a/gcc/config/mcore/mcore.c +++ b/gcc/config/mcore/mcore.c @@ -148,6 +148,8 @@ static rtx mcore_function_arg (CUMULATIVE_ARGS *, static void mcore_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool); +static unsigned int mcore_function_arg_boundary (enum machine_mode, + const_tree); static void mcore_asm_trampoline_template (FILE *); static void mcore_trampoline_init (rtx, tree, rtx); static void mcore_option_override (void); @@ -239,6 +241,8 @@ static const struct default_options mcore_option_optimization_table[] = #define TARGET_FUNCTION_ARG mcore_function_arg #undef TARGET_FUNCTION_ARG_ADVANCE #define TARGET_FUNCTION_ARG_ADVANCE mcore_function_arg_advance +#undef TARGET_FUNCTION_ARG_BOUNDARY +#define TARGET_FUNCTION_ARG_BOUNDARY mcore_function_arg_boundary #undef TARGET_SETUP_INCOMING_VARARGS #define TARGET_SETUP_INCOMING_VARARGS mcore_setup_incoming_varargs @@ -2840,6 +2844,16 @@ mcore_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, + (int)named * mcore_num_arg_regs (mode, type)); } +static unsigned int +mcore_function_arg_boundary (enum machine_mode mode, + const_tree type ATTRIBUTE_UNUSED) +{ + /* Doubles must be aligned to an 8 byte boundary. */ + return (mode != BLKmode && GET_MODE_SIZE (mode) == 8 + ? BIGGEST_ALIGNMENT + : PARM_BOUNDARY); +} + /* Returns the number of bytes of argument registers required to hold *part* of a parameter of machine mode MODE and type TYPE (which may be NULL if the type is not known). If the argument fits entirely in the argument diff --git a/gcc/config/mcore/mcore.h b/gcc/config/mcore/mcore.h index 5158658..f1be994 100644 --- a/gcc/config/mcore/mcore.h +++ b/gcc/config/mcore/mcore.h @@ -119,11 +119,6 @@ extern char * mcore_current_function_name; /* Allocation boundary (in *bits*) for storing arguments in argument list. */ #define PARM_BOUNDARY 32 -/* Doubles must be aligned to an 8 byte boundary. */ -#define FUNCTION_ARG_BOUNDARY(MODE, TYPE) \ - ((MODE != BLKmode && (GET_MODE_SIZE (MODE) == 8)) \ - ? BIGGEST_ALIGNMENT : PARM_BOUNDARY) - /* Boundary (in *bits*) on which stack pointer should be aligned. */ #define STACK_BOUNDARY (TARGET_8ALIGN ? 64 : 32) diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h index be2d6af..6f5801c 100644 --- a/gcc/config/mips/mips-protos.h +++ b/gcc/config/mips/mips-protos.h @@ -240,7 +240,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 int mips_function_arg_boundary (enum machine_mode, const_tree); extern bool mips_pad_arg_upward (enum machine_mode, const_tree); extern bool mips_pad_reg_upward (enum machine_mode, tree); diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 6e7d500..2bd5638 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -1190,6 +1190,7 @@ static const struct mips_rtx_cost_data static rtx mips_find_pic_call_symbol (rtx, rtx); static int mips_register_move_cost (enum machine_mode, reg_class_t, reg_class_t); +static int mips_function_arg_boundary (enum machine_mode, const_tree); /* This hash table keeps track of implicit "mips16" and "nomips16" attributes for -mflip_mips16. It maps decl names onto a boolean mode setting. */ @@ -4783,7 +4784,8 @@ mips_get_arg_info (struct mips_arg_info *info, const CUMULATIVE_ARGS *cum, } /* See whether the argument has doubleword alignment. */ - doubleword_aligned_p = FUNCTION_ARG_BOUNDARY (mode, type) > BITS_PER_WORD; + doubleword_aligned_p = (mips_function_arg_boundary (mode, type) + > BITS_PER_WORD); /* Set REG_OFFSET to the register count we're interested in. The EABI allocates the floating-point registers separately, @@ -5008,11 +5010,11 @@ mips_arg_partial_bytes (CUMULATIVE_ARGS *cum, return info.stack_words > 0 ? info.reg_words * UNITS_PER_WORD : 0; } -/* Implement FUNCTION_ARG_BOUNDARY. Every parameter gets at least - PARM_BOUNDARY bits of alignment, but will be given anything up +/* Implement TARGET_FUNCTION_ARG_BOUNDARY. Every parameter gets at + least PARM_BOUNDARY bits of alignment, but will be given anything up to STACK_BOUNDARY bits if the type requires it. */ -int +static unsigned int mips_function_arg_boundary (enum machine_mode mode, const_tree type) { unsigned int alignment; @@ -16542,6 +16544,8 @@ mips_shift_truncation_mask (enum machine_mode mode) #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_BOUNDARY +#define TARGET_FUNCTION_ARG_BOUNDARY mips_function_arg_boundary #undef TARGET_MODE_REP_EXTENDED #define TARGET_MODE_REP_EXTENDED mips_mode_rep_extended diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index 392e457..49440ff 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -2250,8 +2250,6 @@ typedef struct mips_args { #define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \ mips_init_cumulative_args (&CUM, FNTYPE) -#define FUNCTION_ARG_BOUNDARY mips_function_arg_boundary - #define FUNCTION_ARG_PADDING(MODE, TYPE) \ (mips_pad_arg_upward (MODE, TYPE) ? upward : downward) diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index 076d2de..b11e715 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -164,6 +164,7 @@ static void pa_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool); static rtx pa_function_arg (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool); +static int pa_function_arg_boundary (enum 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, enum machine_mode, @@ -351,6 +352,8 @@ static const struct default_options pa_option_optimization_table[] = #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_BOUNDARY +#define TARGET_FUNCTION_ARG_BOUNDARY pa_function_arg_boundary #undef TARGET_EXPAND_BUILTIN_SAVEREGS #define TARGET_EXPAND_BUILTIN_SAVEREGS hppa_builtin_saveregs @@ -9600,6 +9603,20 @@ pa_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, return retval; } +/* Arguments larger than one word are double word aligned. */ + +static unsigned int +pa_function_arg_boundary (enum machine_mode mode, const_tree type) +{ + tree size = TYPE_SIZE (type); + bool singleword = (type + ? (integer_zerop (size) + || !TREE_CONSTANT (size) + || int_size_in_bytes (type) <= UNITS_PER_WORD) + : GET_MODE_SIZE (mode)); + + return singleword ? PARM_BOUNDARY : MAX_PARM_BOUNDARY; +} /* If this arg would be passed totally in registers or totally on the stack, then this routine should return zero. */ diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h index 46c210e..64c8926 100644 --- a/gcc/config/pa/pa.h +++ b/gcc/config/pa/pa.h @@ -687,20 +687,6 @@ struct hppa_args {int words, nargs_prototype, incoming, indirect; }; #define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \ function_arg_padding ((MODE), (TYPE)) -/* If defined, a C expression that gives the alignment boundary, in - bits, of an argument with the specified mode and type. If it is - not defined, `PARM_BOUNDARY' is used for all arguments. */ - -/* Arguments larger than one word are double word aligned. */ - -#define FUNCTION_ARG_BOUNDARY(MODE, TYPE) \ - (((TYPE) \ - ? (integer_zerop (TYPE_SIZE (TYPE)) \ - || !TREE_CONSTANT (TYPE_SIZE (TYPE)) \ - || int_size_in_bytes (TYPE) <= UNITS_PER_WORD) \ - : GET_MODE_SIZE(MODE) <= UNITS_PER_WORD) \ - ? PARM_BOUNDARY : MAX_PARM_BOUNDARY) - /* On HPPA, we emit profiling code as rtl via PROFILE_HOOK rather than as assembly via FUNCTION_PROFILER. Just output a local label. diff --git a/gcc/config/picochip/picochip-protos.h b/gcc/config/picochip/picochip-protos.h index b3755a6..891badb 100644 --- a/gcc/config/picochip/picochip-protos.h +++ b/gcc/config/picochip/picochip-protos.h @@ -66,8 +66,6 @@ extern int picochip_absolute_memory_operand (rtx op, enum machine_mode mode); extern rtx picochip_function_value (const_tree valtype, const_tree func, bool outgoing); extern int picochip_symbol_offset (rtx operand); -extern int picochip_get_function_arg_boundary (enum machine_mode mode); - extern reg_class_t picochip_secondary_reload(bool in_p, rtx x, reg_class_t cla, diff --git a/gcc/config/picochip/picochip.c b/gcc/config/picochip/picochip.c index d2dab01..67f2f97 100644 --- a/gcc/config/picochip/picochip.c +++ b/gcc/config/picochip/picochip.c @@ -89,6 +89,8 @@ rtx picochip_incoming_function_arg (CUMULATIVE_ARGS * p_cum, const_tree type, bool named); void picochip_arg_advance (CUMULATIVE_ARGS * p_cum, enum machine_mode mode, const_tree type, bool named); +unsigned int picochip_function_boundary (enum machine_mode mode, + const_tree type); int picochip_sched_lookahead (void); int picochip_sched_issue_rate (void); @@ -286,6 +288,9 @@ static const struct default_options picochip_option_optimization_table[] = #undef TARGET_FUNCTION_ARG_ADVANCE #define TARGET_FUNCTION_ARG_ADVANCE picochip_arg_advance +#undef TARGET_FUNCTION_ARG_BOUNDARY +#define TARGET_FUNCTION_ARG_BOUNDARY picochip_function_arg_boundary + #undef TARGET_PROMOTE_FUNCTION_MODE #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote #undef TARGET_PROMOTE_PROTOTYPES @@ -851,7 +856,7 @@ picochip_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, /* Compute the alignment and size of the parameter. */ type_align_in_units = - picochip_get_function_arg_boundary (mode) / BITS_PER_UNIT; + picochip_function_arg_boundary (mode) / BITS_PER_UNIT; type_size_in_units = picochip_compute_arg_size (type, mode); /* Compute the correct offset (i.e., ensure that the offset meets @@ -947,8 +952,9 @@ picochip_incoming_function_arg (CUMULATIVE_ARGS *cum, /* Gives the alignment boundary, in bits, of an argument with the specified mode. */ -int -picochip_get_function_arg_boundary (enum machine_mode mode) +unsigned int +picochip_function_arg_boundary (enum machine_mode mode, + const_tree type ATTRIBUTE_UNUSED) { int align; @@ -983,7 +989,7 @@ picochip_arg_partial_bytes (CUMULATIVE_ARGS * p_cum, enum machine_mode mode, /* Compute the alignment and size of the parameter. */ type_align_in_units = - picochip_get_function_arg_boundary (mode) / BITS_PER_UNIT; + picochip_function_arg_boundary (mode) / BITS_PER_UNIT; type_size_in_units = picochip_compute_arg_size (type, mode); /* Compute the correct offset (i.e., ensure that the offset meets @@ -1037,7 +1043,7 @@ picochip_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, /* Compute the alignment and size of the parameter. */ type_align_in_units = - picochip_get_function_arg_boundary (mode) / BITS_PER_UNIT; + picochip_function_arg_boundary (mode) / BITS_PER_UNIT; type_size_in_units = picochip_compute_arg_size (type, mode); /* Compute the correct offset (i.e., ensure that the offset meets diff --git a/gcc/config/picochip/picochip.h b/gcc/config/picochip/picochip.h index 72b8365..a3b564d 100644 --- a/gcc/config/picochip/picochip.h +++ b/gcc/config/picochip/picochip.h @@ -404,13 +404,6 @@ extern const enum reg_class picochip_regno_reg_class[FIRST_PSEUDO_REGISTER]; #define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT,N_NAMED_ARGS) \ ((CUM) = 0) -/* Originally this used TYPE_ALIGN to determine the - alignment. Unfortunately, this fails in some cases, because the - type is unknown (e.g., libcall's). Instead, use GET_MODE_ALIGNMENT - since the mode is always present. */ -#define FUNCTION_ARG_BOUNDARY(MODE,TYPE) \ - picochip_get_function_arg_boundary(MODE) - /* The first 6 registers can hold parameters. */ #define FUNCTION_ARG_REGNO_P(REGNO) ((REGNO) < 6) diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h index e5c6f0d..40e8acb 100644 --- a/gcc/config/rs6000/rs6000-protos.h +++ b/gcc/config/rs6000/rs6000-protos.h @@ -138,7 +138,6 @@ extern unsigned int rs6000_special_round_type_align (tree, unsigned int, unsigned int); extern unsigned int darwin_rs6000_special_round_type_align (tree, unsigned int, unsigned int); -extern int function_arg_boundary (enum machine_mode, const_tree); extern tree altivec_resolve_overloaded_builtin (location_t, tree, void *); extern rtx rs6000_libcall_value (enum machine_mode); extern rtx rs6000_va_arg (tree, tree); diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index ba85c0a..d71340b 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -1185,6 +1185,8 @@ static void rs6000_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool); static rtx rs6000_function_arg (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool); +static unsigned int rs6000_function_arg_boundary (enum machine_mode, + const_tree); static void rs6000_move_block_from_reg (int regno, rtx x, int nregs); static void setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode, tree, @@ -1587,6 +1589,8 @@ static const struct default_options rs6000_option_optimization_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_BOUNDARY +#define TARGET_FUNCTION_ARG_BOUNDARY rs6000_function_arg_boundary #undef TARGET_BUILD_BUILTIN_VA_LIST #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list @@ -7850,8 +7854,8 @@ function_arg_padding (enum machine_mode mode, const_tree type) Quadword align Altivec vectors. Quadword align large synthetic vector types. */ -int -function_arg_boundary (enum machine_mode mode, const_tree type) +static unsigned int +rs6000_function_arg_boundary (enum machine_mode mode, const_tree type) { if (DEFAULT_ABI == ABI_V4 && (GET_MODE_SIZE (mode) == 8 @@ -7887,7 +7891,7 @@ rs6000_parm_start (enum machine_mode mode, const_tree type, unsigned int align; unsigned int parm_offset; - align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1; + align = rs6000_function_arg_boundary (mode, type) / PARM_BOUNDARY - 1; parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6; return nwords + (-(parm_offset + nwords) & align); } @@ -9399,7 +9403,7 @@ rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p, unsigned HOST_WIDE_INT align, boundary; tree valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL); align = PARM_BOUNDARY / BITS_PER_UNIT; - boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type); + boundary = rs6000_function_arg_boundary (TYPE_MODE (type), type); if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT) boundary = MAX_SUPPORTED_STACK_ALIGNMENT; boundary /= BITS_PER_UNIT; diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index e68936c..9162e4f 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -1706,13 +1706,6 @@ typedef struct rs6000_args #define FUNCTION_ARG_PADDING(MODE, TYPE) function_arg_padding (MODE, TYPE) -/* If defined, a C expression that gives the alignment boundary, in bits, - of an argument with the specified mode and type. If it is not defined, - PARM_BOUNDARY is used for all arguments. */ - -#define FUNCTION_ARG_BOUNDARY(MODE, TYPE) \ - function_arg_boundary (MODE, TYPE) - #define PAD_VARARGS_DOWN \ (FUNCTION_ARG_PADDING (TYPE_MODE (type), type) == downward) diff --git a/gcc/config/rx/rx.c b/gcc/config/rx/rx.c index 968d65f..f8c171d 100644 --- a/gcc/config/rx/rx.c +++ b/gcc/config/rx/rx.c @@ -822,6 +822,13 @@ rx_function_arg_advance (Fargs * cum, Mmode mode, const_tree type, *cum += rx_function_arg_size (mode, type); } +static unsigned int +rx_function_arg_boundary (Mmode mode ATTRIBUTE_UNUSED, + const_tree type ATTRIBUTE_UNUSED) +{ + return 32; +} + /* Return an RTL describing where a function return value of type RET_TYPE is held. */ @@ -2815,6 +2822,9 @@ rx_memory_move_cost (enum machine_mode mode, reg_class_t regclass, bool in) #undef TARGET_FUNCTION_ARG_ADVANCE #define TARGET_FUNCTION_ARG_ADVANCE rx_function_arg_advance +#undef TARGET_FUNCTION_ARG_BOUNDARY +#define TARGET_FUNCTION_ARG_BOUNDARY rx_function_arg_boundary + #undef TARGET_SET_CURRENT_FUNCTION #define TARGET_SET_CURRENT_FUNCTION rx_set_current_function diff --git a/gcc/config/rx/rx.h b/gcc/config/rx/rx.h index 8262f0b..9eb25e8 100644 --- a/gcc/config/rx/rx.h +++ b/gcc/config/rx/rx.h @@ -125,8 +125,6 @@ extern enum rx_cpu_types rx_cpu_type; #define STACK_BOUNDARY 32 #define PARM_BOUNDARY 8 -#define FUNCTION_ARG_BOUNDARY(MODE, TYPE) 32 - #define STACK_GROWS_DOWNWARD 1 #define FRAME_GROWS_DOWNWARD 0 #define FIRST_PARM_OFFSET(FNDECL) 0 diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index d9b1323..f9f3932 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -432,6 +432,8 @@ static rtx sparc_function_arg (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool); static rtx sparc_function_incoming_arg (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool); +static unsigned int sparc_function_arg_boundary (enum machine_mode, + const_tree); static int sparc_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode, tree, bool); static void sparc_dwarf_handle_frame_unspec (const char *, rtx, int); @@ -579,6 +581,8 @@ static const struct default_options sparc_option_optimization_table[] = #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_BOUNDARY +#define TARGET_FUNCTION_ARG_BOUNDARY sparc_function_arg_boundary #undef TARGET_EXPAND_BUILTIN_SAVEREGS #define TARGET_EXPAND_BUILTIN_SAVEREGS sparc_builtin_saveregs @@ -5749,6 +5753,18 @@ sparc_function_incoming_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, return sparc_function_arg_1 (cum, mode, type, named, true); } +/* For sparc64, objects requiring 16 byte alignment are passed that way. */ + +static unsigned int +sparc_function_arg_boundary (enum machine_mode mode, const_tree type) +{ + return ((TARGET_ARCH64 + && (GET_MODE_ALIGNMENT (mode) == 128 + || (type && TYPE_ALIGN (type) == 128))) + ? 128 + : PARM_BOUNDARY); +} + /* For an arg passed partly in registers and partly in memory, this is the number of bytes of registers used. For args passed entirely in registers or entirely in memory, zero. diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index b7f0bd3..e064899 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -1441,17 +1441,6 @@ init_cumulative_args (& (CUM), (FNTYPE), (LIBNAME), (FNDECL)); #define FUNCTION_ARG_PADDING(MODE, TYPE) \ function_arg_padding ((MODE), (TYPE)) -/* If defined, a C expression that gives the alignment boundary, in bits, - of an argument with the specified mode and type. If it is not defined, - PARM_BOUNDARY is used for all arguments. - For sparc64, objects requiring 16 byte alignment are passed that way. */ - -#define FUNCTION_ARG_BOUNDARY(MODE, TYPE) \ -((TARGET_ARCH64 \ - && (GET_MODE_ALIGNMENT (MODE) == 128 \ - || ((TYPE) && TYPE_ALIGN (TYPE) == 128))) \ - ? 128 : PARM_BOUNDARY) - /* 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/xtensa/xtensa-protos.h b/gcc/config/xtensa/xtensa-protos.h index dc1075f..898c808 100644 --- a/gcc/config/xtensa/xtensa-protos.h +++ b/gcc/config/xtensa/xtensa-protos.h @@ -72,10 +72,6 @@ extern reg_class_t xtensa_secondary_reload (bool, rtx, reg_class_t, struct secondary_reload_info *); #endif /* RTX_CODE */ -#ifdef TREE_CODE -extern int function_arg_boundary (enum machine_mode, tree); -#endif /* TREE_CODE */ - extern void xtensa_setup_frame_addresses (void); extern int xtensa_dbx_register_number (int); extern long compute_frame_size (int); diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c index 4abe2ae..9e7c612 100644 --- a/gcc/config/xtensa/xtensa.c +++ b/gcc/config/xtensa/xtensa.c @@ -148,6 +148,8 @@ static rtx xtensa_function_arg (CUMULATIVE_ARGS *, enum machine_mode, static rtx xtensa_function_incoming_arg (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool); static rtx xtensa_function_value (const_tree, const_tree, bool); +static unsigned int xtensa_function_arg_boundary (enum machine_mode, + const_tree); static void xtensa_init_builtins (void); static tree xtensa_fold_builtin (tree, int, tree *, bool); static rtx xtensa_expand_builtin (tree, rtx, rtx, enum machine_mode, int); @@ -228,6 +230,8 @@ static const struct default_options xtensa_option_optimization_table[] = #define TARGET_FUNCTION_ARG xtensa_function_arg #undef TARGET_FUNCTION_INCOMING_ARG #define TARGET_FUNCTION_INCOMING_ARG xtensa_function_incoming_arg +#undef TARGET_FUNCTION_ARG_BOUNDARY +#define TARGET_FUNCTION_ARG_BOUNDARY xtensa_function_arg_boundary #undef TARGET_EXPAND_BUILTIN_SAVEREGS #define TARGET_EXPAND_BUILTIN_SAVEREGS xtensa_builtin_saveregs @@ -2093,8 +2097,8 @@ xtensa_function_incoming_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, return xtensa_function_arg_1 (cum, mode, type, true); } -int -function_arg_boundary (enum machine_mode mode, tree type) +static unsigned int +function_arg_boundary (enum machine_mode mode, const_tree type) { unsigned int alignment; diff --git a/gcc/config/xtensa/xtensa.h b/gcc/config/xtensa/xtensa.h index ee528ef..bd04893 100644 --- a/gcc/config/xtensa/xtensa.h +++ b/gcc/config/xtensa/xtensa.h @@ -591,8 +591,6 @@ typedef struct xtensa_args #define INIT_CUMULATIVE_INCOMING_ARGS(CUM, FNTYPE, LIBNAME) \ init_cumulative_args (&CUM, 1) -#define FUNCTION_ARG_BOUNDARY function_arg_boundary - /* Profiling Xtensa code is typically done with the built-in profiling feature of Tensilica's instruction set simulator, which does not require any compiler support. Profiling code on a real (i.e., diff --git a/gcc/defaults.h b/gcc/defaults.h index 7d3b849..cfbc04d 100644 --- a/gcc/defaults.h +++ b/gcc/defaults.h @@ -1256,14 +1256,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see DEFAULT_FUNCTION_ARG_PADDING ((MODE), (TYPE)) #endif -/* Supply a default definition for FUNCTION_ARG_BOUNDARY. Normally, we let - FUNCTION_ARG_PADDING, which also pads the length, handle any needed - alignment. */ - -#ifndef FUNCTION_ARG_BOUNDARY -#define FUNCTION_ARG_BOUNDARY(MODE, TYPE) PARM_BOUNDARY -#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 5446501..60c4b84 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -4190,8 +4190,8 @@ to pad out an argument with extra space. The value should be of type @code{downward} to pad below, or @code{none} to inhibit padding. The @emph{amount} of padding is always just enough to reach the next -multiple of @code{FUNCTION_ARG_BOUNDARY}; this macro does not control -it. +multiple of @code{TARGET_FUNCTION_ARG_BOUNDARY}; this macro does not +control it. This macro has a default definition which is right for most systems. For little-endian machines, the default is to pad upward. For @@ -4218,11 +4218,11 @@ a three byte aggregate may be passed in the high part of a register if so required. @end defmac -@defmac FUNCTION_ARG_BOUNDARY (@var{mode}, @var{type}) -If defined, a C expression that gives the alignment boundary, in bits, -of an argument with the specified mode and type. If it is not defined, -@code{PARM_BOUNDARY} is used for all arguments. -@end defmac +@deftypefn {Target Hook} {unsigned int} TARGET_FUNCTION_ARG_BOUNDARY (enum machine_mode @var{mode}, const_tree @var{type}) +This hook returns the the alignment boundary, in bits, of an argument +with the specified mode and type. The default hook returns +@code{PARM_BOUNDARY} for all arguments. +@end deftypefn @defmac FUNCTION_ARG_REGNO_P (@var{regno}) A C expression that is nonzero if @var{regno} is the number of a hard diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 4b21c92..cef2a72 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -4180,8 +4180,8 @@ to pad out an argument with extra space. The value should be of type @code{downward} to pad below, or @code{none} to inhibit padding. The @emph{amount} of padding is always just enough to reach the next -multiple of @code{FUNCTION_ARG_BOUNDARY}; this macro does not control -it. +multiple of @code{TARGET_FUNCTION_ARG_BOUNDARY}; this macro does not +control it. This macro has a default definition which is right for most systems. For little-endian machines, the default is to pad upward. For @@ -4208,11 +4208,11 @@ a three byte aggregate may be passed in the high part of a register if so required. @end defmac -@defmac FUNCTION_ARG_BOUNDARY (@var{mode}, @var{type}) -If defined, a C expression that gives the alignment boundary, in bits, -of an argument with the specified mode and type. If it is not defined, -@code{PARM_BOUNDARY} is used for all arguments. -@end defmac +@hook TARGET_FUNCTION_ARG_BOUNDARY +This hook returns the the alignment boundary, in bits, of an argument +with the specified mode and type. The default hook returns +@code{PARM_BOUNDARY} for all arguments. +@end deftypefn @defmac FUNCTION_ARG_REGNO_P (@var{regno}) A C expression that is nonzero if @var{regno} is the number of a hard diff --git a/gcc/function.c b/gcc/function.c index 18025e3..b9805dc 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -2565,7 +2565,7 @@ assign_parm_find_stack_rtl (tree parm, struct assign_parm_data_one *data) align = BITS_PER_UNIT; /* If we're padding upward, we know that the alignment of the slot - is FUNCTION_ARG_BOUNDARY. If we're using slot_offset, we're + 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) @@ -3330,8 +3330,9 @@ assign_parms (tree fndecl) /* Estimate stack alignment from parameter alignment. */ if (SUPPORTS_STACK_ALIGNMENT) { - unsigned int align = FUNCTION_ARG_BOUNDARY (data.promoted_mode, - data.passed_type); + unsigned int align + = targetm.calls.function_arg_boundary (data.promoted_mode, + data.passed_type); align = MINIMUM_ALIGNMENT (data.passed_type, data.promoted_mode, align); if (TYPE_ALIGN (data.nominal_type) > align) @@ -3641,9 +3642,10 @@ gimplify_parameters (void) FNDECL is the function in which the argument was defined. There are two types of rounding that are done. The first, controlled by - FUNCTION_ARG_BOUNDARY, forces the offset from the start of the argument - list to be aligned to the specific boundary (in bits). This rounding - affects the initial and starting offsets, but not the argument size. + TARGET_FUNCTION_ARG_BOUNDARY, forces the offset from the start of the + argument list to be aligned to the specific boundary (in bits). This + rounding affects the initial and starting offsets, but not the argument + size. The second, controlled by FUNCTION_ARG_PADDING and PARM_BOUNDARY, optionally rounds the size of the parm to PARM_BOUNDARY. The @@ -3694,7 +3696,7 @@ locate_and_pad_parm (enum 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); - boundary = FUNCTION_ARG_BOUNDARY (passed_mode, type); + boundary = targetm.calls.function_arg_boundary (passed_mode, type); locate->where_pad = where_pad; /* Alignment can't exceed MAX_SUPPORTED_STACK_ALIGNMENT. */ diff --git a/gcc/target.def b/gcc/target.def index 66006ae..2134145 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -1991,6 +1991,12 @@ DEFHOOK_UNDOC bool named), default_function_incoming_arg) +DEFHOOK +(function_arg_boundary, + "", + unsigned int, (enum machine_mode mode, const_tree type), + default_function_arg_boundary) + /* Return the diagnostic message string if function without a prototype is not allowed for this 'val' argument; NULL otherwise. */ DEFHOOK diff --git a/gcc/targhooks.c b/gcc/targhooks.c index 3647436..35cd592 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -607,6 +607,13 @@ default_function_incoming_arg (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, #endif } +unsigned int +default_function_arg_boundary (enum machine_mode mode ATTRIBUTE_UNUSED, + const_tree type ATTRIBUTE_UNUSED) +{ + return PARM_BOUNDARY; +} + void hook_void_bitmap (bitmap regs ATTRIBUTE_UNUSED) { diff --git a/gcc/targhooks.h b/gcc/targhooks.h index eeefe05..71b612f 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -111,6 +111,8 @@ extern rtx default_function_arg (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool); extern rtx default_function_incoming_arg (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool); +extern unsigned int default_function_arg_boundary (enum machine_mode, + const_tree); extern bool hook_bool_const_rtx_commutative_p (const_rtx, int); extern rtx default_function_value (const_tree, const_tree, bool); extern rtx default_libcall_value (enum machine_mode, const_rtx);