diff options
65 files changed, 463 insertions, 365 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d0bfe32..cdf3aae 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,112 @@ +2004-07-13 Richard Henderson <rth@redhat.com> + + * target.h (struct gcc_target): Add calls.pass_by_reference. + * target-def.h (TARGET_PASS_BY_REFERENCE): New. + * function.c (pass_by_reference): Use the hook. + * system.h (FUNCTION_ARG_PASS_BY_REFERENCE): Poison. + * targhooks.c, targhooks.h (hook_pass_by_reference_false): New. + (hook_pass_by_reference_must_pass_in_stack): New. + * config/alpha/alpha.c (function_arg): Don't query pass-by-ref. + (alpha_pass_by_reference): New. + (TARGET_PASS_BY_REFERENCE): New. + * config/alpha/alpha.h (FUNCTION_ARG_PASS_BY_REFERENCE): Remove. + * config/arc/arc.c (arc_pass_by_reference): New. + (TARGET_PASS_BY_REFERENCE): New. + * config/arc/arc.h (FUNCTION_ARG_PASS_BY_REFERENCE): Remove. + (FUNCTION_ARG_CALLEE_COPIES): True. + * config/arm/arm-protos.h (arm_function_arg_pass_by_reference): Remove. + * config/arm/arm.c (TARGET_PASS_BY_REFERENCE): New. + (arm_pass_by_reference): Rename from arm_function_arg_pass_by_reference. + * config/arm/arm.h (FUNCTION_ARG_PASS_BY_REFERENCE): Remove. + * config/c4x/c4x.h (FUNCTION_ARG_PASS_BY_REFERENCE): Remove. + * config/cris/cris.c (cris_pass_by_reference): New. + (TARGET_PASS_BY_REFERENCE): New. + * config/cris/cris.h (FUNCTION_ARG): Don't query pass-by-ref. + (FUNCTION_INCOMING_ARG, FUNCTION_ARG_ADVANCE): Likewise. + (FUNCTION_ARG_PASS_BY_REFERENCE): Remove. + * config/fr30/fr30.c (TARGET_PASS_BY_REFERENCE): New. + * config/fr30/fr30.h (FUNCTION_ARG_PASS_BY_REFERENCE): Remove. + * config/frv/frv-protos.h (frv_function_arg_pass_by_reference): Kill. + * config/frv/frv.c (TARGET_PASS_BY_REFERENCE): New. + (frv_function_arg_pass_by_reference): Remove. + * config/frv/frv.h (FUNCTION_ARG_PASS_BY_REFERENCE): Remove. + * config/i386/i386-protos.h (function_arg_pass_by_reference): Remove. + * config/i386/i386.c (TARGET_PASS_BY_REFERENCE): New. + (ix86_pass_by_reference): Rename from function_arg_pass_by_reference. + * config/i386/i386.h (FUNCTION_ARG_PASS_BY_REFERENCE): Remove. + * config/ia64/ia64-protos.h (ia64_function_arg_pass_by_reference): Kill. + * config/ia64/ia64.c (TARGET_PASS_BY_REFERENCE): New. + (ia64_pass_by_reference): Rename from + ia64_function_arg_pass_by_reference. + * config/ia64/ia64.h (FUNCTION_ARG_PASS_BY_REFERENCE): Remove. + * config/ip2k/ip2k.h (FUNCTION_ARG_PASS_BY_REFERENCE): Remove. + * config/iq2000/iq2000-protos.h (function_arg_pass_by_reference): Kill. + * config/iq2000/iq2000.c (TARGET_PASS_BY_REFERENCE): New. + (iq2000_pass_by_reference): Rename from function_arg_pass_by_reference. + * config/iq2000/iq2000.h (FUNCTION_ARG_PASS_BY_REFERENCE): Remove. + (FUNCTION_ARG_CALLEE_COPIES): Don't reference pass-by-ref. + * config/m32r/m32r-protos.h (m32r_pass_by_reference): Remove. + * config/m32r/m32r.c (TARGET_PASS_BY_REFERENCE): New. + (m32r_pass_by_reference): Adjust prototype. Make static. + Handle mode sizes correctly. + * config/m32r/m32r.h (FUNCTION_ARG_PASS_BY_REFERENCE): Remove. + * config/m68hc11/m68hc11-protos.h, config/m68hc11/m68hc11.c + (m68hc11_function_arg_pass_by_reference): Remove. + * config/m68hc11/m68hc11.h (FUNCTION_ARG_PASS_BY_REFERENCE): Remove. + (FUNCTION_ARG_CALLEE_COPIES): Don't reference pass-by-ref. + * config/mcore/mcore.c (TARGET_PASS_BY_REFERENCE): New. + * config/mcore/mcore.h (FUNCTION_ARG_PASS_BY_REFERENCE): Remove. + * config/mips/mips-protos.h (function_arg_pass_by_reference): Remove. + * config/mips/mips.c (TARGET_PASS_BY_REFERENCE): New. + (mips_va_arg): Use pass_by_reference. + (mips_pass_by_reference): Rename from function_arg_pass_by_reference. + Handle mode sizes correctly. + * config/mips/mips.h (FUNCTION_ARG_PASS_BY_REFERENCE): Remove. + (FUNCTION_ARG_CALLEE_COPIES): Don't reference pass-by-ref. + * config/mmix/mmix-protos.h (mmix_function_arg_pass_by_reference): Kill. + * config/mmix/mmix.c (TARGET_PASS_BY_REFERENCE): New. + (mmix_pass_by_reference): Rename from + mmix_function_arg_pass_by_reference. + * config/mmix/mmix.h (FUNCTION_ARG_PASS_BY_REFERENCE): Remove. + (FUNCTION_ARG_CALLEE_COPIES): True. + * config/mn10300/mn10300.c (TARGET_PASS_BY_REFERENCE): New. + (mn10300_pass_by_reference): New. + * config/mn10300/mn10300.h (FUNCTION_ARG_PASS_BY_REFERENCE): Remove. + (FUNCTION_ARG_CALLEE_COPIES): True. + * config/pa/pa.c (pa_pass_by_reference): New. + (TARGET_PASS_BY_REFERENCE): New. + * config/pa/pa.h (FUNCTION_ARG_PASS_BY_REFERENCE): Remove. + (FUNCTION_ARG_CALLEE_COPIES): True. + * config/rs6000/rs6000-protos.h (function_arg_pass_by_reference): Kill. + * config/rs6000/rs6000.c (TARGET_PASS_BY_REFERENCE): New. + (rs6000_pass_by_reference): Rename from function_arg_pass_by_reference. + * config/rs6000/rs6000.h (FUNCTION_ARG_PASS_BY_REFERENCE): Remove. + * config/s390/s390-protos.h (s390_function_arg_pass_by_reference): Kill. + * config/s390/s390.c (TARGET_PASS_BY_REFERENCE): New. + (s390_pass_by_reference): Rename from + s390_function_arg_pass_by_reference. + (s390_function_arg_advance): Don't query pass-by-ref. + (s390_function_arg): Likewise. + (s390_gimplify_va_arg): Use pass_by_reference. + (s390_call_saved_register_used): Likewise. + * config/s390/s390.h (FUNCTION_ARG_PASS_BY_REFERENCE): Remove. + * config/sh/sh.c (TARGET_PASS_BY_REFERENCE): New. + (shcompact_byref, sh_pass_by_reference): New. + * config/sh/sh.h (FUNCTION_ARG_PASS_BY_REFERENCE): Remove. + (SHCOMPACT_BYREF): Remove. + * config/sparc/sparc-protos.h (function_arg_pass_by_reference): Kill. + * config/sparc/sparc.c (TARGET_PASS_BY_REFERENCE): New. + (sparc_pass_by_reference): Rename from function_arg_pass_by_reference. + (sparc_gimplify_va_arg): Use pass_by_reference. + * config/sparc/sparc.h (FUNCTION_ARG_PASS_BY_REFERENCE): Remove. + * config/stormy16/stormy16.h (FUNCTION_ARG_PASS_BY_REFERENCE): Remove. + * config/v850/v850.c (TARGET_PASS_BY_REFERENCE): New. + (v850_pass_by_reference): New. + * config/v850/v850.h (FUNCTION_ARG_PASS_BY_REFERENCE): Remove. + (FUNCTION_ARG_CALLEE_COPIES): True. + * doc/tm.texi (TARGET_PASS_BY_REFERENCE): Update from + FUNCTION_ARG_PASS_BY_REFERENCE docs. + 2004-07-14 Richard Henderson <rth@redhat.com> Richard Sandiford <rsandifo@redhat.com> diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index 422d6c6..8ed7b78 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -5922,8 +5922,6 @@ function_arg (CUMULATIVE_ARGS cum, enum machine_mode mode, tree type, basereg = 16; else if (targetm.calls.must_pass_in_stack (mode, type)) return NULL_RTX; - else if (FUNCTION_ARG_PASS_BY_REFERENCE (cum, mode, type, named)) - basereg = 16; } #else #error Unhandled ABI @@ -5979,6 +5977,17 @@ alpha_return_in_memory (tree type, tree fndecl ATTRIBUTE_UNUSED) return size > UNITS_PER_WORD; } +/* Return true if TYPE should be passed by invisible reference. */ + +static bool +alpha_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, + enum machine_mode mode, + tree type ATTRIBUTE_UNUSED, + bool named ATTRIBUTE_UNUSED) +{ + return mode == TFmode || mode == TCmode; +} + /* Define how to find the value returned by a function. VALTYPE is the data type of the value (as a tree). If the precise function being called is known, FUNC is its FUNCTION_DECL; otherwise, FUNC is 0. @@ -10187,6 +10196,8 @@ alpha_init_libfuncs (void) #define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_false #undef TARGET_RETURN_IN_MEMORY #define TARGET_RETURN_IN_MEMORY alpha_return_in_memory +#undef TARGET_PASS_BY_REFERENCE +#define TARGET_PASS_BY_REFERENCE alpha_pass_by_reference #undef TARGET_SETUP_INCOMING_VARARGS #define TARGET_SETUP_INCOMING_VARARGS alpha_setup_incoming_varargs #undef TARGET_STRICT_ARGUMENT_NAMING diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h index e142e5e..b77a9bc 100644 --- a/gcc/config/alpha/alpha.h +++ b/gcc/config/alpha/alpha.h @@ -1063,15 +1063,6 @@ extern int alpha_memory_latency; #define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \ function_arg((CUM), (MODE), (TYPE), (NAMED)) -/* A C expression that indicates when an argument must be passed by - reference. If nonzero for an argument, a copy of that argument is - made in memory and a pointer to the argument is passed instead of - the argument itself. The pointer is passed in whatever way is - appropriate for passing a pointer to that type. */ - -#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \ - ((MODE) == TFmode || (MODE) == TCmode) - /* For an arg passed partly in registers and partly in memory, this is the number of registers used. For args passed entirely in registers or entirely in memory, zero. */ diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c index d648028..cbc0efa 100644 --- a/gcc/config/arc/arc.c +++ b/gcc/config/arc/arc.c @@ -102,6 +102,8 @@ static bool arc_rtx_costs (rtx, int, int, int *); static int arc_address_cost (rtx); static void arc_external_libcall (rtx); static bool arc_return_in_memory (tree, tree); +static bool arc_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, + tree, bool); /* Initialize the GCC target structure. */ #undef TARGET_ASM_ALIGNED_HI_OP @@ -138,6 +140,8 @@ static bool arc_return_in_memory (tree, tree); #undef TARGET_RETURN_IN_MEMORY #define TARGET_RETURN_IN_MEMORY arc_return_in_memory +#undef TARGET_PASS_BY_REFERENCE +#define TARGET_PASS_BY_REFERENCE arc_pass_by_reference #undef TARGET_SETUP_INCOMING_VARARGS #define TARGET_SETUP_INCOMING_VARARGS arc_setup_incoming_varargs @@ -2333,3 +2337,26 @@ arc_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED) return (size == -1 || size > 8); } } + +/* For ARC, All aggregates and arguments greater than 8 bytes are + passed by reference. */ + +static bool +arc_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, + enum machine_mode mode, tree type, + bool named ATTRIBUTE_UNUSED) +{ + unsigned HOST_WIDE_INT size; + + if (type) + { + if (AGGREGATE_TYPE_P (type)) + return true; + size = int_size_in_bytes (type); + } + else + size = GET_MODE_SIZE (mode); + + return size > 8; +} + diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h index 55cb8f4..d615364 100644 --- a/gcc/config/arc/arc.h +++ b/gcc/config/arc/arc.h @@ -696,17 +696,6 @@ extern enum reg_class arc_regno_reg_class[FIRST_PSEUDO_REGISTER]; registers. */ #define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0 -/* A C expression that indicates when an argument must be passed by - reference. If nonzero for an argument, a copy of that argument is - made in memory and a pointer to the argument is passed instead of - the argument itself. The pointer is passed in whatever way is - appropriate for passing a pointer to that type. */ -/* All aggregates and arguments greater than 8 bytes are passed this way. */ -#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \ -(TYPE \ - && (AGGREGATE_TYPE_P (TYPE) \ - || int_size_in_bytes (TYPE) > 8)) - /* A C expression that indicates when it is the called function's responsibility to make copies of arguments passed by reference. If the callee can determine that the argument won't be modified, it can @@ -714,8 +703,7 @@ extern enum reg_class arc_regno_reg_class[FIRST_PSEUDO_REGISTER]; /* ??? We'd love to be able to use NAMED here. Unfortunately, it doesn't include the last named argument so we keep track of the args ourselves. */ -#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) \ -FUNCTION_ARG_PASS_BY_REFERENCE ((CUM), (MODE), (TYPE), (NAMED)) +#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) 1 /* Update the data in CUM to advance over an argument of mode MODE and data type TYPE. diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index 3124d4f..ce3ff6a 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -156,8 +156,6 @@ extern const char *vfp_output_fstmx (rtx *); extern rtx arm_function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree, int); extern void arm_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree); extern rtx arm_va_arg (tree, tree); -extern int arm_function_arg_pass_by_reference (CUMULATIVE_ARGS *, - enum machine_mode, tree, int); extern bool arm_needs_doubleword_align (enum machine_mode, tree); extern rtx arm_function_value(tree, tree); #endif diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 8da8881..a94b82b 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -157,6 +157,8 @@ static void aof_file_end (void); static rtx arm_struct_value_rtx (tree, int); static void arm_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode, tree, int *, int); +static bool arm_pass_by_reference (CUMULATIVE_ARGS *, + enum machine_mode, tree, bool); static bool arm_promote_prototypes (tree); static bool arm_default_short_enums (void); static bool arm_align_anon_bitfield (void); @@ -255,6 +257,8 @@ static bool arm_cookie_has_size (void); #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true #undef TARGET_PROMOTE_PROTOTYPES #define TARGET_PROMOTE_PROTOTYPES arm_promote_prototypes +#undef TARGET_PASS_BY_REFERENCE +#define TARGET_PASS_BY_REFERENCE arm_pass_by_reference #undef TARGET_STRUCT_VALUE_RTX #define TARGET_STRUCT_VALUE_RTX arm_struct_value_rtx @@ -2396,10 +2400,10 @@ arm_function_arg (CUMULATIVE_ARGS *pcum, enum machine_mode mode, /* Variable sized types are passed by reference. This is a GCC extension to the ARM ABI. */ -int -arm_function_arg_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, - enum machine_mode mode ATTRIBUTE_UNUSED, - tree type, int named ATTRIBUTE_UNUSED) +static bool +arm_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, + enum machine_mode mode ATTRIBUTE_UNUSED, + tree type, bool named ATTRIBUTE_UNUSED) { return type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST; } diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index a66ec4d..ad006c5 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -1700,14 +1700,6 @@ typedef struct && (CUM).can_split) \ ? NUM_ARG_REGS - (CUM).nregs : 0) -/* A C expression that indicates when an argument must be passed by - reference. If nonzero for an argument, a copy of that argument is - made in memory and a pointer to the argument is passed instead of - the argument itself. The pointer is passed in whatever way is - appropriate for passing a pointer to that type. */ -#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \ - arm_function_arg_pass_by_reference (&CUM, MODE, TYPE, NAMED) - /* Initialize a variable CUM of type CUMULATIVE_ARGS for a call to a function whose data type is FNTYPE. For a library call, FNTYPE is 0. diff --git a/gcc/config/c4x/c4x.h b/gcc/config/c4x/c4x.h index 823a608..ff2e634 100644 --- a/gcc/config/c4x/c4x.h +++ b/gcc/config/c4x/c4x.h @@ -1130,10 +1130,6 @@ CUMULATIVE_ARGS; #define CALLER_SAVE_PROFITABLE(REFS,CALLS) 0 -/* Never pass data by reference. */ - -#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) 0 - #define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0 /* 1 if N is a possible register number for function argument passing. */ diff --git a/gcc/config/cris/cris.c b/gcc/config/cris/cris.c index b28896f..50f5e59 100644 --- a/gcc/config/cris/cris.c +++ b/gcc/config/cris/cris.c @@ -115,6 +115,8 @@ static void cris_init_libfuncs (void); static bool cris_rtx_costs (rtx, int, int, int *); static int cris_address_cost (rtx); +static bool cris_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, + tree, bool); /* The function cris_target_asm_function_epilogue puts the last insn to output here. It always fits; there won't be a symbol operand. Used in @@ -183,12 +185,12 @@ int cris_cpu_version = CRIS_DEFAULT_CPU_VERSION; #undef TARGET_PROMOTE_FUNCTION_ARGS #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true - #undef TARGET_STRUCT_VALUE_RTX #define TARGET_STRUCT_VALUE_RTX cris_struct_value_rtx - #undef TARGET_SETUP_INCOMING_VARARGS #define TARGET_SETUP_INCOMING_VARARGS cris_setup_incoming_varargs +#undef TARGET_PASS_BY_REFERENCE +#define TARGET_PASS_BY_REFERENCE cris_pass_by_reference struct gcc_target targetm = TARGET_INITIALIZER; @@ -3160,6 +3162,19 @@ cris_setup_incoming_varargs (CUMULATIVE_ARGS *ca, } } +/* Return true if TYPE must be passed by invisible reference. + For cris, we pass <= 8 bytes by value, others by reference. */ + +static bool +cris_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, + enum machine_mode mode, tree type, + bool named ATTRIBUTE_UNUSED) +{ + return (targetm.calls.must_pass_in_stack (mode, type) + || CRIS_FUNCTION_ARG_SIZE (mode, type) > 8); +} + + #if 0 /* Various small functions to replace macros. Only called from a debugger. They might collide with gcc functions or system functions, diff --git a/gcc/config/cris/cris.h b/gcc/config/cris/cris.h index 252992b..a308412 100644 --- a/gcc/config/cris/cris.h +++ b/gcc/config/cris/cris.h @@ -68,7 +68,6 @@ Boston, MA 02111-1307, USA. */ #define CRIS_PLT_GOTOFFSET_SUFFIX ":PLTG" #define CRIS_PLT_PCOFFSET_SUFFIX ":PLT" -/* If you tweak this, don't forget to check cris_expand_builtin_va_arg. */ #define CRIS_FUNCTION_ARG_SIZE(MODE, TYPE) \ ((MODE) != BLKmode ? GET_MODE_SIZE (MODE) \ : (unsigned) int_size_in_bytes (TYPE)) @@ -939,13 +938,9 @@ enum reg_class {NO_REGS, ALL_REGS, LIM_REG_CLASSES}; /* Node: Register Arguments */ -/* The void_type_node is sent as a "closing" call. We have to stop it - since it's invalid to FUNCTION_ARG_PASS_BY_REFERENCE (or was invalid at - some time). */ +/* The void_type_node is sent as a "closing" call. */ #define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \ ((CUM).regs < CRIS_MAX_ARGS_IN_REGS \ - && (TYPE) != void_type_node \ - && ! FUNCTION_ARG_PASS_BY_REFERENCE (CUM, MODE, TYPE, NAMED) \ ? gen_rtx_REG (MODE, (CRIS_FIRST_ARG_REG) + (CUM).regs) \ : NULL_RTX) @@ -953,9 +948,8 @@ enum reg_class {NO_REGS, ALL_REGS, LIM_REG_CLASSES}; that an argument is named, since incoming stdarg/varargs arguments are pushed onto the stack, and we don't have to check against the "closing" void_type_node TYPE parameter. */ -#define FUNCTION_INCOMING_ARG(CUM, MODE, TYPE, NAMED) \ - (((NAMED) && (CUM).regs < CRIS_MAX_ARGS_IN_REGS \ - && ! FUNCTION_ARG_PASS_BY_REFERENCE (CUM, MODE, TYPE, NAMED)) \ +#define FUNCTION_INCOMING_ARG(CUM, MODE, TYPE, NAMED) \ + ((NAMED) && (CUM).regs < CRIS_MAX_ARGS_IN_REGS \ ? gen_rtx_REG (MODE, CRIS_FIRST_ARG_REG + (CUM).regs) \ : NULL_RTX) @@ -966,13 +960,6 @@ enum reg_class {NO_REGS, ALL_REGS, LIM_REG_CLASSES}; && CRIS_FUNCTION_ARG_SIZE (MODE, TYPE) <= 8) \ ? 1 : 0) -/* Structs may be passed by value, but they must not be more than 8 - bytes long. If you tweak this, don't forget to adjust - cris_expand_builtin_va_arg. */ -#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \ - (targetm.calls.must_pass_in_stack (MODE, TYPE) \ - || CRIS_FUNCTION_ARG_SIZE (MODE, TYPE) > 8) \ - /* Contrary to what you'd believe, defining FUNCTION_ARG_CALLEE_COPIES seems like a (small total) loss, at least for gcc-2.7.2 compiling and running gcc-2.1 (small win in size, small loss running -- 100.1%), @@ -991,11 +978,7 @@ struct cum_args {int regs;}; ((CUM).regs = 0) #define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \ - ((CUM).regs \ - = (FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \ - ? (CRIS_MAX_ARGS_IN_REGS) + 1 \ - : ((CUM).regs \ - + (3 + (CRIS_FUNCTION_ARG_SIZE (MODE, TYPE))) / 4))) + ((CUM).regs += (3 + CRIS_FUNCTION_ARG_SIZE (MODE, TYPE)) / 4) #define FUNCTION_ARG_REGNO_P(REGNO) \ ((REGNO) >= CRIS_FIRST_ARG_REG \ diff --git a/gcc/config/fr30/fr30.c b/gcc/config/fr30/fr30.c index 98e45c4..55d1154 100644 --- a/gcc/config/fr30/fr30.c +++ b/gcc/config/fr30/fr30.c @@ -152,6 +152,9 @@ static bool fr30_must_pass_in_stack (enum machine_mode, tree); #undef TARGET_PROMOTE_PROTOTYPES #define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true +#undef TARGET_PASS_BY_REFERENCE +#define TARGET_PASS_BY_REFERENCE hook_pass_by_reference_must_pass_in_stack + #undef TARGET_SETUP_INCOMING_VARARGS #define TARGET_SETUP_INCOMING_VARARGS fr30_setup_incoming_varargs #undef TARGET_MUST_PASS_IN_STACK diff --git a/gcc/config/fr30/fr30.h b/gcc/config/fr30/fr30.h index b8bec8e..201690a 100644 --- a/gcc/config/fr30/fr30.h +++ b/gcc/config/fr30/fr30.h @@ -694,9 +694,6 @@ enum reg_class #define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \ fr30_function_arg_partial_nregs (CUM, MODE, TYPE, NAMED) -#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \ - targetm.calls.must_pass_in_stack (MODE, TYPE) - /* A C statement (sans semicolon) for initializing the variable CUM for the state at the beginning of the argument list. The variable has type `CUMULATIVE_ARGS'. The value of FNTYPE is the tree node for the data type diff --git a/gcc/config/frv/frv-protos.h b/gcc/config/frv/frv-protos.h index a7a8ee6..a63669b 100644 --- a/gcc/config/frv/frv-protos.h +++ b/gcc/config/frv/frv-protos.h @@ -84,10 +84,6 @@ extern int frv_function_arg_partial_nregs (CUMULATIVE_ARGS *, enum machine_mode, tree, int); -extern int frv_function_arg_pass_by_reference (CUMULATIVE_ARGS *, - enum machine_mode, - tree, int); - extern int frv_function_arg_callee_copies (CUMULATIVE_ARGS *, enum machine_mode, tree, int); diff --git a/gcc/config/frv/frv.c b/gcc/config/frv/frv.c index 9935fef..5e4a12f 100644 --- a/gcc/config/frv/frv.c +++ b/gcc/config/frv/frv.c @@ -48,6 +48,7 @@ Boston, MA 02111-1307, USA. */ #include <ctype.h> #include "target.h" #include "target-def.h" +#include "targhooks.h" #include "integrate.h" #ifndef FRV_INLINE @@ -329,6 +330,8 @@ static bool frv_must_pass_in_stack (enum machine_mode mode, tree type); #define TARGET_STRUCT_VALUE_RTX frv_struct_value_rtx #undef TARGET_MUST_PASS_IN_STACK #define TARGET_MUST_PASS_IN_STACK frv_must_pass_in_stack +#undef TARGET_PASS_BY_REFERENCE +#define TARGET_PASS_BY_REFERENCE hook_pass_by_reference_must_pass_in_stack #undef TARGET_EXPAND_BUILTIN_SAVEREGS #define TARGET_EXPAND_BUILTIN_SAVEREGS frv_expand_builtin_saveregs @@ -3147,15 +3150,6 @@ frv_function_arg_partial_nregs (CUMULATIVE_ARGS *cum, } -int -frv_function_arg_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, - enum machine_mode mode, - tree type, - int named ATTRIBUTE_UNUSED) -{ - return targetm.calls.must_pass_in_stack (mode, type); -} - /* If defined, a C expression that indicates when it is the called function's responsibility to make a copy of arguments passed by invisible reference. Normally, the caller makes a copy and passes the address of the copy to the diff --git a/gcc/config/frv/frv.h b/gcc/config/frv/frv.h index 493ebc7..838ca17 100644 --- a/gcc/config/frv/frv.h +++ b/gcc/config/frv/frv.h @@ -1901,9 +1901,6 @@ struct machine_function GTY(()) /* extern int frv_function_arg_partial_nregs (CUMULATIVE_ARGS, int, Tree, int); */ -#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \ - frv_function_arg_pass_by_reference (&CUM, MODE, TYPE, NAMED) - /* If defined, a C expression that indicates when it is the called function's responsibility to make a copy of arguments passed by invisible reference. Normally, the caller makes a copy and passes the address of the copy to the diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index 7fb122d..aae3c7a 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -190,8 +190,6 @@ extern enum rtx_code ix86_reverse_condition (enum rtx_code, enum machine_mode); #ifdef TREE_CODE extern void init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree); extern rtx function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree, int); -extern int function_arg_pass_by_reference (CUMULATIVE_ARGS *, - enum machine_mode, tree, int); extern void function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, tree, int); extern rtx ix86_function_value (tree); diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 9b6e30e..0349979 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -929,6 +929,8 @@ static bool ix86_rtx_costs (rtx, int, int, int *); static int min_insn_size (rtx); static tree ix86_md_asm_clobbers (tree clobbers); static bool ix86_must_pass_in_stack (enum machine_mode mode, tree type); +static bool ix86_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, + tree, bool); #if defined (DO_GLOBAL_CTORS_BODY) && defined (HAS_INIT_SECTION) static void ix86_svr3_asm_out_constructor (rtx, int); @@ -1074,6 +1076,8 @@ static void init_ext_80387_constants (void); #define TARGET_SETUP_INCOMING_VARARGS ix86_setup_incoming_varargs #undef TARGET_MUST_PASS_IN_STACK #define TARGET_MUST_PASS_IN_STACK ix86_must_pass_in_stack +#undef TARGET_PASS_BY_REFERENCE +#define TARGET_PASS_BY_REFERENCE ix86_pass_by_reference #undef TARGET_GIMPLIFY_VA_ARG_EXPR #define TARGET_GIMPLIFY_VA_ARG_EXPR ix86_gimplify_va_arg @@ -2775,10 +2779,10 @@ function_arg (CUMULATIVE_ARGS *cum, /* current arg information */ the argument itself. The pointer is passed in whatever way is appropriate for passing a pointer to that type. */ -int -function_arg_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, - enum machine_mode mode ATTRIBUTE_UNUSED, - tree type, int named ATTRIBUTE_UNUSED) +static bool +ix86_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, + enum machine_mode mode ATTRIBUTE_UNUSED, + tree type, bool named ATTRIBUTE_UNUSED) { if (!TARGET_64BIT) return 0; diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 33cd861..c85c889 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -1765,15 +1765,6 @@ typedef struct ix86_args { #define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0 -/* A C expression that indicates when an argument must be passed by - reference. If nonzero for an argument, a copy of that argument is - made in memory and a pointer to the argument is passed instead of - the argument itself. The pointer is passed in whatever way is - appropriate for passing a pointer to that type. */ - -#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \ - function_arg_pass_by_reference(&CUM, MODE, TYPE, NAMED) - /* Implement `va_start' for varargs and stdarg. */ #define EXPAND_BUILTIN_VA_START(VALIST, NEXTARG) \ ix86_va_start (VALIST, NEXTARG) diff --git a/gcc/config/ia64/ia64-protos.h b/gcc/config/ia64/ia64-protos.h index 50456a6..e59dff5 100644 --- a/gcc/config/ia64/ia64-protos.h +++ b/gcc/config/ia64/ia64-protos.h @@ -118,8 +118,6 @@ extern int ia64_function_arg_partial_nregs (CUMULATIVE_ARGS *, enum machine_mode, tree, int); extern void ia64_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, tree, int); -extern int ia64_function_arg_pass_by_reference (CUMULATIVE_ARGS *, - enum machine_mode, tree, int); extern void ia64_asm_output_external (FILE *, tree, const char *); #endif /* TREE_CODE */ diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index 51e410e..7e19f6b 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -189,6 +189,8 @@ static rtx gen_fr_restore_x (rtx, rtx, rtx); static enum machine_mode hfa_element_mode (tree, int); static void ia64_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode, tree, int *, int); +static bool ia64_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, + tree, bool); static bool ia64_function_ok_for_sibcall (tree, tree); static bool ia64_return_in_memory (tree, tree); static bool ia64_rtx_costs (rtx, int, int, int *); @@ -360,6 +362,8 @@ static const struct attribute_spec ia64_attribute_table[] = #undef TARGET_FUNCTION_OK_FOR_SIBCALL #define TARGET_FUNCTION_OK_FOR_SIBCALL ia64_function_ok_for_sibcall +#undef TARGET_PASS_BY_REFERENCE +#define TARGET_PASS_BY_REFERENCE ia64_pass_by_reference #undef TARGET_ASM_OUTPUT_MI_THUNK #define TARGET_ASM_OUTPUT_MI_THUNK ia64_output_mi_thunk @@ -3940,10 +3944,10 @@ ia64_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, /* Variable sized types are passed by reference. */ /* ??? At present this is a GCC extension to the IA-64 ABI. */ -int -ia64_function_arg_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, - enum machine_mode mode ATTRIBUTE_UNUSED, - tree type, int named ATTRIBUTE_UNUSED) +static bool +ia64_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, + enum machine_mode mode ATTRIBUTE_UNUSED, + tree type, bool named ATTRIBUTE_UNUSED) { return type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST; } diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h index 0e649e3..28fe2d5 100644 --- a/gcc/config/ia64/ia64.h +++ b/gcc/config/ia64/ia64.h @@ -1319,15 +1319,6 @@ enum reg_class #define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \ ia64_function_arg_partial_nregs (&CUM, MODE, TYPE, NAMED) -/* A C expression that indicates when an argument must be passed by reference. - If nonzero for an argument, a copy of that argument is made in memory and a - pointer to the argument is passed instead of the argument itself. The - pointer is passed in whatever way is appropriate for passing a pointer to - that type. */ - -#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \ - ia64_function_arg_pass_by_reference (&CUM, MODE, TYPE, NAMED) - /* A C type for declaring a variable that is used as the first argument of `FUNCTION_ARG' and other related values. For some target machines, the type `int' suffices and can hold the number of bytes of argument so far. */ diff --git a/gcc/config/ip2k/ip2k.h b/gcc/config/ip2k/ip2k.h index c24c493..aecc8cd 100644 --- a/gcc/config/ip2k/ip2k.h +++ b/gcc/config/ip2k/ip2k.h @@ -455,9 +455,6 @@ enum reg_class { #define FUNCTION_VALUE_REGNO_P(N) ((N) == REG_RESULT) -/* Indicate that large structures are passed by reference. */ -#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM,MODE,TYPE,NAMED) 0 - #define DEFAULT_PCC_STRUCT_RETURN 0 #define EPILOGUE_USES(REGNO) 0 diff --git a/gcc/config/iq2000/iq2000-protos.h b/gcc/config/iq2000/iq2000-protos.h index 60c34bc..c0eae3b 100644 --- a/gcc/config/iq2000/iq2000-protos.h +++ b/gcc/config/iq2000/iq2000-protos.h @@ -35,7 +35,6 @@ extern void iq2000_expand_prologue (void); extern void iq2000_expand_epilogue (void); extern void iq2000_expand_eh_return (rtx); extern int iq2000_can_use_return_insn (void); -extern int function_arg_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, tree, int); extern int iq2000_adjust_insn_length (rtx, int); extern char * iq2000_output_conditional_branch (rtx, rtx *, int, int, int, int); extern void print_operand_address (FILE *, rtx); diff --git a/gcc/config/iq2000/iq2000.c b/gcc/config/iq2000/iq2000.c index 4da8712..0e2f7c1 100644 --- a/gcc/config/iq2000/iq2000.c +++ b/gcc/config/iq2000/iq2000.c @@ -171,6 +171,8 @@ static bool iq2000_rtx_costs (rtx, int, int, int *); static int iq2000_address_cost (rtx); static void iq2000_select_section (tree, int, unsigned HOST_WIDE_INT); static bool iq2000_return_in_memory (tree, tree); +static bool iq2000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, + tree, bool); #undef TARGET_INIT_BUILTINS #define TARGET_INIT_BUILTINS iq2000_init_builtins @@ -194,6 +196,8 @@ static bool iq2000_return_in_memory (tree, tree); #undef TARGET_RETURN_IN_MEMORY #define TARGET_RETURN_IN_MEMORY iq2000_return_in_memory +#undef TARGET_PASS_BY_REFERENCE +#define TARGET_PASS_BY_REFERENCE iq2000_pass_by_reference #undef TARGET_SETUP_INCOMING_VARARGS #define TARGET_SETUP_INCOMING_VARARGS iq2000_setup_incoming_varargs @@ -2471,13 +2475,11 @@ iq2000_function_value (tree valtype, tree func ATTRIBUTE_UNUSED) return gen_rtx_REG (mode, reg); } -/* The implementation of FUNCTION_ARG_PASS_BY_REFERENCE. Return - nonzero when an argument must be passed by reference. */ +/* Return true when an argument must be passed by reference. */ -int -function_arg_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, - enum machine_mode mode, tree type, - int named ATTRIBUTE_UNUSED) +static bool +iq2000_pass_by_reference (CUMULATIVE_ARGS *cum, enum machine_mode mode, + tree type, bool named ATTRIBUTE_UNUSED) { int size; diff --git a/gcc/config/iq2000/iq2000.h b/gcc/config/iq2000/iq2000.h index d4e27c1..f6f3810 100644 --- a/gcc/config/iq2000/iq2000.h +++ b/gcc/config/iq2000/iq2000.h @@ -441,11 +441,7 @@ enum reg_class #define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \ function_arg_partial_nregs (& CUM, MODE, TYPE, NAMED) -#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \ - function_arg_pass_by_reference (& CUM, MODE, TYPE, NAMED) - -#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) \ - ((NAMED) && FUNCTION_ARG_PASS_BY_REFERENCE (CUM, MODE, TYPE, NAMED)) +#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) (NAMED) #define MAX_ARGS_IN_REGISTERS 8 diff --git a/gcc/config/m32r/m32r-protos.h b/gcc/config/m32r/m32r-protos.h index 89a4cbe..f012033 100644 --- a/gcc/config/m32r/m32r-protos.h +++ b/gcc/config/m32r/m32r-protos.h @@ -94,9 +94,6 @@ extern int reg_or_zero_operand (rtx, Mmode); #endif /* HAVE_MACHINE_MODES */ -#ifdef TREE_CODE -extern int m32r_pass_by_reference (tree); -#endif /* TREE_CODE */ #endif /* RTX_CODE */ #undef Mmode diff --git a/gcc/config/m32r/m32r.c b/gcc/config/m32r/m32r.c index 6c4a5dd..c46bff5 100644 --- a/gcc/config/m32r/m32r.c +++ b/gcc/config/m32r/m32r.c @@ -99,6 +99,8 @@ static void m32r_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode, tree, int *, int); static void init_idents (void); static bool m32r_rtx_costs (rtx, int, int, int *); +static bool m32r_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, + tree, bool); /* Initialize the GCC target structure. */ #undef TARGET_ATTRIBUTE_TABLE @@ -142,6 +144,8 @@ static bool m32r_rtx_costs (rtx, int, int, int *); #define TARGET_SETUP_INCOMING_VARARGS m32r_setup_incoming_varargs #undef TARGET_MUST_PASS_IN_STACK #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size +#undef TARGET_PASS_BY_REFERENCE +#define TARGET_PASS_BY_REFERENCE m32r_pass_by_reference struct gcc_target targetm = TARGET_INITIALIZER; @@ -969,19 +973,21 @@ large_insn_p (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) return get_attr_length (op) != 2; } -/* Return nonzero if TYPE must be passed or returned in memory. - The m32r treats both directions the same so we handle both directions - in this function. */ +/* Return nonzero if TYPE must be passed by indirect reference. */ -int -m32r_pass_by_reference (tree type) +static bool +m32r_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, + enum machine_mode mode, tree type, + bool named ATTRIBUTE_UNUSED) { - int size = int_size_in_bytes (type); + int size; - if (size < 0 || size > 8) - return 1; + if (type) + size = int_size_in_bytes (type); + else + size = GET_MODE_SIZE (mode); - return 0; + return (size < 0 || size > 8); } /* Comparisons. */ @@ -1347,7 +1353,7 @@ function_arg_partial_nregs (CUMULATIVE_ARGS *cum, enum machine_mode mode, static bool m32r_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED) { - return m32r_pass_by_reference (type); + return m32r_pass_by_reference (NULL, TYPE_MODE (type), type, false); } /* Do any needed setup for a variadic function. For the M32R, we must diff --git a/gcc/config/m32r/m32r.h b/gcc/config/m32r/m32r.h index 6300967..2f38e0a 100644 --- a/gcc/config/m32r/m32r.h +++ b/gcc/config/m32r/m32r.h @@ -1110,15 +1110,6 @@ extern enum reg_class m32r_regno_reg_class[FIRST_PSEUDO_REGISTER]; #define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \ function_arg_partial_nregs (&CUM, (int)MODE, TYPE, NAMED) -/* A C expression that indicates when an argument must be passed by - reference. If nonzero for an argument, a copy of that argument is - made in memory and a pointer to the argument is passed instead of - the argument itself. The pointer is passed in whatever way is - appropriate for passing a pointer to that type. */ -/* All arguments greater than 8 bytes are passed this way. */ -#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \ - ((TYPE) && m32r_pass_by_reference (TYPE)) - /* Update the data in CUM to advance over an argument of mode MODE and data type TYPE. (TYPE is null for libcalls where that information may not be available.) */ diff --git a/gcc/config/m68hc11/m68hc11-protos.h b/gcc/config/m68hc11/m68hc11-protos.h index dbd7d87..af8c35b 100644 --- a/gcc/config/m68hc11/m68hc11-protos.h +++ b/gcc/config/m68hc11/m68hc11-protos.h @@ -123,10 +123,6 @@ extern void m68hc11_init_cumulative_args (CUMULATIVE_ARGS*, tree, rtx); extern rtx m68hc11_function_arg (const CUMULATIVE_ARGS* , enum machine_mode, tree, int); -extern int m68hc11_function_arg_pass_by_reference (const CUMULATIVE_ARGS*, - enum machine_mode, - tree, - int); extern int m68hc11_function_arg_padding (enum machine_mode, tree); extern void m68hc11_function_epilogue (FILE*,int); diff --git a/gcc/config/m68hc11/m68hc11.c b/gcc/config/m68hc11/m68hc11.c index 321e1ab..ba58e8b 100644 --- a/gcc/config/m68hc11/m68hc11.c +++ b/gcc/config/m68hc11/m68hc11.c @@ -1472,24 +1472,6 @@ m68hc11_is_trap_symbol (rtx sym) /* Argument support functions. */ -/* Handle the FUNCTION_ARG_PASS_BY_REFERENCE macro. - Arrays are passed by references and other types by value. - - SCz: I tried to pass DImode by reference but it seems that this - does not work very well. */ -int -m68hc11_function_arg_pass_by_reference (const CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, - enum machine_mode mode ATTRIBUTE_UNUSED, - tree type, - int named ATTRIBUTE_UNUSED) -{ - return ((type && TREE_CODE (type) == ARRAY_TYPE) - /* Consider complex values as aggregates, so care for TCmode. */ - /*|| GET_MODE_SIZE (mode) > 4 SCz, temporary */ - /*|| (type && AGGREGATE_TYPE_P (type))) */ ); -} - - /* Define the offset between two registers, one to be eliminated, and the other its replacement, at the start of a routine. */ int diff --git a/gcc/config/m68hc11/m68hc11.h b/gcc/config/m68hc11/m68hc11.h index 378454c..9732219 100644 --- a/gcc/config/m68hc11/m68hc11.h +++ b/gcc/config/m68hc11/m68hc11.h @@ -1036,17 +1036,6 @@ typedef struct m68hc11_args int nregs; } CUMULATIVE_ARGS; -/* A C expression that indicates when an argument must be passed by reference. - If nonzero for an argument, a copy of that argument is made in memory and a - pointer to the argument is passed instead of the argument itself. - The pointer is passed in whatever way is appropriate for passing a pointer - to that type. - - 64-bit numbers are passed by reference. */ -#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \ - m68hc11_function_arg_pass_by_reference (& (CUM), (MODE), (TYPE), (NAMED)) - - /* 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, @@ -1069,8 +1058,7 @@ typedef struct m68hc11_args value. The called function must not modify this value. If it can be determined that the value won't be modified, it need not make a copy; otherwise a copy must be made. */ -#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) \ - ((NAMED) && FUNCTION_ARG_PASS_BY_REFERENCE (CUM, MODE, TYPE, NAMED)) +#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) (NAMED) /* Initialize a variable CUM of type CUMULATIVE_ARGS for a call to a function whose data type is FNTYPE. For a library call, FNTYPE is 0. */ diff --git a/gcc/config/mcore/mcore.c b/gcc/config/mcore/mcore.c index 7bad189..c41ce8f 100644 --- a/gcc/config/mcore/mcore.c +++ b/gcc/config/mcore/mcore.c @@ -194,6 +194,8 @@ static bool mcore_return_in_memory (tree, tree); #define TARGET_RETURN_IN_MEMORY mcore_return_in_memory #undef TARGET_MUST_PASS_IN_STACK #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size +#undef TARGET_PASS_BY_REFERENCE +#define TARGET_PASS_BY_REFERENCE hook_pass_by_reference_must_pass_in_stack #undef TARGET_SETUP_INCOMING_VARARGS #define TARGET_SETUP_INCOMING_VARARGS mcore_setup_incoming_varargs diff --git a/gcc/config/mcore/mcore.h b/gcc/config/mcore/mcore.h index b026c14..b800a93 100644 --- a/gcc/config/mcore/mcore.h +++ b/gcc/config/mcore/mcore.h @@ -712,14 +712,6 @@ extern const enum reg_class reg_class_from_letter[]; #define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \ mcore_function_arg (CUM, MODE, TYPE, NAMED) -/* A C expression that indicates when an argument must be passed by - reference. If nonzero for an argument, a copy of that argument is - made in memory and a pointer to the argument is passed instead of - the argument itself. The pointer is passed in whatever way is - appropriate for passing a pointer to that type. */ -#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \ - targetm.calls.must_pass_in_stack (MODE, TYPE) - /* For an arg passed partly in registers and partly in memory, this is the number of registers used. For args passed entirely in registers or entirely in memory, zero. diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h index f38809e..820d75f 100644 --- a/gcc/config/mips/mips-protos.h +++ b/gcc/config/mips/mips-protos.h @@ -181,8 +181,6 @@ extern void mips_expand_prologue (void); extern void mips_expand_epilogue (int); extern int mips_can_use_return_insn (void); extern struct rtx_def *mips_function_value (tree, tree, enum machine_mode); -extern int function_arg_pass_by_reference (const CUMULATIVE_ARGS *, - enum machine_mode, tree, int); extern bool mips_cannot_change_mode_class (enum machine_mode, enum machine_mode, enum reg_class); diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 3e93a01..02231f3 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -290,6 +290,8 @@ static void mips_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode, tree, int *, int); static tree mips_build_builtin_va_list (void); static tree mips_gimplify_va_arg_expr (tree, tree, tree *, tree *); +static bool mips_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode mode, + tree, bool); #if TARGET_IRIX static void irix_asm_named_section_1 (const char *, unsigned int, @@ -744,6 +746,8 @@ const struct mips_cpu_info mips_cpu_info_table[] = { #define TARGET_STRICT_ARGUMENT_NAMING mips_strict_argument_naming #undef TARGET_MUST_PASS_IN_STACK #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size +#undef TARGET_PASS_BY_REFERENCE +#define TARGET_PASS_BY_REFERENCE mips_pass_by_reference struct gcc_target targetm = TARGET_INITIALIZER; @@ -4045,8 +4049,7 @@ mips_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p) tree addr; bool indirect; - indirect - = function_arg_pass_by_reference (NULL, TYPE_MODE (type), type, 0); + indirect = pass_by_reference (NULL, TYPE_MODE (type), type, 0); if (indirect) type = build_pointer_type (type); @@ -7321,13 +7324,12 @@ mips_function_value (tree valtype, tree func ATTRIBUTE_UNUSED, return gen_rtx_REG (mode, GP_RETURN); } -/* The implementation of FUNCTION_ARG_PASS_BY_REFERENCE. Return - nonzero when an argument must be passed by reference. */ +/* Return nonzero when an argument must be passed by reference. */ -int -function_arg_pass_by_reference (const CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, - enum machine_mode mode, tree type, - int named ATTRIBUTE_UNUSED) +static bool +mips_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, + enum machine_mode mode, tree type, + bool named ATTRIBUTE_UNUSED) { if (mips_abi == ABI_EABI) { @@ -7337,7 +7339,11 @@ function_arg_pass_by_reference (const CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, if (type == NULL_TREE || mode == DImode || mode == DFmode) return 0; - size = int_size_in_bytes (type); + if (type) + size = int_size_in_bytes (type); + else + size = GET_MODE_SIZE (mode); + return size == -1 || size > UNITS_PER_WORD; } else diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index 3517780..a4c7be9 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -2351,9 +2351,6 @@ typedef struct mips_args { ? PARM_BOUNDARY \ : GET_MODE_ALIGNMENT(MODE))) -#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \ - function_arg_pass_by_reference (&CUM, MODE, TYPE, NAMED) - #define FUNCTION_ARG_PADDING(MODE, TYPE) \ (mips_pad_arg_upward (MODE, TYPE) ? upward : downward) @@ -2361,8 +2358,7 @@ typedef struct mips_args { (mips_pad_reg_upward (MODE, TYPE) ? upward : downward) #define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) \ - (mips_abi == ABI_EABI && (NAMED) \ - && FUNCTION_ARG_PASS_BY_REFERENCE (CUM, MODE, TYPE, NAMED)) + (mips_abi == ABI_EABI && (NAMED)) /* 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/mmix/mmix-protos.h b/gcc/config/mmix/mmix-protos.h index e10e65b..c2f02cc 100644 --- a/gcc/config/mmix/mmix-protos.h +++ b/gcc/config/mmix/mmix-protos.h @@ -53,8 +53,6 @@ extern int mmix_local_regno (int); extern int mmix_dbx_register_number (int); extern int mmix_use_simple_return (void); extern void mmix_make_decl_one_only (tree); -extern int mmix_function_arg_pass_by_reference - (const CUMULATIVE_ARGS *, enum machine_mode, tree, int); extern rtx mmix_function_outgoing_value (tree, tree); extern int mmix_function_value_regno_p (int); extern int mmix_data_alignment (tree, int); diff --git a/gcc/config/mmix/mmix.c b/gcc/config/mmix/mmix.c index 4e1731b..ae69548 100644 --- a/gcc/config/mmix/mmix.c +++ b/gcc/config/mmix/mmix.c @@ -139,7 +139,8 @@ static void mmix_file_start (void); static void mmix_file_end (void); static bool mmix_rtx_costs (rtx, int, int, int *); static rtx mmix_struct_value_rtx (tree, int); - +static bool mmix_pass_by_reference (const CUMULATIVE_ARGS *, + enum machine_mode, tree, bool); /* Target structure macros. Listed by node. See `Using and Porting GCC' for a general description. */ @@ -201,9 +202,10 @@ static rtx mmix_struct_value_rtx (tree, int); #undef TARGET_STRUCT_VALUE_RTX #define TARGET_STRUCT_VALUE_RTX mmix_struct_value_rtx - #undef TARGET_SETUP_INCOMING_VARARGS #define TARGET_SETUP_INCOMING_VARARGS mmix_setup_incoming_varargs +#undef TARGET_PASS_BY_REFERENCE +#define TARGET_PASS_BY_REFERENCE mmix_pass_by_reference struct gcc_target targetm = TARGET_INITIALIZER; @@ -590,11 +592,9 @@ mmix_function_arg (const CUMULATIVE_ARGS *argsp, /* Returns nonzero for everything that goes by reference, 0 for everything that goes by value. */ -int -mmix_function_arg_pass_by_reference (const CUMULATIVE_ARGS *argsp, - enum machine_mode mode, - tree type, - int named ATTRIBUTE_UNUSED) +static bool +mmix_pass_by_reference (const CUMULATIVE_ARGS *argsp, enum machine_mode mode, + tree type, bool named ATTRIBUTE_UNUSED) { /* FIXME: Check: I'm not sure the must_pass_in_stack check is necessary. */ diff --git a/gcc/config/mmix/mmix.h b/gcc/config/mmix/mmix.h index 5d68fa7..6894337 100644 --- a/gcc/config/mmix/mmix.h +++ b/gcc/config/mmix/mmix.h @@ -720,18 +720,7 @@ enum reg_class #define FUNCTION_INCOMING_ARG(CUM, MODE, TYPE, NAMED) \ mmix_function_arg (&(CUM), MODE, TYPE, NAMED, 1) -#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \ - mmix_function_arg_pass_by_reference (&(CUM), MODE, TYPE, NAMED) - -/* This *sounds* good, but does not seem to be implemented correctly to - be a win; at least it wasn't in 2.7.2. FIXME: Check and perhaps - replace with a big comment. - The definition needs to match or be a subset of - FUNCTION_ARG_PASS_BY_REFERENCE, since not all callers check that before - usage. Watch lots of C++ testcases fail if set to 1, for example - g++.dg/init/byval1.C. */ -#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) \ - mmix_function_arg_pass_by_reference (&(CUM), MODE, TYPE, NAMED) +#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) 1 typedef struct { int regs; int lib; } CUMULATIVE_ARGS; diff --git a/gcc/config/mn10300/mn10300.c b/gcc/config/mn10300/mn10300.c index b5686c4..a67a75d 100644 --- a/gcc/config/mn10300/mn10300.c +++ b/gcc/config/mn10300/mn10300.c @@ -71,6 +71,8 @@ static bool mn10300_rtx_costs (rtx, int, int, int *); static void mn10300_file_start (void); static bool mn10300_return_in_memory (tree, tree); static rtx mn10300_builtin_saveregs (void); +static bool mn10300_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, + tree, bool); /* Initialize the GCC target structure. */ #undef TARGET_ASM_ALIGNED_HI_OP @@ -91,9 +93,10 @@ static rtx mn10300_builtin_saveregs (void); #undef TARGET_PROMOTE_PROTOTYPES #define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true - #undef TARGET_RETURN_IN_MEMORY #define TARGET_RETURN_IN_MEMORY mn10300_return_in_memory +#undef TARGET_PASS_BY_REFERENCE +#define TARGET_PASS_BY_REFERENCE mn10300_pass_by_reference #undef TARGET_EXPAND_BUILTIN_SAVEREGS #define TARGET_EXPAND_BUILTIN_SAVEREGS mn10300_builtin_saveregs @@ -1456,6 +1459,23 @@ mn10300_va_start (tree valist, rtx nextarg) std_expand_builtin_va_start (valist, nextarg); } +/* Return true when a parameter should be passed by reference. */ + +static bool +mn10300_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, + enum machine_mode mode, tree type, + bool named ATTRIBUTE_UNUSED) +{ + unsigned HOST_WIDE_INT size; + + if (type) + size = int_size_in_bytes (type); + else + size = GET_MODE_SIZE (mode); + + return size > 8; +} + /* Return an RTX to represent where a value with mode MODE will be returned from a function. If the result is 0, the argument is pushed. */ diff --git a/gcc/config/mn10300/mn10300.h b/gcc/config/mn10300/mn10300.h index e831e28..e77f9d2 100644 --- a/gcc/config/mn10300/mn10300.h +++ b/gcc/config/mn10300/mn10300.h @@ -611,11 +611,7 @@ struct cum_arg {int nbytes; }; #define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \ function_arg_partial_nregs (&CUM, MODE, TYPE, NAMED) -#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \ - ((TYPE) && int_size_in_bytes (TYPE) > 8) - -#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) \ - ((TYPE) && int_size_in_bytes (TYPE) > 8) +#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) 1 /* Define how to find the value returned by a function. VALTYPE is the data type of the value (as a tree). diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index 723fbec..7f4ba45 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -143,6 +143,9 @@ static void output_deferred_plabels (void); static void pa_hpux_init_libfuncs (void); #endif static rtx pa_struct_value_rtx (tree, int); +static bool pa_pass_by_reference (CUMULATIVE_ARGS *ca, enum machine_mode, + tree, bool); + /* Save the operands last given to a compare for use when we generate a scc or bcc insn. */ @@ -267,6 +270,8 @@ static size_t n_deferred_plabels = 0; #define TARGET_RETURN_IN_MEMORY pa_return_in_memory #undef TARGET_MUST_PASS_IN_STACK #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size +#undef TARGET_PASS_BY_REFERENCE +#define TARGET_PASS_BY_REFERENCE pa_pass_by_reference #undef TARGET_EXPAND_BUILTIN_SAVEREGS #define TARGET_EXPAND_BUILTIN_SAVEREGS hppa_builtin_saveregs @@ -5838,6 +5843,37 @@ secondary_reload_class (enum reg_class class, enum machine_mode mode, rtx in) return NO_REGS; } +/* In the 32-bit runtime, arguments larger than eight bytes are passed + by invisible reference. As a GCC extension, we also pass anything + with a zero or variable size by reference. + + The 64-bit runtime does not describe passing any types by invisible + reference. The internals of GCC can't currently handle passing + empty structures, and zero or variable length arrays when they are + not passed entirely on the stack or by reference. Thus, as a GCC + extension, we pass these types by reference. The HP compiler doesn't + support these types, so hopefully there shouldn't be any compatibility + issues. This may have to be revisited when HP releases a C99 compiler + or updates the ABI. */ + +static bool +pa_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, + enum machine_mode mode, tree type, + bool named ATTRIBUTE_UNUSED) +{ + HOST_WIDE_INT size; + + if (type) + size = int_size_in_bytes (type); + else + size = GET_MODE_SIZE (mode); + + if (TARGET_64BIT) + return size <= 0; + else + return size <= 0 || size > 8; +} + enum direction function_arg_padding (enum machine_mode mode, tree type) { diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h index 2d60573..0ceedc6 100644 --- a/gcc/config/pa/pa.h +++ b/gcc/config/pa/pa.h @@ -913,27 +913,7 @@ struct hppa_args {int words, nargs_prototype, incoming, indirect; }; : GET_MODE_SIZE(MODE) <= UNITS_PER_WORD) \ ? PARM_BOUNDARY : MAX_PARM_BOUNDARY) -/* In the 32-bit runtime, arguments larger than eight bytes are passed - by invisible reference. As a GCC extension, we also pass anything - with a zero or variable size by reference. - - The 64-bit runtime does not describe passing any types by invisible - reference. The internals of GCC can't currently handle passing - empty structures, and zero or variable length arrays when they are - not passed entirely on the stack or by reference. Thus, as a GCC - extension, we pass these types by reference. The HP compiler doesn't - support these types, so hopefully there shouldn't be any compatibility - issues. This may have to be revisited when HP releases a C99 compiler - or updates the ABI. */ -#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \ - (TARGET_64BIT \ - ? ((TYPE) && int_size_in_bytes (TYPE) <= 0) \ - : (((TYPE) && (int_size_in_bytes (TYPE) > 8 \ - || int_size_in_bytes (TYPE) <= 0)) \ - || ((MODE) && GET_MODE_SIZE (MODE) > 8))) - -#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) \ - FUNCTION_ARG_PASS_BY_REFERENCE (CUM, MODE, TYPE, NAMED) +#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) 1 extern GTY(()) rtx hppa_compare_op0; diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h index 50f4766..c096808 100644 --- a/gcc/config/rs6000/rs6000-protos.h +++ b/gcc/config/rs6000/rs6000-protos.h @@ -156,9 +156,6 @@ extern struct rtx_def *function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree, int); extern int function_arg_partial_nregs (CUMULATIVE_ARGS *, enum machine_mode, tree, int); -extern int function_arg_pass_by_reference (CUMULATIVE_ARGS *, - enum machine_mode, - tree, int); extern rtx rs6000_function_value (tree, tree); extern rtx rs6000_libcall_value (enum machine_mode); extern struct rtx_def *rs6000_va_arg (tree, tree); diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index ea81e8b..1013f97 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -735,6 +735,8 @@ static void rs6000_move_block_from_reg (int regno, rtx x, int nregs); static void setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode, tree, int *, int); +static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, + tree, bool); #if TARGET_MACHO static void macho_branch_islands (void); static void add_compiler_branch_island (tree, tree, int); @@ -951,6 +953,8 @@ static const char alt_reg_names[][8] = #define TARGET_SPLIT_COMPLEX_ARG hook_bool_tree_true #undef TARGET_MUST_PASS_IN_STACK #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack +#undef TARGET_PASS_BY_REFERENCE +#define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference #undef TARGET_BUILD_BUILTIN_VA_LIST #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list @@ -5182,10 +5186,10 @@ function_arg_partial_nregs (CUMULATIVE_ARGS *cum, enum machine_mode mode, As an extension to all ABIs, variable sized types are passed by reference. */ -int -function_arg_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, - enum machine_mode mode ATTRIBUTE_UNUSED, - tree type, int named ATTRIBUTE_UNUSED) +static bool +rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, + enum machine_mode mode ATTRIBUTE_UNUSED, + tree type, bool named ATTRIBUTE_UNUSED) { if ((DEFAULT_ABI == ABI_V4 && ((type && AGGREGATE_TYPE_P (type)) diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index 17df6c0..fdf3d4a 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -1735,15 +1735,6 @@ typedef struct rs6000_args #define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \ function_arg_partial_nregs (&CUM, MODE, TYPE, NAMED) -/* A C expression that indicates when an argument must be passed by - reference. If nonzero for an argument, a copy of that argument is - made in memory and a pointer to the argument is passed instead of - the argument itself. The pointer is passed in whatever way is - appropriate for passing a pointer to that type. */ - -#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \ - function_arg_pass_by_reference(&CUM, MODE, TYPE, NAMED) - /* 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 diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h index 6c9d7e7..447edff 100644 --- a/gcc/config/s390/s390-protos.h +++ b/gcc/config/s390/s390-protos.h @@ -96,7 +96,6 @@ extern rtx s390_load_got (void); #endif /* RTX_CODE */ #ifdef TREE_CODE -extern int s390_function_arg_pass_by_reference (enum machine_mode, tree); extern void s390_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, tree, int); #ifdef RTX_CODE diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 58424a4..4d4aef8 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -81,6 +81,8 @@ static tree s390_build_builtin_va_list (void); static tree s390_gimplify_va_arg (tree, tree, tree *, tree *); static bool s390_function_ok_for_sibcall (tree, tree); static bool s390_call_saved_register_used (tree); +static bool s390_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode mode, + tree, bool); #undef TARGET_ASM_ALIGNED_HI_OP #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t" @@ -155,6 +157,8 @@ static bool s390_call_saved_register_used (tree); #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true #undef TARGET_PROMOTE_FUNCTION_RETURN #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true +#undef TARGET_PASS_BY_REFERENCE +#define TARGET_PASS_BY_REFERENCE s390_pass_by_reference #undef TARGET_FUNCTION_OK_FOR_SIBCALL #define TARGET_FUNCTION_OK_FOR_SIBCALL s390_function_ok_for_sibcall @@ -6324,8 +6328,10 @@ s390_function_arg_integer (enum machine_mode mode, tree type) all other structures (and complex numbers) are passed by reference. */ -int -s390_function_arg_pass_by_reference (enum machine_mode mode, tree type) +static bool +s390_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, + enum machine_mode mode, tree type, + bool named ATTRIBUTE_UNUSED) { int size = s390_function_arg_size (mode, type); if (size > 8) @@ -6354,11 +6360,7 @@ void s390_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type, int named ATTRIBUTE_UNUSED) { - if (s390_function_arg_pass_by_reference (mode, type)) - { - cum->gprs += 1; - } - else if (s390_function_arg_float (mode, type)) + if (s390_function_arg_float (mode, type)) { cum->fprs += 1; } @@ -6394,9 +6396,6 @@ rtx s390_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type, int named ATTRIBUTE_UNUSED) { - if (s390_function_arg_pass_by_reference (mode, type)) - return 0; - if (s390_function_arg_float (mode, type)) { if (cum->fprs + 1 > (TARGET_64BIT? 4 : 2)) @@ -6652,7 +6651,7 @@ s390_gimplify_va_arg (tree valist, tree type, tree *pre_p, size = int_size_in_bytes (type); - if (s390_function_arg_pass_by_reference (TYPE_MODE (type), type)) + if (pass_by_reference (NULL, TYPE_MODE (type), type, false)) { if (TARGET_DEBUG_ARG) { @@ -7364,7 +7363,7 @@ s390_call_saved_register_used (tree argument_list) if (! (mode = TYPE_MODE (TREE_TYPE (parameter)))) abort(); - if (s390_function_arg_pass_by_reference (mode, type)) + if (pass_by_reference (&cum, mode, type, true)) { mode = Pmode; type = build_pointer_type (type); diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h index 85168b4..d804599 100644 --- a/gcc/config/s390/s390.h +++ b/gcc/config/s390/s390.h @@ -665,9 +665,6 @@ CUMULATIVE_ARGS; #define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \ s390_function_arg (&CUM, MODE, TYPE, NAMED) -#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \ - s390_function_arg_pass_by_reference (MODE, TYPE) - #define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0 /* Arguments can be placed in general registers 2 to 6, diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index 4003f16..b3b2ab3 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -282,6 +282,8 @@ static bool sh_strict_argument_naming (CUMULATIVE_ARGS *); static bool sh_pretend_outgoing_varargs_named (CUMULATIVE_ARGS *); static tree sh_build_builtin_va_list (void); static tree sh_gimplify_va_arg_expr (tree, tree, tree *, tree *); +static bool sh_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, + tree, bool); /* Initialize the GCC target structure. */ @@ -438,6 +440,8 @@ static tree sh_gimplify_va_arg_expr (tree, tree, tree *, tree *); #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED sh_pretend_outgoing_varargs_named #undef TARGET_MUST_PASS_IN_STACK #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size +#undef TARGET_PASS_BY_REFERENCE +#define TARGET_PASS_BY_REFERENCE sh_pass_by_reference #undef TARGET_BUILD_BUILTIN_VA_LIST #define TARGET_BUILD_BUILTIN_VA_LIST sh_build_builtin_va_list @@ -6504,6 +6508,51 @@ sh_promote_prototypes (tree type) return ! sh_attr_renesas_p (type); } +/* Whether an argument must be passed by reference. On SHcompact, we + pretend arguments wider than 32-bits that would have been passed in + registers are passed by reference, so that an SHmedia trampoline + loads them into the full 64-bits registers. */ + +static int +shcompact_byref (CUMULATIVE_ARGS *cum, enum machine_mode mode, + tree type, bool named) +{ + unsigned HOST_WIDE_INT size; + + if (type) + size = int_size_in_bytes (type); + else + size = GET_MODE_SIZE (mode); + + if (cum->arg_count[SH_ARG_INT] < NPARM_REGS (SImode) + && (!named + || GET_SH_ARG_CLASS (mode) == SH_ARG_INT + || (GET_SH_ARG_CLASS (mode) == SH_ARG_FLOAT + && cum->arg_count[SH_ARG_FLOAT] >= NPARM_REGS (SFmode))) + && size > 4 + && !SHCOMPACT_FORCE_ON_STACK (mode, type) + && !SH5_WOULD_BE_PARTIAL_NREGS (*cum, mode, type, named)) + return size; + else + return 0; +} + +static bool +sh_pass_by_reference (CUMULATIVE_ARGS *cum, enum machine_mode mode, + tree type, bool named) +{ + if (targetm.calls.must_pass_in_stack (mode, type)) + return true; + + if (TARGET_SHCOMPACT) + { + cum->byref = shcompact_byref (cum, mode, type, named); + return cum->byref != 0; + } + + return false; +} + /* Define where to put the arguments to a function. Value is zero to push the argument on the stack, or a hard register in which to store the argument. diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h index a76bda1..e38361f 100644 --- a/gcc/config/sh/sh.h +++ b/gcc/config/sh/sh.h @@ -1826,8 +1826,8 @@ struct sh_args { used to pass arguments, if the arguments didn't have to be passed by reference. */ int byref_regs; - /* Set by SHCOMPACT_BYREF if the current argument is to be passed by - reference. */ + /* Set as by shcompact_byref if the current argument is to be passed + by reference. */ int byref; /* call_cookie is a bitmask used by call expanders, as well as @@ -2033,31 +2033,6 @@ struct sh_args { foo (float a, __complex float b); a: fr5 b.real: fr4 b.imag: fr7 */ #define FUNCTION_ARG_SCmode_WART 1 -/* Whether an argument must be passed by reference. On SHcompact, we - pretend arguments wider than 32-bits that would have been passed in - registers are passed by reference, so that an SHmedia trampoline - loads them into the full 64-bits registers. */ -#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM,MODE,TYPE,NAMED) \ - (targetm.calls.must_pass_in_stack ((MODE), (TYPE)) \ - || SHCOMPACT_BYREF ((CUM), (MODE), (TYPE), (NAMED))) - -#define SHCOMPACT_BYREF(CUM, MODE, TYPE, NAMED) \ - ((CUM).byref \ - = (TARGET_SHCOMPACT \ - && (CUM).arg_count[(int) SH_ARG_INT] < NPARM_REGS (SImode) \ - && (! (NAMED) || GET_SH_ARG_CLASS (MODE) == SH_ARG_INT \ - || (GET_SH_ARG_CLASS (MODE) == SH_ARG_FLOAT \ - && ((CUM).arg_count[(int) SH_ARG_FLOAT] \ - >= NPARM_REGS (SFmode)))) \ - && ((MODE) == BLKmode ? int_size_in_bytes (TYPE) \ - : GET_MODE_SIZE (MODE)) > 4 \ - && ! SHCOMPACT_FORCE_ON_STACK ((MODE), (TYPE)) \ - && ! SH5_WOULD_BE_PARTIAL_NREGS ((CUM), (MODE), \ - (TYPE), (NAMED))) \ - ? ((MODE) == BLKmode ? int_size_in_bytes (TYPE) \ - : GET_MODE_SIZE (MODE)) \ - : 0) - /* If an argument of size 5, 6 or 7 bytes is to be passed in a 64-bit register in SHcompact mode, it must be padded in the most significant end. This means that passing it by reference wouldn't diff --git a/gcc/config/sparc/sparc-protos.h b/gcc/config/sparc/sparc-protos.h index c28c318..bc4d6ac 100644 --- a/gcc/config/sparc/sparc-protos.h +++ b/gcc/config/sparc/sparc-protos.h @@ -32,8 +32,6 @@ extern struct rtx_def *function_arg (const CUMULATIVE_ARGS *, enum machine_mode, tree, int, int); extern int function_arg_partial_nregs (const CUMULATIVE_ARGS *, enum machine_mode, tree, int); -extern int function_arg_pass_by_reference (const CUMULATIVE_ARGS *, - enum machine_mode, tree, int); #ifdef RTX_CODE extern void init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree); extern void sparc_va_start (tree, rtx); diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 5c2188a..1dbd002 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -332,6 +332,8 @@ static rtx sparc_struct_value_rtx (tree, int); static bool sparc_return_in_memory (tree, tree); static bool sparc_strict_argument_naming (CUMULATIVE_ARGS *); static tree sparc_gimplify_va_arg (tree, tree, tree *, tree *); +static bool sparc_pass_by_reference (CUMULATIVE_ARGS *, + enum machine_mode, tree, bool); /* Option handling. */ @@ -436,6 +438,8 @@ enum processor_type sparc_cpu; #define TARGET_RETURN_IN_MEMORY sparc_return_in_memory #undef TARGET_MUST_PASS_IN_STACK #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size +#undef TARGET_PASS_BY_REFERENCE +#define TARGET_PASS_BY_REFERENCE sparc_pass_by_reference #undef TARGET_EXPAND_BUILTIN_SAVEREGS #define TARGET_EXPAND_BUILTIN_SAVEREGS sparc_builtin_saveregs @@ -5707,8 +5711,8 @@ function_arg_partial_nregs (const struct sparc_args *cum, } else { - /* We are guaranteed by function_arg_pass_by_reference that the size - of the argument is not greater than 16 bytes, so we only need to + /* We are guaranteed by pass_by_reference that the size of the + argument is not greater than 16 bytes, so we only need to return 1 if the argument is partially passed in registers. */ if (type && AGGREGATE_TYPE_P (type)) @@ -5739,16 +5743,16 @@ function_arg_partial_nregs (const struct sparc_args *cum, return 0; } -/* Handle the FUNCTION_ARG_PASS_BY_REFERENCE macro. +/* Return true if the argument should be passed by reference. !v9: The SPARC ABI stipulates passing struct arguments (of any size) and quad-precision floats by invisible reference. v9: Aggregates greater than 16 bytes are passed by reference. For Pascal, also pass arrays by reference. */ -int -function_arg_pass_by_reference (const struct sparc_args *cum ATTRIBUTE_UNUSED, - enum machine_mode mode, tree type, - int named ATTRIBUTE_UNUSED) +static bool +sparc_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, + enum machine_mode mode, tree type, + bool named ATTRIBUTE_UNUSED) { if (TARGET_ARCH32) { @@ -6003,7 +6007,7 @@ sparc_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p) bool indirect; tree ptrtype = build_pointer_type (type); - if (function_arg_pass_by_reference (0, TYPE_MODE (type), type, 0)) + if (pass_by_reference (NULL, TYPE_MODE (type), type, 0)) { indirect = true; size = rsize = UNITS_PER_WORD; diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index 18de27f8..4b07337 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -1742,15 +1742,6 @@ function_arg (& (CUM), (MODE), (TYPE), (NAMED), 1) #define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \ function_arg_partial_nregs (& (CUM), (MODE), (TYPE), (NAMED)) -/* A C expression that indicates when an argument must be passed by reference. - If nonzero for an argument, a copy of that argument is made in memory and a - pointer to the argument is passed instead of the argument itself. - The pointer is passed in whatever way is appropriate for passing a pointer - to that type. */ - -#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \ -function_arg_pass_by_reference (& (CUM), (MODE), (TYPE), (NAMED)) - /* 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, diff --git a/gcc/config/stormy16/stormy16.h b/gcc/config/stormy16/stormy16.h index ec87550..31eb43e 100644 --- a/gcc/config/stormy16/stormy16.h +++ b/gcc/config/stormy16/stormy16.h @@ -418,8 +418,6 @@ enum reg_class #define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0 -#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) 0 - /* For this platform, the value of CUMULATIVE_ARGS is the number of words of arguments that have been passed in registers so far. */ #define CUMULATIVE_ARGS int diff --git a/gcc/config/v850/v850.c b/gcc/config/v850/v850.c index 7221bd7..11311c3 100644 --- a/gcc/config/v850/v850.c +++ b/gcc/config/v850/v850.c @@ -67,6 +67,8 @@ static void v850_encode_section_info (tree, rtx, int); static bool v850_return_in_memory (tree, tree); static void v850_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode, tree, int *, int); +static bool v850_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, + tree, bool); /* Information about the various small memory areas. */ struct small_memory_info small_memory[ (int)SMALL_MEMORY_max ] = @@ -129,6 +131,9 @@ static int v850_interrupt_p = FALSE; #undef TARGET_RETURN_IN_MEMORY #define TARGET_RETURN_IN_MEMORY v850_return_in_memory +#undef TARGET_PASS_BY_REFERENCE +#define TARGET_PASS_BY_REFERENCE v850_pass_by_reference + #undef TARGET_SETUP_INCOMING_VARARGS #define TARGET_SETUP_INCOMING_VARARGS v850_setup_incoming_varargs @@ -178,6 +183,20 @@ override_options (void) } +static bool +v850_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, + enum machine_mode mode, tree type, + bool named ATTRIBUTE_UNUSED) +{ + unsigned HOST_WIDE_INT size; + + if (type) + size = int_size_in_bytes (type); + else + size = GET_MODE_SIZE (mode); + + return size > 8; +} /* Return an RTX to represent where a value with mode MODE will be returned from a function. If the result is 0, the argument is pushed. */ diff --git a/gcc/config/v850/v850.h b/gcc/config/v850/v850.h index 9a34a50..5643a9d 100644 --- a/gcc/config/v850/v850.h +++ b/gcc/config/v850/v850.h @@ -773,11 +773,7 @@ struct cum_arg { int nbytes; int anonymous_args; }; space allocated by the caller. */ #define OUTGOING_REG_PARM_STACK_SPACE -#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \ - ((TYPE) && (unsigned HOST_WIDE_INT) int_size_in_bytes (TYPE) > 8) - -#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) \ - FUNCTION_ARG_PASS_BY_REFERENCE (CUM, MODE, TYPE, NAMED) +#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) 1 /* 1 if N is a possible register number for function argument passing. */ diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 28dfe7d..72f0fb4 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -3722,22 +3722,17 @@ register to be used by the caller for this argument; likewise @code{FUNCTION_INCOMING_ARG}, for the called function. @end defmac -@defmac FUNCTION_ARG_PASS_BY_REFERENCE (@var{cum}, @var{mode}, @var{type}, @var{named}) -A C expression that indicates when an argument must be passed by reference. -If nonzero for an argument, a copy of that argument is made in memory and a +@deftypefn {Target Hook} bool TARGET_PASS_BY_REFERENCE (CUMULATIVE_ARGS *@var{cum}, enum machine_mode @var{mode}, tree @var{type}, bool @var{named}) +This target hook should return @code{true} if an argument at the +position indicated by @var{cum} should be passed by reference. This +predicate is queried after target independent reasons for being +passed by reference, such as @code{TREE_ADDRESSABLE (type)}. + +If the hook returns true, a copy of that argument is made in memory and a pointer to the argument is passed instead of the argument itself. The pointer is passed in whatever way is appropriate for passing a pointer to that type. - -On machines where @code{REG_PARM_STACK_SPACE} is not defined, a suitable -definition of this macro might be -@smallexample -#define FUNCTION_ARG_PASS_BY_REFERENCE\ -(CUM, MODE, TYPE, NAMED) \ - targetm.calls.must_pass_in_stack (MODE, TYPE) -@end smallexample -@c this is *still* too long. --mew 5feb93 -@end defmac +@end deftypefn @defmac FUNCTION_ARG_CALLEE_COPIES (@var{cum}, @var{mode}, @var{type}, @var{named}) If defined, a C expression that indicates when it is the called function's diff --git a/gcc/function.c b/gcc/function.c index 08b2e43..2d6a976 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -2029,9 +2029,8 @@ use_register_for_decl (tree decl) /* Return true if TYPE should be passed by invisible reference. */ bool -pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, - enum machine_mode mode ATTRIBUTE_UNUSED, - tree type, bool named_arg ATTRIBUTE_UNUSED) +pass_by_reference (CUMULATIVE_ARGS *ca, enum machine_mode mode, + tree type, bool named_arg) { if (type) { @@ -2046,11 +2045,7 @@ pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, return true; } -#ifdef FUNCTION_ARG_PASS_BY_REFERENCE - return FUNCTION_ARG_PASS_BY_REFERENCE (*ca, mode, type, named_arg); -#else - return false; -#endif + return targetm.calls.pass_by_reference (ca, mode, type, named_arg); } /* Structures to communicate between the subroutines of assign_parms. diff --git a/gcc/system.h b/gcc/system.h index ce8f3ec..26dccf4 100644 --- a/gcc/system.h +++ b/gcc/system.h @@ -585,7 +585,7 @@ extern int snprintf (char *, size_t, const char *, ...); SETUP_INCOMING_VARARGS EXPAND_BUILTIN_SAVEREGS \ DEFAULT_SHORT_ENUMS SPLIT_COMPLEX_ARGS MD_ASM_CLOBBERS \ HANDLE_PRAGMA_REDEFINE_EXTNAME HANDLE_PRAGMA_EXTERN_PREFIX \ - MUST_PASS_IN_STACK + MUST_PASS_IN_STACK FUNCTION_ARG_PASS_BY_REFERENCE /* Other obsolete target macros, or macros that used to be in target headers and were not used, and may be obsolete or may never have diff --git a/gcc/target-def.h b/gcc/target-def.h index 329e44b..5671b1b 100644 --- a/gcc/target-def.h +++ b/gcc/target-def.h @@ -362,6 +362,8 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define TARGET_GIMPLIFY_VA_ARG_EXPR std_gimplify_va_arg_expr #endif +#define TARGET_PASS_BY_REFERENCE hook_pass_by_reference_false + #define TARGET_LATE_RTL_PROLOGUE_EPILOGUE false #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size_or_pad @@ -373,6 +375,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. TARGET_STRUCT_VALUE_RTX, \ TARGET_RETURN_IN_MEMORY, \ TARGET_RETURN_IN_MSB, \ + TARGET_PASS_BY_REFERENCE, \ TARGET_EXPAND_BUILTIN_SAVEREGS, \ TARGET_SETUP_INCOMING_VARARGS, \ TARGET_STRICT_ARGUMENT_NAMING, \ diff --git a/gcc/target.h b/gcc/target.h index 2c38dc5..f4f4984 100644 --- a/gcc/target.h +++ b/gcc/target.h @@ -448,6 +448,13 @@ struct gcc_target rtx (*struct_value_rtx) (tree fndecl, int incoming); bool (*return_in_memory) (tree type, tree fndecl); bool (*return_in_msb) (tree type); + + /* Return true if a parameter must be passed by reference. TYPE may + be null if this is a libcall. CA may be null if this query is + from __builtin_va_arg. */ + bool (*pass_by_reference) (CUMULATIVE_ARGS *ca, enum machine_mode mode, + tree type, bool named_arg); + rtx (*expand_builtin_saveregs) (void); /* Returns pretend_argument_size. */ void (*setup_incoming_varargs) (CUMULATIVE_ARGS *ca, enum machine_mode mode, diff --git a/gcc/targhooks.c b/gcc/targhooks.c index a2745c4..be4d144 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -168,3 +168,25 @@ default_cxx_get_cookie_size (tree type) return cookie_size; } + +/* This version of the TARGET_PASS_BY_REFERENCE hook adds no conditions + beyond those mandated by generic code. */ + +bool +hook_pass_by_reference_false (CUMULATIVE_ARGS *c ATTRIBUTE_UNUSED, + enum machine_mode mode ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED, + bool named_arg ATTRIBUTE_UNUSED) +{ + return false; +} + +/* Return true if a parameter must be passed by reference. This version + of the TARGET_PASS_BY_REFERENCE hook uses just MUST_PASS_IN_STACK. */ + +bool +hook_pass_by_reference_must_pass_in_stack (CUMULATIVE_ARGS *c ATTRIBUTE_UNUSED, + enum machine_mode mode ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED, + bool named_arg ATTRIBUTE_UNUSED) +{ + return targetm.calls.must_pass_in_stack (mode, type); +} diff --git a/gcc/targhooks.h b/gcc/targhooks.h index fba17f8..6d3295c 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -34,3 +34,8 @@ extern bool default_pretend_outgoing_varargs_named (CUMULATIVE_ARGS *); extern bool hook_bool_CUMULATIVE_ARGS_true (CUMULATIVE_ARGS *); extern tree default_cxx_guard_type (void); extern tree default_cxx_get_cookie_size (tree); + +extern bool hook_pass_by_reference_false + (CUMULATIVE_ARGS *, enum machine_mode mode, tree, bool); +extern bool hook_pass_by_reference_must_pass_in_stack + (CUMULATIVE_ARGS *, enum machine_mode mode, tree, bool); |