From 80b40b87845bf2293f2bfdd215bbf758db5ceff4 Mon Sep 17 00:00:00 2001 From: Segher Boessenkool Date: Sat, 21 Jan 2017 04:11:49 +0100 Subject: [PATCH] rs6000: Small varargs for BE SVR4 (PR61729, PR77850) 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 | 7 +++++++ gcc/config/rs6000/rs6000.c | 10 ++++++++++ 2 files changed, 17 insertions(+) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 10a69781251..254e73949d6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2017-01-20 Segher Boessenkool + + 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 * config/aarch64/aarch64-builtins.c (aarch64_init_builtins): Register diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index be7e94770b5..124f562185d 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -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); -- 2.30.2