aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/calls.c4
-rw-r--r--gcc/config/rs6000/rs6000.c241
-rw-r--r--gcc/config/sparc/sparc.h6
-rw-r--r--gcc/defaults.h4
-rw-r--r--gcc/function.c29
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/va-arg-24.c34
-rw-r--r--gcc/testsuite/gcc.dg/darwin-abi-2.c23
9 files changed, 267 insertions, 92 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 83438d6..54c7374 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,18 @@
2003-10-07 Geoffrey Keating <geoffk@apple.com>
+ * function.c (pad_to_arg_alignment): Take STACK_POINTER_OFFSET into
+ account when aligning arguments.
+ * calls.c (STACK_POINTER_OFFSET): Move default from here ...
+ * defaults.h (STACK_POINTER_OFFSET): ... to here.
+ * config/sparc/sparc.h (STACK_BOUNDARY): Add comment about how
+ it's wrong when TARGET_ARCH64 && TARGET_STACK_BIAS.
+ (SPARC_STACK_BOUNDARY_HACK): Define.
+ * config/rs6000/rs6000.c (function_arg): On non-SVR4 systems,
+ arrange for vector parameters to varargs functions to be passed
+ in both memory and GPRs when appropriate.
+ (rs6000_va_arg): Vector arguments passed in memory are 16-byte
+ aligned.
+
* hooks.c (hook_bool_tree_true): New.
(hook_rtx_tree_int_null): New.
(hook_rtx_rtx_null): Use NULL, not 0.
diff --git a/gcc/calls.c b/gcc/calls.c
index aa64980..18df59a 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -41,10 +41,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "cgraph.h"
#include "except.h"
-#ifndef STACK_POINTER_OFFSET
-#define STACK_POINTER_OFFSET 0
-#endif
-
/* Like PREFERRED_STACK_BOUNDARY but in units of bytes, not bits. */
#define STACK_BYTES (PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT)
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 29a584c..d6183b8 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -544,134 +544,149 @@ rs6000_override_options (const char *default_cpu)
/* Simplify the entries below by making a mask for any POWER
variant and any PowerPC variant. */
-#define POWER_MASKS (MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING)
-#define POWERPC_MASKS (MASK_POWERPC | MASK_PPC_GPOPT \
- | MASK_PPC_GFXOPT | MASK_POWERPC64)
-#define POWERPC_OPT_MASKS (MASK_PPC_GPOPT | MASK_PPC_GFXOPT)
+ enum {
+ POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
+ POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
+ POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT
+ | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC),
+ POWERPC_OPT_MASKS = MASK_PPC_GPOPT | MASK_PPC_GFXOPT | MASK_ALTIVEC,
+
+ SET_MASKS = (POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT)
+ };
+
+ /* FIXME: In this table, there are a few places where SET_MASKS is
+ used with MASK_POWERPC64 masked off; these indicate processors
+ that are 64-bit but that don't yet have 64-bit switched on by
+ default because it doesn't work in the rest of the backend.
+ There are also some places that SET_MASKS is used with other
+ flags, those are because earlier versions of this table didn't
+ specifically set or clear those flags and I didn't know what the
+ processor supported. Please delete this comment when all of those
+ cases are gone. */
static struct ptt
{
const char *const name; /* Canonical processor name. */
const enum processor_type processor; /* Processor type enum value. */
const int target_enable; /* Target flags to enable. */
- const int target_disable; /* Target flags to disable. */
+ const int target_set; /* Target flags to change. */
} const processor_target_table[]
= {{"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS,
- POWER_MASKS | POWERPC_MASKS},
+ SET_MASKS},
{"power", PROCESSOR_POWER,
MASK_POWER | MASK_MULTIPLE | MASK_STRING,
- MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
+ SET_MASKS},
{"power2", PROCESSOR_POWER,
MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
- POWERPC_MASKS | MASK_NEW_MNEMONICS},
+ SET_MASKS},
{"power3", PROCESSOR_PPC630,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS},
+ POWERPC_BASE_MASK | MASK_PPC_GFXOPT,
+ SET_MASKS & ~MASK_POWERPC64 & ~MASK_PPC_GPOPT},
{"power4", PROCESSOR_POWER4,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS},
+ POWERPC_BASE_MASK | MASK_PPC_GFXOPT,
+ SET_MASKS & ~MASK_POWERPC64 & ~MASK_PPC_GPOPT},
{"powerpc", PROCESSOR_POWERPC,
- MASK_POWERPC | MASK_NEW_MNEMONICS,
- POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
+ POWERPC_BASE_MASK,
+ SET_MASKS},
{"powerpc64", PROCESSOR_POWERPC64,
- MASK_POWERPC | MASK_POWERPC64 | MASK_NEW_MNEMONICS,
- POWER_MASKS | POWERPC_OPT_MASKS},
+ POWERPC_BASE_MASK | MASK_POWERPC64,
+ SET_MASKS},
{"rios", PROCESSOR_RIOS1,
MASK_POWER | MASK_MULTIPLE | MASK_STRING,
- MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
+ SET_MASKS},
{"rios1", PROCESSOR_RIOS1,
MASK_POWER | MASK_MULTIPLE | MASK_STRING,
- MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
+ SET_MASKS},
{"rsc", PROCESSOR_PPC601,
MASK_POWER | MASK_MULTIPLE | MASK_STRING,
- MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
+ SET_MASKS},
{"rsc1", PROCESSOR_PPC601,
MASK_POWER | MASK_MULTIPLE | MASK_STRING,
- MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
+ SET_MASKS},
{"rios2", PROCESSOR_RIOS2,
MASK_POWER | MASK_MULTIPLE | MASK_STRING | MASK_POWER2,
- POWERPC_MASKS | MASK_NEW_MNEMONICS},
+ SET_MASKS},
{"rs64a", PROCESSOR_RS64A,
- MASK_POWERPC | MASK_NEW_MNEMONICS,
- POWER_MASKS | POWERPC_OPT_MASKS},
+ POWERPC_BASE_MASK,
+ SET_MASKS},
{"401", PROCESSOR_PPC403,
- MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
- POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
+ POWERPC_BASE_MASK | MASK_SOFT_FLOAT,
+ SET_MASKS},
{"403", PROCESSOR_PPC403,
- MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS | MASK_STRICT_ALIGN,
- POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
+ POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN,
+ SET_MASKS},
{"405", PROCESSOR_PPC405,
- MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
- POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
+ POWERPC_BASE_MASK | MASK_SOFT_FLOAT,
+ SET_MASKS},
{"405fp", PROCESSOR_PPC405,
- MASK_POWERPC | MASK_NEW_MNEMONICS,
- POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
+ POWERPC_BASE_MASK,
+ SET_MASKS},
{"440", PROCESSOR_PPC440,
- MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
- POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
+ POWERPC_BASE_MASK | MASK_SOFT_FLOAT,
+ SET_MASKS},
{"440fp", PROCESSOR_PPC440,
- MASK_POWERPC | MASK_NEW_MNEMONICS,
- POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
+ POWERPC_BASE_MASK,
+ SET_MASKS},
{"505", PROCESSOR_MPCCORE,
- MASK_POWERPC | MASK_NEW_MNEMONICS,
- POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
+ POWERPC_BASE_MASK,
+ SET_MASKS},
{"601", PROCESSOR_PPC601,
- MASK_POWER | MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_MULTIPLE | MASK_STRING,
- MASK_POWER2 | POWERPC_OPT_MASKS | MASK_POWERPC64},
+ MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING,
+ SET_MASKS},
{"602", PROCESSOR_PPC603,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
+ POWERPC_BASE_MASK | MASK_PPC_GFXOPT,
+ SET_MASKS},
{"603", PROCESSOR_PPC603,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
+ POWERPC_BASE_MASK | MASK_PPC_GFXOPT,
+ SET_MASKS},
{"603e", PROCESSOR_PPC603,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
+ POWERPC_BASE_MASK | MASK_PPC_GFXOPT,
+ SET_MASKS},
{"ec603e", PROCESSOR_PPC603,
- MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
- POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
+ POWERPC_BASE_MASK | MASK_SOFT_FLOAT,
+ SET_MASKS},
{"604", PROCESSOR_PPC604,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
+ POWERPC_BASE_MASK | MASK_PPC_GFXOPT,
+ SET_MASKS},
{"604e", PROCESSOR_PPC604e,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
+ POWERPC_BASE_MASK | MASK_PPC_GFXOPT,
+ SET_MASKS},
{"620", PROCESSOR_PPC620,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS},
+ POWERPC_BASE_MASK | MASK_PPC_GFXOPT,
+ SET_MASKS & ~MASK_POWERPC64 & ~MASK_PPC_GPOPT},
{"630", PROCESSOR_PPC630,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS},
+ POWERPC_BASE_MASK | MASK_PPC_GFXOPT,
+ SET_MASKS & ~MASK_POWERPC64 & ~MASK_PPC_GPOPT},
{"740", PROCESSOR_PPC750,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
+ POWERPC_BASE_MASK | MASK_PPC_GFXOPT,
+ SET_MASKS},
{"750", PROCESSOR_PPC750,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
+ POWERPC_BASE_MASK | MASK_PPC_GFXOPT,
+ SET_MASKS},
{"7400", PROCESSOR_PPC7400,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
+ POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC,
+ SET_MASKS},
{"7450", PROCESSOR_PPC7450,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
+ POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC,
+ SET_MASKS},
{"8540", PROCESSOR_PPC8540,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
+ POWERPC_BASE_MASK | MASK_PPC_GFXOPT,
+ SET_MASKS},
{"801", PROCESSOR_MPCCORE,
- MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
- POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
+ POWERPC_BASE_MASK | MASK_SOFT_FLOAT,
+ SET_MASKS},
{"821", PROCESSOR_MPCCORE,
- MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
- POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
+ POWERPC_BASE_MASK | MASK_SOFT_FLOAT,
+ SET_MASKS},
{"823", PROCESSOR_MPCCORE,
- MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
- POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
+ POWERPC_BASE_MASK | MASK_SOFT_FLOAT,
+ SET_MASKS},
{"860", PROCESSOR_MPCCORE,
- MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
- POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
+ POWERPC_BASE_MASK | MASK_SOFT_FLOAT,
+ SET_MASKS},
{"970", PROCESSOR_POWER4,
- MASK_POWERPC | POWERPC_OPT_MASKS | MASK_NEW_MNEMONICS,
- POWER_MASKS}};
+ POWERPC_BASE_MASK | POWERPC_OPT_MASKS | MASK_ALTIVEC,
+ SET_MASKS & ~MASK_POWERPC64}};
const size_t ptt_size = ARRAY_SIZE (processor_target_table);
@@ -697,8 +712,8 @@ rs6000_override_options (const char *default_cpu)
if (ptr->set_arch_p)
{
+ target_flags &= ~processor_target_table[j].target_set;
target_flags |= processor_target_table[j].target_enable;
- target_flags &= ~processor_target_table[j].target_disable;
}
break;
}
@@ -3732,10 +3747,25 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
{
- if (cum->vregno <= ALTIVEC_ARG_MAX_REG && cum->nargs_prototype >= 0)
+ if (named && cum->vregno <= ALTIVEC_ARG_MAX_REG)
cum->vregno++;
else
- cum->words += RS6000_ARG_SIZE (mode, type);
+ {
+ int align;
+
+ /* Vector parameters must be 16-byte aligned. This places them at
+ 2 mod 4 in terms of words (on both ABIs). */
+ align = ((6 - (cum->words & 3)) & 3);
+ cum->words += align + RS6000_ARG_SIZE (mode, type);
+
+ if (TARGET_DEBUG_ARG)
+ {
+ fprintf (stderr, "function_adv: words = %2d, align=%d, ",
+ cum->words, align);
+ fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
+ cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
+ }
+ }
}
else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
&& !cum->stdarg
@@ -3913,8 +3943,37 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
{
if (named && cum->vregno <= ALTIVEC_ARG_MAX_REG)
return gen_rtx_REG (mode, cum->vregno);
+ else if (named || abi == ABI_V4)
+ return NULL_RTX;
else
- return NULL;
+ {
+ /* Vector parameters to varargs functions under AIX or Darwin
+ get passed in memory and possibly also in GPRs. */
+ int align, align_words;
+ rtx reg;
+
+ /* Vector parameters must be 16-byte aligned. This places them at
+ 2 mod 4 in terms of words. */
+ align = ((6 - (cum->words & 3)) & 3);
+ align_words = cum->words + align;
+
+ /* Out of registers? Memory, then. */
+ if (align_words >= GP_ARG_NUM_REG)
+ return NULL_RTX;
+
+ /* The vector value goes in both memory and GPRs. Varargs
+ vector regs will always be saved in R5-R8 or R9-R12. */
+ reg = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
+
+ return gen_rtx_PARALLEL (mode,
+ gen_rtvec (2,
+ gen_rtx_EXPR_LIST (VOIDmode,
+ NULL_RTX,
+ const0_rtx),
+ gen_rtx_EXPR_LIST (VOIDmode,
+ reg,
+ const0_rtx)));
+ }
}
else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode))
return rs6000_spe_function_arg (cum, mode, type);
@@ -4302,7 +4361,29 @@ rs6000_va_arg (tree valist, tree type)
return expand_expr (t, NULL_RTX, VOIDmode, EXPAND_NORMAL);
}
else
- return std_expand_builtin_va_arg (valist, type);
+ {
+ /* Altivec arguments must be aligned to a 128-bit boundary. */
+ if (ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
+ {
+ tree vtype = TREE_TYPE (valist);
+ tree new_valist, modify;
+
+ /* Round address up to multiple of 16. Computes
+ (addr+15)&~0xf. */
+ new_valist = fold (build (BIT_AND_EXPR, vtype,
+ fold (build (PLUS_EXPR, vtype, valist,
+ build_int_2 (15, 0))),
+ build_int_2 (~15, -1)));
+
+ /* Update valist. */
+ modify = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
+ new_valist);
+ TREE_SIDE_EFFECTS (modify) = 1;
+ expand_expr (modify, const0_rtx, VOIDmode, EXPAND_NORMAL);
+ }
+
+ return std_expand_builtin_va_arg (valist, type);
+ }
}
f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h
index 77de509..d2a37f3 100644
--- a/gcc/config/sparc/sparc.h
+++ b/gcc/config/sparc/sparc.h
@@ -780,7 +780,13 @@ if (TARGET_ARCH64 \
#define PARM_BOUNDARY (TARGET_ARCH64 ? 64 : 32)
/* Boundary (in *bits*) on which stack pointer should be aligned. */
+/* FIXME, this is wrong when TARGET_ARCH64 and TARGET_STACK_BIAS, because
+ then sp+2047 is 128-bit aligned so sp is really only byte-aligned. */
#define STACK_BOUNDARY (TARGET_ARCH64 ? 128 : 64)
+/* Temporary hack until the FIXME above is fixed. This macro is used
+ only in pad_to_arg_alignment in function.c; see the comment there
+ for details about what it does. */
+#define SPARC_STACK_BOUNDARY_HACK (TARGET_ARCH64 && TARGET_STACK_BIAS)
/* ALIGN FRAMES on double word boundaries */
diff --git a/gcc/defaults.h b/gcc/defaults.h
index 34e9f7b..f2595b0b 100644
--- a/gcc/defaults.h
+++ b/gcc/defaults.h
@@ -679,4 +679,8 @@ You Lose! You must define PREFERRED_DEBUGGING_TYPE!
#define MOVE_MAX_PIECES MOVE_MAX
#endif
+#ifndef STACK_POINTER_OFFSET
+#define STACK_POINTER_OFFSET 0
+#endif
+
#endif /* ! GCC_DEFAULTS_H */
diff --git a/gcc/function.c b/gcc/function.c
index 0251fe3..0f158ac 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -5511,6 +5511,16 @@ pad_to_arg_alignment (struct args_size *offset_ptr, int boundary,
{
tree save_var = NULL_TREE;
HOST_WIDE_INT save_constant = 0;
+ HOST_WIDE_INT sp_offset = STACK_POINTER_OFFSET;
+
+#ifdef SPARC_STACK_BOUNDARY_HACK
+ /* The sparc port has a bug. It sometimes claims a STACK_BOUNDARY
+ higher than the real alignment of %sp. However, when it does this,
+ the alignment of %sp+STACK_POINTER_OFFSET will be STACK_BOUNDARY.
+ This is a temporary hack while the sparc port is fixed. */
+ if (SPARC_STACK_BOUNDARY_HACK)
+ sp_offset = 0;
+#endif
int boundary_in_bytes = boundary / BITS_PER_UNIT;
@@ -5527,14 +5537,17 @@ pad_to_arg_alignment (struct args_size *offset_ptr, int boundary,
{
if (offset_ptr->var)
{
- offset_ptr->var =
+ tree sp_offset_tree = ssize_int (sp_offset);
+ tree offset = size_binop (PLUS_EXPR,
+ ARGS_SIZE_TREE (*offset_ptr),
+ sp_offset_tree);
#ifdef ARGS_GROW_DOWNWARD
- round_down
+ tree rounded = round_down (offset, boundary / BITS_PER_UNIT);
#else
- round_up
+ tree rounded = round_up (offset, boundary / BITS_PER_UNIT);
#endif
- (ARGS_SIZE_TREE (*offset_ptr),
- boundary / BITS_PER_UNIT);
+
+ offset_ptr->var = size_binop (MINUS_EXPR, rounded, sp_offset_tree);
/* ARGS_SIZE_TREE includes constant term. */
offset_ptr->constant = 0;
if (boundary > PARM_BOUNDARY && boundary > STACK_BOUNDARY)
@@ -5543,11 +5556,11 @@ pad_to_arg_alignment (struct args_size *offset_ptr, int boundary,
}
else
{
- offset_ptr->constant =
+ offset_ptr->constant = -sp_offset +
#ifdef ARGS_GROW_DOWNWARD
- FLOOR_ROUND (offset_ptr->constant, boundary_in_bytes);
+ FLOOR_ROUND (offset_ptr->constant + sp_offset, boundary_in_bytes);
#else
- CEIL_ROUND (offset_ptr->constant, boundary_in_bytes);
+ CEIL_ROUND (offset_ptr->constant + sp_offset, boundary_in_bytes);
#endif
if (boundary > PARM_BOUNDARY && boundary > STACK_BOUNDARY)
alignment_pad->constant = offset_ptr->constant - save_constant;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 49f002a..4cf0775 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2003-10-07 Geoffrey Keating <geoffk@apple.com>
+
+ * gcc.dg/darwin-abi-2.c: New file.
+ * gcc.c-torture/execute/va-arg-24.c: New file.
+
2003-10-06 Bob Wilson <bob.wilson@acm.org>
* g++.dg/template/spec10.C: Set exit value to zero on success. Fix
diff --git a/gcc/testsuite/gcc.c-torture/execute/va-arg-24.c b/gcc/testsuite/gcc.c-torture/execute/va-arg-24.c
new file mode 100644
index 0000000..c8fdaf0
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/va-arg-24.c
@@ -0,0 +1,34 @@
+/* Varargs and vectors! */
+
+#include <stdarg.h>
+
+#define vector __attribute__((vector_size(16)))
+
+const vector unsigned int v1 = {10,11,12,13};
+const vector unsigned int v2 = {20,21,22,23};
+
+void foo(int a, ...)
+{
+ va_list args;
+ vector unsigned int v;
+
+ va_start (args, a);
+ v = va_arg (args, vector unsigned int);
+ if (a != 1 || memcmp (&v, &v1, sizeof (v)) != 0)
+ abort ();
+ a = va_arg (args, int);
+ if (a != 2)
+ abort ();
+ v = va_arg (args, vector unsigned int);
+ if (memcmp (&v, &v2, sizeof (v) != 0))
+ abort ();
+ va_end (args);
+}
+
+int main(void)
+{
+ foo (1, (vector unsigned int){10,11,12,13}, 2,
+ (vector unsigned int){14,15,16,17});
+ return 0;
+}
+
diff --git a/gcc/testsuite/gcc.dg/darwin-abi-2.c b/gcc/testsuite/gcc.dg/darwin-abi-2.c
new file mode 100644
index 0000000..81da83c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/darwin-abi-2.c
@@ -0,0 +1,23 @@
+/* { dg-do run { target powerpc*-*-darwin* } } */
+
+/* You might think you'd need -maltivec for this, but actually you
+ don't; GCC will happily do everything in GPRs, and it still
+ tests that the ABI is correct. */
+
+#include <stdio.h>
+
+#define vector __attribute__((vector_size(16)))
+
+int main(void)
+{
+ vector unsigned int v = { 100, 200, 300, 400 };
+ vector unsigned int w = { 4, 5, 6, 7 };
+ char x[64];
+ sprintf (x, "%lvu,%d,%lvu", v, 1, w);
+ if (strcmp (x, "100 200 300 400,1,4 5 6 7") != 0)
+ {
+ puts (x);
+ abort ();
+ }
+ return 0;
+}