* 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.
From-SVN: r84672
+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>
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
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.
#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
#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. */
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);
\f
/* Initialize the GCC target structure. */
#undef TARGET_ASM_ALIGNED_HI_OP
#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
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;
+}
+
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
/* ??? 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.
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
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);
#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
/* 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;
}
&& (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.
#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. */
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
#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;
}
}
+/* 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,
#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))
/* 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)
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)
&& 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%),
((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 \
#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
#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
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);
#include <ctype.h>
#include "target.h"
#include "target-def.h"
+#include "targhooks.h"
#include "integrate.h"
#ifndef FRV_INLINE
#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
}
\f
-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
/* 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
#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);
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);
#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
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;
#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)
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 */
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 *);
#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
/* 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;
}
#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. */
#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
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);
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
#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
return gen_rtx_REG (mode, reg);
}
\f
-/* 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;
#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
#endif /* HAVE_MACHINE_MODES */
-#ifdef TREE_CODE
-extern int m32r_pass_by_reference (tree);
-#endif /* TREE_CODE */
#endif /* RTX_CODE */
#undef Mmode
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);
\f
/* Initialize the GCC target structure. */
#undef TARGET_ATTRIBUTE_TABLE
#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;
\f
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);
}
\f
/* Comparisons. */
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
#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.) */
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);
/* 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
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,
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. */
#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
#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.
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);
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,
#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;
\f
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);
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)
{
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
? 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)
(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
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);
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. */
#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;
/* 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. */
#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;
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);
\f
/* Initialize the GCC target structure. */
#undef TARGET_ASM_ALIGNED_HI_OP
#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
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. */
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
function_arg_partial_nregs (&CUM, MODE, TYPE, NAMED)
\f
-#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).
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. */
#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
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)
{
: 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
\f
extern GTY(()) rtx hppa_compare_op0;
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);
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);
#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
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))
#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
#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
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"
#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
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)
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;
}
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))
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)
{
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);
#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,
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);
\f
/* Initialize the GCC target structure. */
#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
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.
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
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
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);
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);
\f
/* Option handling. */
#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
}
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))
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)
{
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;
#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,
#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
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 ] =
#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
}
\f
+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. */
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. */
@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
/* 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)
{
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.
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
#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
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, \
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,
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);
+}
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);