From: Geoffrey Keating Date: Tue, 7 Oct 2003 19:23:08 +0000 (+0000) Subject: hooks.c (hook_bool_tree_true): New. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c6e8c9219569f455c71553d29ad8d6af20098b92;p=gcc.git hooks.c (hook_bool_tree_true): New. * hooks.c (hook_bool_tree_true): New. (hook_rtx_tree_int_null): New. (hook_rtx_rtx_null): Use NULL, not 0. * hooks.h: Add 'extern' to everything. (hook_bool_tree_true): New. (hook_rtx_tree_int_null): New. * targhooks.c (hook_bool_CUMULATIVE_ARGS_true): New. * targhooks.h (hook_bool_CUMULATIVE_ARGS_true): New. * config/rs6000/rs6000-protos.h (setup_incoming_varargs): Remove prototype. * config/rs6000/rs6000.c (rs6000_return_in_memory): New. (setup_incoming_varargs): Prototype. (TARGET_PROMOTE_FUNCTION_ARGS): Define. (TARGET_PROMOTE_FUNCTION_RETURN): Define. (TARGET_STRUCT_VALUE_RTX): Define. (TARGET_RETURN_IN_MEMORY): Define. (TARGET_SETUP_INCOMING_VARARGS): Define. (TARGET_STRICT_ARGUMENT_NAMING): Define. (TARGET_PRETEND_OUTGOING_VARARGS_NAMED): Define. (init_cumulative_args): Use rs6000_return_in_memory. (setup_incoming_varargs): Make 'static'. * config/rs6000/rs6000.h (PROMOTE_FUNCTION_ARGS): Delete. (PROMOTE_FUNCTION_RETURN): Delete. (STRUCT_VALUE): Delete. (RETURN_IN_MEMORY): Delete. (SETUP_INCOMING_VARARGS): Delete. From-SVN: r72197 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 69487651fe4..94546133142 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,26 @@ +2003-10-06 Geoffrey Keating + + * config/sparc/sparc.h (STACK_BOUNDARY): Add comment about how + it's wrong when TARGET_ARCH64 && TARGET_STACK_BIAS. + +2003-09-24 Geoffrey Keating + + * 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 * 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 021c40cc761..35af1676152 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 2dd108a4137..29a584c1016 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 beaf8d3b212..5d7e2e7d546 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 966945d9066..939ed844168 100644 --- a/gcc/hooks.c +++ b/gcc/hooks.c @@ -158,6 +158,12 @@ hook_bool_tree_false (tree a ATTRIBUTE_UNUSED) return false; } +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) { @@ -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 a3465f122d0..77111155ba7 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 5597635a0ab..1000abb5d24 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 0d7b276a9a4..724abe82ab4 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 *);