aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUros Bizjak <ubizjak@gmail.com>2019-01-16 16:33:34 +0100
committerUros Bizjak <uros@gcc.gnu.org>2019-01-16 16:33:34 +0100
commit647c5e3ea774f96c7f84b3ebacf1cb180aa2fbc5 (patch)
tree06484c4e4da15fc483b687690a4a165b49acaf3d
parent638b5fcaa0dd5b3ee5f3fd430f4c27d9a847fa07 (diff)
downloadgcc-647c5e3ea774f96c7f84b3ebacf1cb180aa2fbc5.zip
gcc-647c5e3ea774f96c7f84b3ebacf1cb180aa2fbc5.tar.gz
gcc-647c5e3ea774f96c7f84b3ebacf1cb180aa2fbc5.tar.bz2
alpha.c (alpha_gimplify_va_arg): Handle split indirect COMPLEX_TYPE arguments.
* config/alpha/alpha.c (alpha_gimplify_va_arg): Handle split indirect COMPLEX_TYPE arguments. From-SVN: r267973
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/alpha/alpha.c34
2 files changed, 38 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7898357..c0a7e23 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2019-01-16 Uroš Bizjak <ubizjak@gmail.com>
+
+ * config/alpha/alpha.c (alpha_gimplify_va_arg):
+ Handle split indirect COMPLEX_TYPE arguments.
+
2019-01-16 Richard Earnshaw <rearnsha@arm.com>
PR target/86891
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index ce45c54..f0e8124 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -6378,8 +6378,40 @@ alpha_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
offset = get_initialized_tmp_var (t, pre_p, NULL);
indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
+
if (indirect)
- type = build_pointer_type_for_mode (type, ptr_mode, true);
+ {
+ if (TREE_CODE (type) == COMPLEX_TYPE
+ && targetm.calls.split_complex_arg (type))
+ {
+ tree real_part, imag_part, real_temp;
+
+ tree ptr_type = build_pointer_type_for_mode (TREE_TYPE (type),
+ ptr_mode, true);
+
+ real_part = alpha_gimplify_va_arg_1 (ptr_type, base,
+ offset, pre_p);
+ real_part = build_va_arg_indirect_ref (real_part);
+
+ /* Copy the value into a new temporary, lest the formal temporary
+ be reused out from under us. */
+ real_temp = get_initialized_tmp_var (real_part, pre_p, NULL);
+
+ imag_part = alpha_gimplify_va_arg_1 (ptr_type, base,
+ offset, pre_p);
+ imag_part = build_va_arg_indirect_ref (imag_part);
+
+ r = build2 (COMPLEX_EXPR, type, real_temp, imag_part);
+
+ /* Stuff the offset temporary back into its field. */
+ gimplify_assign (unshare_expr (offset_field),
+ fold_convert (TREE_TYPE (offset_field), offset),
+ pre_p);
+ return r;
+ }
+ else
+ type = build_pointer_type_for_mode (type, ptr_mode, true);
+ }
/* Find the value. Note that this will be a stable indirection, or
a composite of stable indirections in the case of complex. */