]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
rs6000.c (rs6000_gimplify_va_arg): If STRICT_ALIGNMENT and the type is more aligned...
authorJoseph Myers <joseph@codesourcery.com>
Wed, 29 Nov 2006 12:49:06 +0000 (12:49 +0000)
committerJoseph Myers <jsm28@gcc.gnu.org>
Wed, 29 Nov 2006 12:49:06 +0000 (12:49 +0000)
* config/rs6000/rs6000.c (rs6000_gimplify_va_arg): If
STRICT_ALIGNMENT and the type is more aligned than the saved
registers, copy via a temporary.

From-SVN: r119307

gcc/ChangeLog
gcc/config/rs6000/rs6000.c

index c838be7693a6488d92fc3d9a18d19d09804a7686..0c02f8bede58b2b0b3a104c51fb198170db2dd29 100644 (file)
@@ -1,3 +1,9 @@
+2006-11-29  Joseph Myers  <joseph@codesourcery.com>
+
+       * config/rs6000/rs6000.c (rs6000_gimplify_va_arg): If
+       STRICT_ALIGNMENT and the type is more aligned than the saved
+       registers, copy via a temporary.
+
 2006-11-28  Andrew Pinski  <pinskia@gmail.com>
 
        PR tree-opt/29984
index d52a75951c3ff75dcaa9608e81b217a3a8763b10..675af68fe9a37f08e832d0d2eb4b8971fea1f80f 100644 (file)
@@ -6222,6 +6222,27 @@ rs6000_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
       append_to_statement_list (t, pre_p);
     }
 
+  if (STRICT_ALIGNMENT
+      && (TYPE_ALIGN (type)
+         > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
+    {
+      /* The value (of type complex double, for example) may not be
+        aligned in memory in the saved registers, so copy via a
+        temporary.  (This is the same code as used for SPARC.)  */
+      tree tmp = create_tmp_var (type, "va_arg_tmp");
+      tree dest_addr = build_fold_addr_expr (tmp);
+
+      tree copy = build_function_call_expr
+       (implicit_built_in_decls[BUILT_IN_MEMCPY],
+        tree_cons (NULL_TREE, dest_addr,
+                   tree_cons (NULL_TREE, addr,
+                              tree_cons (NULL_TREE, size_int (rsize * 4),
+                                         NULL_TREE))));
+
+      gimplify_and_add (copy, pre_p);
+      addr = dest_addr;
+    }
+
   addr = fold_convert (ptrtype, addr);
   return build_va_arg_indirect_ref (addr);
 }