summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2004-07-14 06:24:27 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2004-07-14 06:24:27 +0000
commitb981d932962c8e9f6744359ef47d255a2c6b3be8 (patch)
tree0831bbea139cb77f60030d22ed84f1ab3e43068a /gcc
parent1344a976e60432908706853a9e01e0b0e1db27c5 (diff)
downloadgcc-b981d932962c8e9f6744359ef47d255a2c6b3be8.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@84672 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog109
-rw-r--r--gcc/config/alpha/alpha.c15
-rw-r--r--gcc/config/alpha/alpha.h9
-rw-r--r--gcc/config/arc/arc.c27
-rw-r--r--gcc/config/arc/arc.h14
-rw-r--r--gcc/config/arm/arm-protos.h2
-rw-r--r--gcc/config/arm/arm.c12
-rw-r--r--gcc/config/arm/arm.h8
-rw-r--r--gcc/config/c4x/c4x.h4
-rw-r--r--gcc/config/cris/cris.c19
-rw-r--r--gcc/config/cris/cris.h25
-rw-r--r--gcc/config/fr30/fr30.c3
-rw-r--r--gcc/config/fr30/fr30.h3
-rw-r--r--gcc/config/frv/frv-protos.h4
-rw-r--r--gcc/config/frv/frv.c12
-rw-r--r--gcc/config/frv/frv.h3
-rw-r--r--gcc/config/i386/i386-protos.h2
-rw-r--r--gcc/config/i386/i386.c12
-rw-r--r--gcc/config/i386/i386.h9
-rw-r--r--gcc/config/ia64/ia64-protos.h2
-rw-r--r--gcc/config/ia64/ia64.c12
-rw-r--r--gcc/config/ia64/ia64.h9
-rw-r--r--gcc/config/ip2k/ip2k.h3
-rw-r--r--gcc/config/iq2000/iq2000-protos.h1
-rw-r--r--gcc/config/iq2000/iq2000.c14
-rw-r--r--gcc/config/iq2000/iq2000.h6
-rw-r--r--gcc/config/m32r/m32r-protos.h3
-rw-r--r--gcc/config/m32r/m32r.c26
-rw-r--r--gcc/config/m32r/m32r.h9
-rw-r--r--gcc/config/m68hc11/m68hc11-protos.h4
-rw-r--r--gcc/config/m68hc11/m68hc11.c18
-rw-r--r--gcc/config/m68hc11/m68hc11.h14
-rw-r--r--gcc/config/mcore/mcore.c2
-rw-r--r--gcc/config/mcore/mcore.h8
-rw-r--r--gcc/config/mips/mips-protos.h2
-rw-r--r--gcc/config/mips/mips.c24
-rw-r--r--gcc/config/mips/mips.h6
-rw-r--r--gcc/config/mmix/mmix-protos.h2
-rw-r--r--gcc/config/mmix/mmix.c14
-rw-r--r--gcc/config/mmix/mmix.h13
-rw-r--r--gcc/config/mn10300/mn10300.c22
-rw-r--r--gcc/config/mn10300/mn10300.h6
-rw-r--r--gcc/config/pa/pa.c36
-rw-r--r--gcc/config/pa/pa.h22
-rw-r--r--gcc/config/rs6000/rs6000-protos.h3
-rw-r--r--gcc/config/rs6000/rs6000.c12
-rw-r--r--gcc/config/rs6000/rs6000.h9
-rw-r--r--gcc/config/s390/s390-protos.h1
-rw-r--r--gcc/config/s390/s390.c23
-rw-r--r--gcc/config/s390/s390.h3
-rw-r--r--gcc/config/sh/sh.c49
-rw-r--r--gcc/config/sh/sh.h29
-rw-r--r--gcc/config/sparc/sparc-protos.h2
-rw-r--r--gcc/config/sparc/sparc.c20
-rw-r--r--gcc/config/sparc/sparc.h9
-rw-r--r--gcc/config/stormy16/stormy16.h2
-rw-r--r--gcc/config/v850/v850.c19
-rw-r--r--gcc/config/v850/v850.h6
-rw-r--r--gcc/doc/tm.texi21
-rw-r--r--gcc/function.c11
-rw-r--r--gcc/system.h2
-rw-r--r--gcc/target-def.h3
-rw-r--r--gcc/target.h7
-rw-r--r--gcc/targhooks.c22
-rw-r--r--gcc/targhooks.h5
65 files changed, 463 insertions, 365 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d0bfe32dbd2..cdf3aaec381 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 422d6c6a44c..8ed7b78d72c 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 e142e5e177a..b77a9bce290 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 d648028030b..cbc0efaca69 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 55cb8f4c0d9..d615364069d 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 3124d4f1a1f..ce3ff6aff69 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 8da8881afe6..a94b82bbec5 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 a66ec4d6289..ad006c555b0 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 823a6085da6..ff2e634b14f 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 b28896f549a..50f5e59bf78 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 252992b0376..a308412e7ac 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 98e45c43939..55d1154bc4c 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 b8bec8e4fc4..201690a4242 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 a7a8ee667f6..a63669b36cc 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 9935fef4895..5e4a12f5c4a 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 493ebc76a4a..838ca176114 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 7fb122dc6d8..aae3c7acb0f 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 9b6e30e8fd8..0349979fb14 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 33cd861819f..c85c8892893 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 50456a61e5e..e59dff5afbe 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 51e410eb2c8..7e19f6ba043 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 0e649e3442e..28fe2d54c9f 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 c24c49370f5..aecc8cdf56b 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 60c34bc37ab..c0eae3b01f1 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 4da87120257..0e2f7c146f6 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 d4e27c1aae3..f6f381089e2 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 89a4cbe28f9..f01203334e7 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 6c4a5dd5918..c46bff52ae4 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 6300967afc0..2f38e0a725d 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 dbd7d87f7f4..af8c35b8a1c 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 321e1ab1633..ba58e8b9a10 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 378454ca658..9732219c298 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 7bad189422e..c41ce8f41d5 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 b026c1416b9..b800a932659 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 f38809eaf68..820d75f9cc0 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 3e93a015a94..02231f39171 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 35177804812..a4c7be938f1 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 e10e65bb0ea..c2f02ccb772 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 4e1731bc29e..ae69548a222 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 5d68fa716c5..6894337b2ff 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 b5686c404ed..a67a75d3225 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 e831e28035a..e77f9d26e44 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 723fbec2ea5..7f4ba45c2c6 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 2d60573de58..0ceedc68348 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 50f47664084..c096808b337 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 ea81e8ba734..1013f971072 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 17df6c082eb..fdf3d4afef9 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 6c9d7e7677e..447edff9b21 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 58424a41315..4d4aef8c9c8 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 85168b4d99a..d804599a3f7 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 4003f1676d6..b3b2ab381b5 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 a76bda1238f..e38361f186a 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 c28c31817ae..bc4d6ac5c28 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 5c2188a623e..1dbd0020f8a 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 18de27f86ab..4b073377869 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 ec87550029f..31eb43e2b29 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 7221bd737db..11311c3fbf2 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 9a34a50a5af..5643a9df749 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 28dfe7d9e75..72f0fb4db25 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 08b2e439bbc..2d6a976e892 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 ce8f3ecd825..26dccf4c70a 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 329e44b9b97..5671b1b43fe 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 2c38dc5dcc6..f4f4984b7a1 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 a2745c4cbcd..be4d1446e06 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 fba17f82001..6d3295c2297 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);