]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
alpha.c (alpha_gimplify_va_arg): Handle split indirect COMPLEX_TYPE arguments.
authorUros Bizjak <uros@gcc.gnu.org>
Fri, 18 Jan 2019 16:46:47 +0000 (17:46 +0100)
committerUros Bizjak <uros@gcc.gnu.org>
Fri, 18 Jan 2019 16:46:47 +0000 (17:46 +0100)
* config/alpha/alpha.c (alpha_gimplify_va_arg):
Handle split indirect COMPLEX_TYPE arguments.

From-SVN: r268081

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

index 8dd7731098e172f1e8f2853005f4d4bd4013c5cb..9dc3762f8b5756feeb04e204e091c32047fb58d8 100644 (file)
@@ -1,3 +1,8 @@
+2019-01-18  Uroš Bizjak  <ubizjak@gmail.com>
+
+       * config/alpha/alpha.c (alpha_gimplify_va_arg):
+       Handle split indirect COMPLEX_TYPE arguments.
+
 2019-01-16  Martin Jambor  <mjambor@suse.cz>
 
        Backported from mainline
@@ -8,7 +13,7 @@
        we check pointers against pointers.
 
 2019-01-09  Eric Botcazou  <ebotcazou@adacore.com>
-            James Clarke  <jrtc27@jrtc27.com>
+           James Clarke  <jrtc27@jrtc27.com>
 
        PR target/84010
        * config/sparc/sparc.c (sparc_legitimize_tls_address): Only use Pmode
index 75a2af1e3de31e78916cd96e667349372c03ec7e..8355031bff14a569b83ecd77530244bd64aee1f1 100644 (file)
@@ -6357,8 +6357,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.  */