rs6000: Small varargs for BE SVR4 (PR61729, PR77850)
authorSegher Boessenkool <segher@kernel.crashing.org>
Sat, 21 Jan 2017 03:11:49 +0000 (04:11 +0100)
committerSegher Boessenkool <segher@gcc.gnu.org>
Sat, 21 Jan 2017 03:11:49 +0000 (04:11 +0100)
The varargs code for SVR4 puts all (integer) arguments in 4-byte slots.
When it then reads an item from there as something not a multiple of 4
bytes, it needs to adjust the address if big endian.  We didn't yet do
that.

This fixes the g++.dg/abi/scoped1.C, gcc.dg/compat/scalar-by-value-4,
and gcc.dg/compat/scalar-return-4 testcases.

PR target/61729
PR target/77850
* config/rs6000/rs6000.c (rs6000_gimplify_va_arg): Adjust address to
read from, for big endian.

From-SVN: r244740

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

index 10a6978125128bdf4985bceaa7deb5d5fd11f69a..254e73949d68465b14bee04c78df2ddd4211e4da 100644 (file)
@@ -1,3 +1,10 @@
+2017-01-20  Segher Boessenkool  <segher@kernel.crashing.org>
+
+       PR target/61729
+       PR target/77850
+       * config/rs6000/rs6000.c (rs6000_gimplify_va_arg): Adjust address to
+       read from, for big endian.
+
 2017-01-20  Jiong Wang  <jiong.wang@arm.com>
 
        * config/aarch64/aarch64-builtins.c (aarch64_init_builtins): Register
index be7e94770b5117053c030b75dc74cbef57b21422..124f562185d2c6d3392c4913013ae9de324629f2 100644 (file)
@@ -13684,6 +13684,7 @@ rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
 
   size = int_size_in_bytes (type);
   rsize = (size + 3) / 4;
+  int pad = 4 * rsize - size;
   align = 1;
 
   machine_mode mode = TYPE_MODE (type);
@@ -13765,6 +13766,10 @@ rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
          && mode == SDmode)
        t = fold_build_pointer_plus_hwi (t, size);
 
+      /* Args are passed right-aligned.  */
+      if (BYTES_BIG_ENDIAN)
+       t = fold_build_pointer_plus_hwi (t, pad);
+
       gimplify_assign (addr, t, pre_p);
 
       gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
@@ -13790,6 +13795,11 @@ rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
       t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
                  build_int_cst (TREE_TYPE (t), -align));
     }
+
+  /* Args are passed right-aligned.  */
+  if (BYTES_BIG_ENDIAN)
+    t = fold_build_pointer_plus_hwi (t, pad);
+
   gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
 
   gimplify_assign (unshare_expr (addr), t, pre_p);