diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-09-05 00:16:18 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-09-05 00:16:18 +0000 |
commit | a959290029aade6de4bf3866d0cca137067f663e (patch) | |
tree | 37b6e2cabd6f1672b8525e0ccc80e082bc7a76b2 /gcc | |
parent | 9c7abf83626d9c0437f641d8c2b484463840794e (diff) | |
download | gcc-a959290029aade6de4bf3866d0cca137067f663e.tar.gz |
* sparc.h (EXPAND_BUILTIN_VA_START): Define.
(EXPAND_BUILTIN_VA_ARG): Define.
* sparc.c (sparc_va_start): New.
(sparc_va_arg): New.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@29115 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.c | 90 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.h | 8 |
3 files changed, 105 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fe084e32f75..d417604b255 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +Sat Sep 4 17:15:13 1999 Richard Henderson <rth@cygnus.com> + + * sparc.h (EXPAND_BUILTIN_VA_START): Define. + (EXPAND_BUILTIN_VA_ARG): Define. + * sparc.c (sparc_va_start): New. + (sparc_va_arg): New. + Sun Sep 5 11:11:59 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz> * config/c4x/c4x.h (DBR_OUTPUT_SEQEND): Use XVECEXP not XEXPs. diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index ad51856714d..622e04b0774 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -4280,6 +4280,96 @@ sparc_builtin_saveregs () return address; } + +/* Implement `va_start' for varargs and stdarg. */ + +void +sparc_va_start (stdarg_p, valist, nextarg) + int stdarg_p ATTRIBUTE_UNUSED; + tree valist; + rtx nextarg; +{ + nextarg = expand_builtin_saveregs (); + std_expand_builtin_va_start (1, valist, nextarg); +} + +/* Implement `va_arg'. */ + +rtx +sparc_va_arg (valist, type) + tree valist, type; +{ + HOST_WIDE_INT size, rsize, align; + tree addr, incr, tmp; + rtx addr_rtx; + int indirect = 0; + + /* Round up sizeof(type) to a word. */ + size = int_size_in_bytes (type); + rsize = (size + UNITS_PER_WORD - 1) & -UNITS_PER_WORD; + align = 0; + + if (TARGET_ARCH64) + { + if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD) + align = 2 * UNITS_PER_WORD; + + if (AGGREGATE_TYPE_P (type) && size > 16) + { + indirect = 1; + size = rsize = UNITS_PER_WORD; + } + } + else + { + if (AGGREGATE_TYPE_P (type) + || TYPE_MODE (type) == TFmode + || TYPE_MODE (type) == TCmode) + { + 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; + if (align) + { + incr = fold (build (PLUS_EXPR, ptr_type_node, incr, + build_int_2 (align - 1, 0))); + incr = fold (build (BIT_AND_EXPR, ptr_type_node, incr, + build_int_2 (-align, -1))); + } + + addr = incr = save_expr (incr); + if (BYTES_BIG_ENDIAN && size < rsize) + { + addr = fold (build (PLUS_EXPR, ptr_type_node, incr, + build_int_2 (rsize - size, 0))); + } + incr = fold (build (PLUS_EXPR, ptr_type_node, incr, + build_int_2 (rsize, 0))); + + incr = build (MODIFY_EXPR, ptr_type_node, valist, incr); + TREE_SIDE_EFFECTS (incr) = 1; + expand_expr (incr, const0_rtx, VOIDmode, EXPAND_NORMAL); + + addr_rtx = expand_expr (addr, NULL, Pmode, EXPAND_NORMAL); + + if (indirect) + { + addr_rtx = force_reg (Pmode, addr_rtx); + addr_rtx = gen_rtx_MEM (Pmode, addr_rtx); + MEM_ALIAS_SET (addr_rtx) = get_varargs_alias_set (); + } + + return addr_rtx; +} /* Return the string to output a conditional branch to LABEL, which is the operand number of the label. OP is the conditional expression. diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index 9d78988ed48..d113248b808 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -2046,6 +2046,14 @@ void sparc64_initialize_trampoline (); extern struct rtx_def *sparc_builtin_saveregs (); #define EXPAND_BUILTIN_SAVEREGS() sparc_builtin_saveregs () +/* Implement `va_start' for varargs and stdarg. */ +#define EXPAND_BUILTIN_VA_START(stdarg, valist, nextarg) \ + sparc_va_start (stdarg, valist, nextarg) + +/* Implement `va_arg'. */ +#define EXPAND_BUILTIN_VA_ARG(valist, type) \ + sparc_va_arg (valist, type) + /* Define this macro if the location where a function argument is passed depends on whether or not it is a named argument. |