aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorGeoffrey Keating <geoffk@redhat.com>2000-11-09 17:38:20 +0000
committerGeoffrey Keating <geoffk@gcc.gnu.org>2000-11-09 17:38:20 +0000
commit9a0662b4d5ca89808c149d69d271068ae0e54560 (patch)
tree591da3e5a035add693d8ea50a5fdceea98190cf5 /gcc
parent1caa7aba31c9ff1c1b40eaef4837a55ccf3ff298 (diff)
downloadgcc-9a0662b4d5ca89808c149d69d271068ae0e54560.zip
gcc-9a0662b4d5ca89808c149d69d271068ae0e54560.tar.gz
gcc-9a0662b4d5ca89808c149d69d271068ae0e54560.tar.bz2
sparc.c (sparc_va_arg): When the required alignment is more than that provided, copy to a temporary.
* config/sparc/sparc.c (sparc_va_arg): When the required alignment is more than that provided, copy to a temporary. From-SVN: r37344
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/sparc/sparc.c37
2 files changed, 36 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e63ecbc..1d81a64 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2000-11-08 Geoffrey Keating <geoffk@redhat.com>
+
+ * config/sparc/sparc.c (sparc_va_arg): When the required alignment
+ is more than that provided, copy to a temporary.
+
2000-11-09 Alexandre Oliva <aoliva@redhat.com>
* mklibgcc.in (EXTRA_MULTILIB_PARTS): Prevent `make' from
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 8c96a8a..85707e4 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -4793,12 +4793,6 @@ sparc_va_arg (valist, type)
indirect = 1;
size = rsize = UNITS_PER_WORD;
}
- else
- {
- /* ??? The old va-sparc.h implementation, for 8 byte objects
- copied stuff to a temporary -- I don't see that that
- provides any more alignment than the stack slot did. */
- }
}
incr = valist;
@@ -4825,6 +4819,37 @@ sparc_va_arg (valist, type)
addr_rtx = expand_expr (addr, NULL, Pmode, EXPAND_NORMAL);
+ /* If the address isn't aligned properly for the type,
+ we may need to copy to a temporary.
+ FIXME: This is inefficient. Usually we can do this
+ in registers. */
+ if (align == 0
+ && TYPE_ALIGN (type) > BITS_PER_WORD
+ && !indirect)
+ {
+ /* FIXME: We really need to specify that the temporary is live
+ for the whole function because expand_builtin_va_arg wants
+ the alias set to be get_varargs_alias_set (), but in this
+ case the alias set is that for TYPE and if the memory gets
+ reused it will be reused with alias set TYPE. */
+ rtx tmp = assign_temp (type, 0, 1, 0);
+ rtx dest_addr;
+
+ addr_rtx = force_reg (Pmode, addr_rtx);
+ addr_rtx = gen_rtx_MEM (BLKmode, addr_rtx);
+ MEM_ALIAS_SET (addr_rtx) = get_varargs_alias_set ();
+ tmp = shallow_copy_rtx (tmp);
+ PUT_MODE (tmp, BLKmode);
+ MEM_ALIAS_SET (tmp) = 0;
+
+ dest_addr = emit_block_move (tmp, addr_rtx, GEN_INT (rsize),
+ BITS_PER_WORD);
+ if (dest_addr != NULL_RTX)
+ addr_rtx = dest_addr;
+ else
+ addr_rtx = XCEXP (tmp, 0, MEM);
+ }
+
if (indirect)
{
addr_rtx = force_reg (Pmode, addr_rtx);