summaryrefslogtreecommitdiff
path: root/gcc/function.c
diff options
context:
space:
mode:
authorDJ Delorie <dj@redhat.com>2003-09-03 23:18:05 -0400
committerDJ Delorie <dj@gcc.gnu.org>2003-09-03 23:18:05 -0400
commit61f71b34471e03254cdadd61f1418f425101273f (patch)
tree99ad51d803293a4cc8d3ad48596aa725cf1cc596 /gcc/function.c
parentb885908b11b9952ec25251e56ab7000d9349c163 (diff)
downloadgcc-61f71b34471e03254cdadd61f1418f425101273f.tar.gz
targhooks.c: New file.
* targhooks.c: New file. * targhooks.h: New file. * Makefile.in: Add targhooks.o support. (function.o): Depend on$(TARGET_H). (stmt.o): Likewise. (combine.o): Depend on $(TREE_H) and $(TARGET_H). * builtins.c (apply_args_size, expand_builtin_apply_args_1, expand_builtin_apply): Convert to calls.struct_value_rtx hook. (expand_builtin_saveregs): Convert to calls.expand_builtin_saveregs hook. * c-decl.c (start_decl): Handle new calls.promote_prototypes hook here, instead of ... (get_parm_info) ... here. (store_parm_decls_oldstyle): Convert to calls.promote_prototypes hook. (finish_function): Handle calls.promote_prototypes hook here too. * c-typeck.c (convert_arguments): Convert to calls.promote_prototypes hook. (c_convert_parm_for_inlining): Likewise. * calls.c (initialize_argument_information): Convert to calls.promote_function_args hook. (expand_call): Convert to calls.struct_value_rtx, calls.strict_argument_naming, calls.pretend_outgoing_varargs_named, and calls.promote_function_return hooks. Pass fndecl to aggregate_value_p. Initialize CUMULATIVE_ARGS before calling hooks, so they can use that. (emit_library_call_value_1): Likewise. * combine.c (setup_incoming_promotions): Convert to calls.promote_function_args hook. * emit-rtl.c: Convert to calls.struct_value_rtx hook. * expr.c (expand_assignment): Pass call to aggregate_value_p. (expand_expr): Likewise. * expr.h: Remove support for SETUP_INCOMING_VARARGS, STRICT_ARGUMENT_NAMING, PRETEND_OUTGOING_VARARGS_NAMED, RETURN_IN_MEMORY macro defaults. * final.c (profile_function): Convert to calls.struct_value_rtx hook. * function.c (aggregate_value_p): Accept function type tree as second parameter; try to deduce fntype from it. Convert to calls.return_in_memory hook. (assign_parms): Convert to calls.setup_incoming_varargs, calls.strict_argument_naming, calls.promote_function_args, calls.pretend_outgoing_varargs_named hooks. Pass fndecl to aggregate_value_p. (expand_function_start): Likewise. Convert to calls.struct_value_rtx hook. (expand_function_end): Convert to calls.promote_function_return hook. (allocate_struct_function): Pass fndecl to aggregate_value_p. * hard-reg-set.h: Update comments to new hook names. * integrate.c (expand_inline_function): Pass fndecl to aggregate_value_p. * reg-stack.c (stack_result): Likewise. * rtl.h (struct_value_rtx, struct_value_incoming_rtx): Delete. * stmt.c (expand_value_return): Convert to calls.promote_function_return hook. * target-def.h: Add TARGET_PROMOTE_FUNCTION_ARGS, TARGET_PROMOTE_FUNCTION_RETURN, TARGET_PROMOTE_PROTOTYPES, TARGET_STRUCT_VALUE_RTX, TARGET_RETURN_IN_MEMORY, TARGET_EXPAND_BUILTIN_SAVEREGS, TARGET_SETUP_INCOMING_VARARGS, TARGET_STRICT_ARGUMENT_NAMING, TARGET_PRETEND_OUTGOING_VARARGS_NAMED, and TARGET_CALLS. * target.h: Likewise. * tree.h (aggregate_value_p): Also takes a tree to deduce function attributes from (for target hooks). * doc/tm.texi (PROMOTE_FUNCTION_ARGS, PROMOTE_FUNCTION_RETURN, PROMOTE_PROTOTYPES, RETURN_IN_MEMORY, STRUCT_VALUE_REGNUM, STRUCT_VALUE, STRUCT_VALUE_INCOMING_REGNUM, STRUCT_VALUE_INCOMING, EXPAND_BUILTIN_SAVEREGS, SETUP_INCOMING_VARARGS, STRICT_ARGUMENT_NAMING, PRETEND_OUTGOING_VARARGS_NAMED): Convert to hooks. * config/alpha/alpha.c (alpha_output_mi_thunk_osf): Pass function to aggregate_value_p. * config/arm/arm.c (arm_init_cumulative_args, arm_output_mi_thunk): Likewise. * config/i386/i386.c (ix86_return_pops_args, x86_this_parameter): Likewise. * config/mips/mips.c (mips_save_reg_p, mips_expand_prologue, mips_can_use_return_insn): Likewise. * config/rs6000/rs6000.c (rs6000_output_mi_thunk): Likewise. * config/s390/s390.c (s390_output_mi_thunk): Likewise. * config/sparc/sparc.c (sparc_output_mi_thunk): Pass function to aggregate_value_p. * config/story16/stormy16.c (xstormy16_asm_output_mi_thunk): Pass function to aggregate_value_p. * objc/objc-act.c (generate_struct_by_value_array): Pass NULL to aggregate_value_p. * config/sh/sh-protos.h (sh_builtin_saveregs): Remove. (sh_attr_renesas_p, sh_cfun_attr_renesas_p, sh_function_arg, sh_function_arg_advance, sh_pass_in_reg_p): New. * config/sh/sh.c (sh_handle_renesas_attribute, sh_promote_prototypes, sh_struct_value_rtx, sh_return_in_memory, sh_builtin_saveregs, sh_setup_incoming_varargs, sh_strict_argument_naming, sh_pretend_outgoing_varargs_named): New decls. (targetm): Add new hooks. (calc_live_regs): Save MACL and MACH if the function has the renesas attribute. (sh_expand_prologue): Support renesas attribute. (sh_builtin_saveregs): Make static. (sh_build_va_list): Support renesas attribute. (sh_va_start): Likewise. (sh_va_arg): Likewise. (sh_promote_prototypes): New. (sh_function_arg): New, moved from sh.h. Support renesas attribute. (sh_function_arg_advance): Likewise. (sh_return_in_memory): Likewise. (sh_strict_argument_naming): Likewise. (sh_pretend_outgoing_varargs_named): Likewise. (sh_struct_value_rtx): New. (sh_attribute): Add renesas attribute. (sh_handle_renesas_attribute): New. (sh_attr_renesas_p, sh_cfun_attr_renesas_p): New. (sh_ms_bitfield_layout_p): Support renesas attribute also. (sh_output_mi_thunk): Pass function to aggregate_value_p. * config/sh/sh.h (TARGET_SWITCHES): Add -mrenesas as an alias for -mhitachi. (STRUCT_VALUE_REGNUM, STRUCT_VALUE, RETURN_IN_MEMORY): Moved to target hooks. (sh_args): Add renesas_abi flag. (INIT_CUMULATIVE_ARGS): Set it. Pass fndecl to aggregate_value_p. (FUNCTION_ARG_ADVANCE, FUNCTION_ARG): Move to sh.c. (PASS_IN_REG_P): Support renesas attribute. Pass DF and TF on the stack for the renesas abi. (STRICT_ARGUMENT_NAMING, PRETEND_OUTGOING_VARARGS_NAMED, SETUP_INCOMING_VARARGS, EXPAND_BUILTIN_SAVEREGS, PROMOTE_PROTOTYPES): Moved to sh.c. * config/sh/sh.md (call): Set call cookie to indicate renesas calls. * decl.c (finish_function): Pass fndecl to aggregate_value_p. * misc.c (default_pass_by_ref): Convert to calls.return_in_memory hook. From-SVN: r71048
Diffstat (limited to 'gcc/function.c')
-rw-r--r--gcc/function.c74
1 files changed, 46 insertions, 28 deletions
diff --git a/gcc/function.c b/gcc/function.c
index 6decfdf232d..8227139d256 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -62,6 +62,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "tm_p.h"
#include "integrate.h"
#include "langhooks.h"
+#include "target.h"
#ifndef TRAMPOLINE_ALIGNMENT
#define TRAMPOLINE_ALIGNMENT FUNCTION_BOUNDARY
@@ -4177,16 +4178,37 @@ get_first_nonparm_insn (void)
EXP may be a type node or an expression (whose type is tested). */
int
-aggregate_value_p (tree exp)
+aggregate_value_p (tree exp, tree fntype)
{
int i, regno, nregs;
rtx reg;
tree type = (TYPE_P (exp)) ? exp : TREE_TYPE (exp);
+ if (fntype)
+ switch (TREE_CODE (fntype))
+ {
+ case CALL_EXPR:
+ fntype = get_callee_fndecl (fntype);
+ fntype = fntype ? TREE_TYPE (fntype) : 0;
+ break;
+ case FUNCTION_DECL:
+ fntype = TREE_TYPE (fntype);
+ break;
+ case FUNCTION_TYPE:
+ case METHOD_TYPE:
+ break;
+ case IDENTIFIER_NODE:
+ fntype = 0;
+ break;
+ default:
+ /* We don't expect other rtl types here. */
+ abort();
+ }
+
if (TREE_CODE (type) == VOID_TYPE)
return 0;
- if (RETURN_IN_MEMORY (type))
+ if (targetm.calls.return_in_memory (type, fntype))
return 1;
/* Types that are TREE_ADDRESSABLE must be constructed in memory,
and thus can't be returned in registers. */
@@ -4230,9 +4252,7 @@ assign_parms (tree fndecl)
/* This is a dummy PARM_DECL that we used for the function result if
the function returns a structure. */
tree function_result_decl = 0;
-#ifdef SETUP_INCOMING_VARARGS
int varargs_setup = 0;
-#endif
int reg_parm_stack_space = 0;
rtx conversion_insns = 0;
@@ -4265,9 +4285,9 @@ assign_parms (tree fndecl)
stack_args_size.var = 0;
/* If struct value address is treated as the first argument, make it so. */
- if (aggregate_value_p (DECL_RESULT (fndecl))
+ if (aggregate_value_p (DECL_RESULT (fndecl), fndecl)
&& ! current_function_returns_pcc_struct
- && struct_value_incoming_rtx == 0)
+ && targetm.calls.struct_value_rtx (TREE_TYPE (fndecl), 1) == 0)
{
tree type = build_pointer_type (TREE_TYPE (fntype));
@@ -4336,7 +4356,7 @@ assign_parms (tree fndecl)
/* Set NAMED_ARG if this arg should be treated as a named arg. For
most machines, if this is a varargs/stdarg function, then we treat
the last named arg as if it were anonymous too. */
- named_arg = STRICT_ARGUMENT_NAMING ? 1 : ! last_named;
+ named_arg = targetm.calls.strict_argument_naming (&args_so_far) ? 1 : ! last_named;
if (TREE_TYPE (parm) == error_mark_node
/* This can happen after weird syntax errors
@@ -4401,11 +4421,12 @@ assign_parms (tree fndecl)
promoted_mode = passed_mode;
-#ifdef PROMOTE_FUNCTION_ARGS
- /* Compute the mode in which the arg is actually extended to. */
- unsignedp = TREE_UNSIGNED (passed_type);
- promoted_mode = promote_mode (passed_type, promoted_mode, &unsignedp, 1);
-#endif
+ if (targetm.calls.promote_function_args (TREE_TYPE (fndecl)))
+ {
+ /* Compute the mode in which the arg is actually extended to. */
+ unsignedp = TREE_UNSIGNED (passed_type);
+ promoted_mode = promote_mode (passed_type, promoted_mode, &unsignedp, 1);
+ }
/* Let machine desc say which reg (if any) the parm arrives in.
0 means it arrives on the stack. */
@@ -4420,7 +4441,6 @@ assign_parms (tree fndecl)
if (entry_parm == 0)
promoted_mode = passed_mode;
-#ifdef SETUP_INCOMING_VARARGS
/* If this is the last named parameter, do any required setup for
varargs or stdargs. We need to know about the case of this being an
addressable type, in which case we skip the registers it
@@ -4433,11 +4453,11 @@ assign_parms (tree fndecl)
Also, indicate when RTL generation is to be suppressed. */
if (last_named && !varargs_setup)
{
- SETUP_INCOMING_VARARGS (args_so_far, promoted_mode, passed_type,
- current_function_pretend_args_size, 0);
+ targetm.calls.setup_incoming_varargs (&args_so_far, promoted_mode,
+ passed_type,
+ &current_function_pretend_args_size, 0);
varargs_setup = 1;
}
-#endif
/* Determine parm's home in the stack,
in case it arrives in the stack or we should pretend it did.
@@ -4457,7 +4477,8 @@ assign_parms (tree fndecl)
#endif
if (!in_regs && !named_arg)
{
- int pretend_named = PRETEND_OUTGOING_VARARGS_NAMED;
+ int pretend_named =
+ targetm.calls.pretend_outgoing_varargs_named (&args_so_far);
if (pretend_named)
{
#ifdef FUNCTION_INCOMING_ARG
@@ -5275,8 +5296,6 @@ split_complex_args (tree args)
that REGNO is promoted from and whether the promotion was signed or
unsigned. */
-#ifdef PROMOTE_FUNCTION_ARGS
-
rtx
promoted_input_arg (unsigned int regno, enum machine_mode *pmode, int *punsignedp)
{
@@ -5304,7 +5323,6 @@ promoted_input_arg (unsigned int regno, enum machine_mode *pmode, int *punsigned
return 0;
}
-#endif
/* Compute the size and offset from the start of the stacked arguments for a
parm passed in mode PASSED_MODE and with type TYPE.
@@ -6284,7 +6302,7 @@ allocate_struct_function (tree fndecl)
current_function_name = (*lang_hooks.decl_printable_name) (fndecl, 2);
result = DECL_RESULT (fndecl);
- if (aggregate_value_p (result))
+ if (aggregate_value_p (result, fndecl))
{
#ifdef PCC_STATIC_STRUCT_RETURN
current_function_returns_pcc_struct = 1;
@@ -6515,7 +6533,7 @@ expand_function_start (tree subr, int parms_have_cleanups)
before any library calls that assign parms might generate. */
/* Decide whether to return the value in memory or in a register. */
- if (aggregate_value_p (DECL_RESULT (subr)))
+ if (aggregate_value_p (DECL_RESULT (subr), subr))
{
/* Returning something that won't go in a register. */
rtx value_address = 0;
@@ -6529,13 +6547,14 @@ expand_function_start (tree subr, int parms_have_cleanups)
else
#endif
{
+ rtx sv = targetm.calls.struct_value_rtx (TREE_TYPE (subr), 1);
/* Expect to be passed the address of a place to store the value.
If it is passed as an argument, assign_parms will take care of
it. */
- if (struct_value_incoming_rtx)
+ if (sv)
{
value_address = gen_reg_rtx (Pmode);
- emit_move_insn (value_address, struct_value_incoming_rtx);
+ emit_move_insn (value_address, sv);
}
}
if (value_address)
@@ -6973,10 +6992,9 @@ expand_function_end (void)
{
int unsignedp = TREE_UNSIGNED (TREE_TYPE (decl_result));
-#ifdef PROMOTE_FUNCTION_RETURN
- promote_mode (TREE_TYPE (decl_result), GET_MODE (decl_rtl),
- &unsignedp, 1);
-#endif
+ if (targetm.calls.promote_function_return (TREE_TYPE (current_function_decl)))
+ promote_mode (TREE_TYPE (decl_result), GET_MODE (decl_rtl),
+ &unsignedp, 1);
convert_move (real_decl_rtl, decl_rtl, unsignedp);
}