aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog23
-rw-r--r--gcc/config/rs6000/rs6000-protos.h3
-rw-r--r--gcc/config/rs6000/rs6000.c65
-rw-r--r--gcc/config/rs6000/rs6000.h53
-rw-r--r--gcc/hooks.c15
-rw-r--r--gcc/hooks.h62
-rw-r--r--gcc/targhooks.c7
-rw-r--r--gcc/targhooks.h2
8 files changed, 141 insertions, 89 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6948765..9454613 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,26 @@
+2003-10-06 Geoffrey Keating <geoffk@apple.com>
+
+ * config/sparc/sparc.h (STACK_BOUNDARY): Add comment about how
+ it's wrong when TARGET_ARCH64 && TARGET_STACK_BIAS.
+
+2003-09-24 Geoffrey Keating <geoffk@apple.com>
+
+ * 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.
+
+ * config/rs6000/rs6000.c (rs6000_override_options): Make processor
+ list have list of flags to set and all flags, rather than flags
+ to set and flags to clear; add MASK_ALTIVEC where appropriate;
+ use enums rather than #defines.
+
+ * 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.
+
2003-10-07 Gerald Pfeifer <gerald@pfeifer.com>
* doc/invoke.texi (Warning Options): Simplify and clarify the
diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index 021c40c..35af167 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -151,9 +151,6 @@ extern int function_arg_partial_nregs (CUMULATIVE_ARGS *,
extern int function_arg_pass_by_reference (CUMULATIVE_ARGS *,
enum machine_mode,
tree, int);
-extern void setup_incoming_varargs (CUMULATIVE_ARGS *,
- enum machine_mode, tree,
- int *, int);
extern rtx rs6000_function_value (tree, tree);
extern rtx rs6000_libcall_value (enum machine_mode);
extern struct rtx_def *rs6000_va_arg (tree, tree);
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 2dd108a..29a584c 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -242,6 +242,7 @@ static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
HOST_WIDE_INT, tree);
static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
+static bool rs6000_return_in_memory (tree, tree);
static void rs6000_file_start (void);
#if TARGET_ELF
static unsigned int rs6000_elf_section_type_flags (tree, const char *, int);
@@ -326,6 +327,9 @@ static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
static rtx rs6000_complex_function_value (enum machine_mode);
static rtx rs6000_spe_function_arg (CUMULATIVE_ARGS *,
enum machine_mode, tree);
+static void setup_incoming_varargs (CUMULATIVE_ARGS *,
+ enum machine_mode, tree,
+ int *, int);
/* Hash table stuff for keeping track of TOC entries. */
@@ -503,6 +507,29 @@ static const char alt_reg_names[][8] =
#undef TARGET_DWARF_REGISTER_SPAN
#define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
+/* On rs6000, function arguments are promoted, as are function return
+ values. */
+#undef TARGET_PROMOTE_FUNCTION_ARGS
+#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
+#undef TARGET_PROMOTE_FUNCTION_RETURN
+#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
+
+/* Structure return values are passed as an extra parameter. */
+#undef TARGET_STRUCT_VALUE_RTX
+#define TARGET_STRUCT_VALUE_RTX hook_rtx_tree_int_null
+
+#undef TARGET_RETURN_IN_MEMORY
+#define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
+
+#undef TARGET_SETUP_INCOMING_VARARGS
+#define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
+
+/* Always strict argument naming on rs6000. */
+#undef TARGET_STRICT_ARGUMENT_NAMING
+#define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
+#undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
+#define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Override command line options. Mostly we process the processor
@@ -3521,6 +3548,39 @@ rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
}
+/* Return a nonzero value to say to return the function value in
+ memory, just as large structures are always returned. TYPE will be
+ the data type of the value, and FNTYPE will be the type of the
+ function doing the returning, or @code{NULL} for libcalls.
+
+ The AIX ABI for the RS/6000 specifies that all structures are
+ returned in memory. The Darwin ABI does the same. The SVR4 ABI
+ specifies that structures <= 8 bytes are returned in r3/r4, but a
+ draft put them in memory, and GCC used to implement the draft
+ instead of the final standard. Therefore, TARGET_AIX_STRUCT_RET
+ controls this instead of DEFAULT_ABI; V.4 targets needing backward
+ compatibility can change DRAFT_V4_STRUCT_RET to override the
+ default, and -m switches get the final word. See
+ rs6000_override_options for more details.
+
+ The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
+ long double support is enabled. These values are returned in memory.
+
+ int_size_in_bytes returns -1 for variable size objects, which go in
+ memory always. The cast to unsigned makes -1 > 8. */
+
+static bool
+rs6000_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
+{
+ if (AGGREGATE_TYPE_P (type)
+ && (TARGET_AIX_STRUCT_RET
+ || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
+ return true;
+ if (DEFAULT_ABI == ABI_V4 && TYPE_MODE (type) == TFmode)
+ return true;
+ return false;
+}
+
/* Initialize a variable CUM of type CUMULATIVE_ARGS
for a call to a function whose data type is FNTYPE.
For a library call, FNTYPE is 0.
@@ -3553,7 +3613,8 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
else if (cum->prototype)
cum->nargs_prototype = (list_length (TYPE_ARG_TYPES (fntype)) - 1
+ (TYPE_MODE (TREE_TYPE (fntype)) == BLKmode
- || RETURN_IN_MEMORY (TREE_TYPE (fntype))));
+ || rs6000_return_in_memory (TREE_TYPE (fntype),
+ fntype)));
else
cum->nargs_prototype = 0;
@@ -4011,7 +4072,7 @@ function_arg_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
Normally, this macro will push all remaining incoming registers on the
stack and set PRETEND_SIZE to the length of the registers pushed. */
-void
+static void
setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
tree type, int *pretend_size ATTRIBUTE_UNUSED, int no_rtl)
{
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index beaf8d3..5d7e2e7 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -563,15 +563,6 @@ extern int rs6000_sched_restricted_insns_priority;
&& GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \
(MODE) = word_mode;
-/* Define this if function arguments should also be promoted using the above
- procedure. */
-
-#define PROMOTE_FUNCTION_ARGS
-
-/* Likewise, if the function return value is promoted. */
-
-#define PROMOTE_FUNCTION_RETURN
-
/* Define this if most significant bit is lowest numbered
in instructions that operate on numbered bit-fields. */
/* That is true on RS/6000. */
@@ -1151,11 +1142,6 @@ extern int rs6000_sched_restricted_insns_priority;
/* Count register number. */
#define COUNT_REGISTER_REGNUM 66
-
-/* Place that structure value return address is placed.
-
- On the RS/6000, it is passed as an extra parameter. */
-#define STRUCT_VALUE 0
/* Define the classes of registers for register constraints in the
machine description. Also define ranges of constants.
@@ -1616,28 +1602,6 @@ typedef struct rs6000_stack {
#define LIBCALL_VALUE(MODE) rs6000_libcall_value ((MODE))
-/* The AIX ABI for the RS/6000 specifies that all structures are
- returned in memory. The Darwin ABI does the same. The SVR4 ABI
- specifies that structures <= 8 bytes are returned in r3/r4, but a
- draft put them in memory, and GCC used to implement the draft
- instead of the final standard. Therefore, TARGET_AIX_STRUCT_RET
- controls this instead of DEFAULT_ABI; V.4 targets needing backward
- compatibility can change DRAFT_V4_STRUCT_RET to override the
- default, and -m switches get the final word. See
- rs6000_override_options for more details.
-
- The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
- long double support is enabled. These values are returned in memory.
-
- int_size_in_bytes returns -1 for variable size objects, which go in
- memory always. The cast to unsigned makes -1 > 8. */
-
-#define RETURN_IN_MEMORY(TYPE) \
- ((AGGREGATE_TYPE_P (TYPE) \
- && (TARGET_AIX_STRUCT_RET \
- || (unsigned HOST_WIDE_INT) int_size_in_bytes (TYPE) > 8)) \
- || (DEFAULT_ABI == ABI_V4 && TYPE_MODE (TYPE) == TFmode))
-
/* DRAFT_V4_STRUCT_RET defaults off. */
#define DRAFT_V4_STRUCT_RET 0
@@ -1857,23 +1821,6 @@ typedef struct rs6000_args
the ABIs at the moment. For now, only AIX gets fixed. */
#define SPLIT_COMPLEX_ARGS (DEFAULT_ABI == ABI_AIX)
-/* Perform any needed actions needed for a function that is receiving a
- variable number of arguments.
-
- CUM is as above.
-
- MODE and TYPE are the mode and type of the current parameter.
-
- PRETEND_SIZE is a variable that should be set to the amount of stack
- that must be pushed by the prolog to pretend that our caller pushed
- it.
-
- Normally, this macro will push all remaining incoming registers on the
- stack and set PRETEND_SIZE to the length of the registers pushed. */
-
-#define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL) \
- setup_incoming_varargs (&CUM, MODE, TYPE, &PRETEND_SIZE, NO_RTL)
-
/* Define the `__builtin_va_list' type for the ABI. */
#define BUILD_VA_LIST_TYPE(VALIST) \
(VALIST) = rs6000_build_va_list ()
diff --git a/gcc/hooks.c b/gcc/hooks.c
index 966945d..939ed844 100644
--- a/gcc/hooks.c
+++ b/gcc/hooks.c
@@ -159,6 +159,12 @@ hook_bool_tree_false (tree a ATTRIBUTE_UNUSED)
}
bool
+hook_bool_tree_true (tree a ATTRIBUTE_UNUSED)
+{
+ return true;
+}
+
+bool
hook_bool_tree_tree_false (tree a ATTRIBUTE_UNUSED, tree b ATTRIBUTE_UNUSED)
{
return false;
@@ -190,7 +196,14 @@ hook_rtx_rtx_identity (rtx x)
rtx
hook_rtx_rtx_null (rtx x ATTRIBUTE_UNUSED)
{
- return 0;
+ return NULL;
+}
+
+/* Generic hook that takes a tree and an int and returns NULL_RTX. */
+rtx
+hook_rtx_tree_int_null (tree a ATTRIBUTE_UNUSED, int b ATTRIBUTE_UNUSED)
+{
+ return NULL;
}
/* Generic hook that takes a size_t and returns NULL. */
diff --git a/gcc/hooks.h b/gcc/hooks.h
index a3465f1..7711115 100644
--- a/gcc/hooks.h
+++ b/gcc/hooks.h
@@ -22,40 +22,42 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef GCC_HOOKS_H
#define GCC_HOOKS_H
-bool hook_bool_void_false (void);
-bool hook_bool_bool_false (bool);
-bool hook_bool_tree_false (tree);
-bool hook_bool_tree_hwi_hwi_tree_false (tree, HOST_WIDE_INT, HOST_WIDE_INT,
+extern bool hook_bool_void_false (void);
+extern bool hook_bool_bool_false (bool);
+extern bool hook_bool_tree_false (tree);
+extern bool hook_bool_tree_true (tree);
+extern bool hook_bool_tree_hwi_hwi_tree_false (tree, HOST_WIDE_INT, HOST_WIDE_INT,
tree);
-bool hook_bool_tree_hwi_hwi_tree_true (tree, HOST_WIDE_INT, HOST_WIDE_INT,
+extern bool hook_bool_tree_hwi_hwi_tree_true (tree, HOST_WIDE_INT, HOST_WIDE_INT,
tree);
-bool hook_bool_rtx_false (rtx);
-bool hook_bool_rtx_int_int_intp_false (rtx, int, int, int *);
-bool hook_bool_constcharptr_size_t_false (const char *, size_t);
-
-void hook_void_tree_int (tree, int);
-void hook_void_void (void);
-void hook_void_FILEptr_constcharptr (FILE *, const char *);
-void hook_void_tree (tree);
-void hook_void_tree_treeptr (tree, tree *);
-void hook_void_constcharptr (const char *);
-
-int hook_int_tree_tree_1 (tree, tree);
-int hook_int_rtx_0 (rtx);
-int hook_int_void_0 (void);
-int hook_int_size_t_constcharptr_int_0 (size_t, const char *, int);
-int hook_int_void_no_regs (void);
-
-unsigned hook_uint_uint_constcharptrptr_0 (unsigned, const char **);
-
-bool default_can_output_mi_thunk_no_vcall (tree, HOST_WIDE_INT,
+extern bool hook_bool_rtx_false (rtx);
+extern bool hook_bool_rtx_int_int_intp_false (rtx, int, int, int *);
+extern bool hook_bool_constcharptr_size_t_false (const char *, size_t);
+
+extern void hook_void_tree_int (tree, int);
+extern void hook_void_void (void);
+extern void hook_void_FILEptr_constcharptr (FILE *, const char *);
+extern void hook_void_tree (tree);
+extern void hook_void_tree_treeptr (tree, tree *);
+extern void hook_void_constcharptr (const char *);
+
+extern int hook_int_tree_tree_1 (tree, tree);
+extern int hook_int_rtx_0 (rtx);
+extern int hook_int_void_0 (void);
+extern int hook_int_size_t_constcharptr_int_0 (size_t, const char *, int);
+extern int hook_int_void_no_regs (void);
+
+extern unsigned hook_uint_uint_constcharptrptr_0 (unsigned, const char **);
+
+extern bool default_can_output_mi_thunk_no_vcall (tree, HOST_WIDE_INT,
HOST_WIDE_INT, tree);
-bool hook_bool_tree_tree_false (tree, tree);
+extern bool hook_bool_tree_tree_false (tree, tree);
-rtx hook_rtx_rtx_identity (rtx);
-rtx hook_rtx_rtx_null (rtx);
-void * hook_voidp_size_t_null (size_t);
-bool hook_bool_voidp_size_t_false (void *, size_t);
+extern rtx hook_rtx_rtx_identity (rtx);
+extern rtx hook_rtx_rtx_null (rtx);
+extern rtx hook_rtx_tree_int_null (tree, int);
+extern void * hook_voidp_size_t_null (size_t);
+extern bool hook_bool_voidp_size_t_false (void *, size_t);
#endif
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index 5597635..1000abb 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -195,3 +195,10 @@ default_pretend_outgoing_varargs_named(CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED)
#endif
#endif
}
+
+/* Generic hook that takes a CUMULATIVE_ARGS pointer and returns true. */
+bool
+hook_bool_CUMULATIVE_ARGS_true (CUMULATIVE_ARGS * a ATTRIBUTE_UNUSED)
+{
+ return true;
+}
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index 0d7b276..724abe8 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -31,3 +31,5 @@ extern rtx default_expand_builtin_saveregs (void);
extern void default_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode, tree, int *, int);
extern bool default_strict_argument_naming (CUMULATIVE_ARGS *);
extern bool default_pretend_outgoing_varargs_named (CUMULATIVE_ARGS *);
+
+extern bool hook_bool_CUMULATIVE_ARGS_true (CUMULATIVE_ARGS *);