alpha.c (alpha_gimplify_va_arg): Handle split indirect COMPLEX_TYPE arguments.
authorUros Bizjak <ubizjak@gmail.com>
Wed, 16 Jan 2019 15:33:34 +0000 (16:33 +0100)
committerUros Bizjak <uros@gcc.gnu.org>
Wed, 16 Jan 2019 15:33:34 +0000 (16:33 +0100)
* config/alpha/alpha.c (alpha_gimplify_va_arg):
Handle split indirect COMPLEX_TYPE arguments.

From-SVN: r267973

gcc/ChangeLog
gcc/config/alpha/alpha.c

index 78983572b236699225b0986dca16789001651090..c0a7e237b1ff62053956b8a67cbabe8b99dc9ea7 100644 (file)
@@ -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
index ce45c54eeb7afa6bb79ad1e74c486d96764ff209..f0e8124797f3a957efc74019e9555c7cf5a1304b 100644 (file)
@@ -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.  */