summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>1999-09-05 00:16:18 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>1999-09-05 00:16:18 +0000
commita959290029aade6de4bf3866d0cca137067f663e (patch)
tree37b6e2cabd6f1672b8525e0ccc80e082bc7a76b2 /gcc
parent9c7abf83626d9c0437f641d8c2b484463840794e (diff)
downloadgcc-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/ChangeLog7
-rw-r--r--gcc/config/sparc/sparc.c90
-rw-r--r--gcc/config/sparc/sparc.h8
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.