aboutsummaryrefslogtreecommitdiff
path: root/gcc/calls.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2004-03-12 02:03:32 -0800
committerRichard Henderson <rth@gcc.gnu.org>2004-03-12 02:03:32 -0800
commit42ba51300418d586a41637d9c1fc72c6078b7c6d (patch)
treebdd3000f3e6489ec11b58de31921ac902908031e /gcc/calls.c
parentac011d28bb63763829fd3bec7792fe13d58cfac7 (diff)
downloadgcc-42ba51300418d586a41637d9c1fc72c6078b7c6d.zip
gcc-42ba51300418d586a41637d9c1fc72c6078b7c6d.tar.gz
gcc-42ba51300418d586a41637d9c1fc72c6078b7c6d.tar.bz2
re PR target/14547 (Passing _Complex long double does not follow the ABI)
PR target/14547 * target.h (struct gcc_target): Move calls substructure before booleans. Add split_complex_arg. * function.c (assign_parms, split_complex_args): Use it. * calls.c (expand_call): Likewise. (split_complex_values): Likewise. Check for splittable types before allocating memory. (split_complex_types): Likewise. * system.h (SPLIT_COMPLEX_ARGS): Poison. * expr.h (SPLIT_COMPLEX_ARGS): Remove. * target-def.h (TARGET_SPLIT_COMPLEX_ARG): New. * config/alpha/alpha.c (alpha_split_complex_arg): New. (TARGET_SPLIT_COMPLEX_ARG): New. * config/alpha/alpha.h (SPLIT_COMPLEX_ARGS): Remove. * config/rs6000/rs6000.c (TARGET_SPLIT_COMPLEX_ARG): New. (rs6000_override_options): Zap it for non-AIX. (rs6000_function_value): Use targetm.calls.split_complex_arg. * config/rs6000/rs6000.h (SPLIT_COMPLEX_ARGS): Remove. * config/xtensa/xtensa.c (TARGET_SPLIT_COMPLEX_ARG): New. * config/xtensa/xtensa.h (SPLIT_COMPLEX_ARGS): Remove. * doc/tm.texi (TARGET_SPLIT_COMPLEX_ARG): Modify from old SPLIT_COMPLEX_ARGS entry. From-SVN: r79376
Diffstat (limited to 'gcc/calls.c')
-rw-r--r--gcc/calls.c30
1 files changed, 27 insertions, 3 deletions
diff --git a/gcc/calls.c b/gcc/calls.c
index 29c06aa..e58bd05 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -2347,7 +2347,7 @@ expand_call (tree exp, rtx target, int ignore)
/* Munge the tree to split complex arguments into their imaginary
and real parts. */
- if (SPLIT_COMPLEX_ARGS)
+ if (targetm.calls.split_complex_arg)
{
type_arg_types = split_complex_types (TYPE_ARG_TYPES (funtype));
actparms = split_complex_values (actparms);
@@ -3557,6 +3557,17 @@ split_complex_values (tree values)
{
tree p;
+ /* Before allocating memory, check for the common case of no complex. */
+ for (p = values; p; p = TREE_CHAIN (p))
+ {
+ tree type = TREE_TYPE (TREE_VALUE (p));
+ if (type && TREE_CODE (type) == COMPLEX_TYPE
+ && targetm.calls.split_complex_arg (type))
+ goto found;
+ }
+ return values;
+
+ found:
values = copy_list (values);
for (p = values; p; p = TREE_CHAIN (p))
@@ -3568,7 +3579,8 @@ split_complex_values (tree values)
if (!complex_type)
continue;
- if (TREE_CODE (complex_type) == COMPLEX_TYPE)
+ if (TREE_CODE (complex_type) == COMPLEX_TYPE
+ && targetm.calls.split_complex_arg (complex_type))
{
tree subtype;
tree real, imag, next;
@@ -3599,13 +3611,25 @@ split_complex_types (tree types)
{
tree p;
+ /* Before allocating memory, check for the common case of no complex. */
+ for (p = types; p; p = TREE_CHAIN (p))
+ {
+ tree type = TREE_VALUE (p);
+ if (TREE_CODE (type) == COMPLEX_TYPE
+ && targetm.calls.split_complex_arg (type))
+ goto found;
+ }
+ return types;
+
+ found:
types = copy_list (types);
for (p = types; p; p = TREE_CHAIN (p))
{
tree complex_type = TREE_VALUE (p);
- if (TREE_CODE (complex_type) == COMPLEX_TYPE)
+ if (TREE_CODE (complex_type) == COMPLEX_TYPE
+ && targetm.calls.split_complex_arg (complex_type))
{
tree next, imag;