diff options
author | Geoffrey Keating <geoffk@redhat.com> | 2000-11-09 17:38:20 +0000 |
---|---|---|
committer | Geoffrey Keating <geoffk@gcc.gnu.org> | 2000-11-09 17:38:20 +0000 |
commit | 9a0662b4d5ca89808c149d69d271068ae0e54560 (patch) | |
tree | 591da3e5a035add693d8ea50a5fdceea98190cf5 /gcc | |
parent | 1caa7aba31c9ff1c1b40eaef4837a55ccf3ff298 (diff) | |
download | gcc-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/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.c | 37 |
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); |