summaryrefslogtreecommitdiff
path: root/gcc/calls.c
diff options
context:
space:
mode:
authordj <dj@138bc75d-0d04-0410-961f-82ee72b054a4>2003-09-04 03:18:05 +0000
committerdj <dj@138bc75d-0d04-0410-961f-82ee72b054a4>2003-09-04 03:18:05 +0000
commit455507905e358525176b45e9c2c49e0d35e79927 (patch)
tree99ad51d803293a4cc8d3ad48596aa725cf1cc596 /gcc/calls.c
parent9d344979cab6242e4366ca8d9c5d924daa9112f5 (diff)
downloadgcc-455507905e358525176b45e9c2c49e0d35e79927.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@71048 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/calls.c')
-rw-r--r--gcc/calls.c61
1 files changed, 33 insertions, 28 deletions
diff --git a/gcc/calls.c b/gcc/calls.c
index 50fa592972a..dc3da0a9174 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -1,5 +1,5 @@
/* Convert function calls to rtl insns, for GNU C compiler.
- Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998
+ Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -1177,9 +1177,8 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
mode = TYPE_MODE (type);
unsignedp = TREE_UNSIGNED (type);
-#ifdef PROMOTE_FUNCTION_ARGS
- mode = promote_mode (type, mode, &unsignedp, 1);
-#endif
+ if (targetm.calls.promote_function_args (fndecl ? TREE_TYPE (fndecl) : 0))
+ mode = promote_mode (type, mode, &unsignedp, 1);
args[i].unsignedp = unsignedp;
args[i].mode = mode;
@@ -2060,6 +2059,7 @@ expand_call (tree exp, rtx target, int ignore)
/* Nonzero if called function returns an aggregate in memory PCC style,
by returning the address of where to find it. */
int pcc_struct_value = 0;
+ rtx struct_value = 0;
/* Number of actual parameters in this call, including struct value addr. */
int num_actuals;
@@ -2175,6 +2175,8 @@ expand_call (tree exp, rtx target, int ignore)
else
flags |= flags_from_decl_or_type (TREE_TYPE (TREE_TYPE (p)));
+ struct_value = targetm.calls.struct_value_rtx (fndecl ? TREE_TYPE (fndecl) : 0, 0);
+
/* Warn if this value is an aggregate type,
regardless of which calling convention we are using for it. */
if (warn_aggregate_return && AGGREGATE_TYPE_P (TREE_TYPE (exp)))
@@ -2222,7 +2224,7 @@ expand_call (tree exp, rtx target, int ignore)
/* Set up a place to return a structure. */
/* Cater to broken compilers. */
- if (aggregate_value_p (exp))
+ if (aggregate_value_p (exp, fndecl))
{
/* This call returns a big structure. */
flags &= ~(ECF_CONST | ECF_PURE | ECF_LIBCALL_BLOCK);
@@ -2316,7 +2318,7 @@ expand_call (tree exp, rtx target, int ignore)
/* If struct_value_rtx is 0, it means pass the address
as if it were an extra parameter. */
- if (structure_value_addr && struct_value_rtx == 0)
+ if (structure_value_addr && struct_value == 0)
{
/* If structure_value_addr is a REG other than
virtual_outgoing_args_rtx, we can use always use it. If it
@@ -2342,6 +2344,14 @@ expand_call (tree exp, rtx target, int ignore)
for (p = actparms, num_actuals = 0; p; p = TREE_CHAIN (p))
num_actuals++;
+ /* Start updating where the next arg would go.
+
+ On some machines (such as the PA) indirect calls have a difuferent
+ calling convention than normal calls. The last argument in
+ INIT_CUMULATIVE_ARGS tells the backend if this is an indirect call
+ or not. */
+ INIT_CUMULATIVE_ARGS (args_so_far, funtype, NULL_RTX, fndecl);
+
/* Compute number of named args.
Normally, don't include the last named arg if anonymous args follow.
We do include the last named arg if STRICT_ARGUMENT_NAMING is nonzero.
@@ -2358,27 +2368,19 @@ expand_call (tree exp, rtx target, int ignore)
reliable way to pass unnamed args in registers, so we must force
them into memory. */
- if ((STRICT_ARGUMENT_NAMING
- || ! PRETEND_OUTGOING_VARARGS_NAMED)
+ if ((targetm.calls.strict_argument_naming (&args_so_far)
+ || ! targetm.calls.pretend_outgoing_varargs_named (&args_so_far))
&& type_arg_types != 0)
n_named_args
= (list_length (type_arg_types)
/* Don't include the last named arg. */
- - (STRICT_ARGUMENT_NAMING ? 0 : 1)
+ - (targetm.calls.strict_argument_naming (&args_so_far) ? 0 : 1)
/* Count the struct value address, if it is passed as a parm. */
+ structure_value_addr_parm);
else
/* If we know nothing, treat all args as named. */
n_named_args = num_actuals;
- /* Start updating where the next arg would go.
-
- On some machines (such as the PA) indirect calls have a different
- calling convention than normal calls. The last argument in
- INIT_CUMULATIVE_ARGS tells the backend if this is an indirect call
- or not. */
- INIT_CUMULATIVE_ARGS (args_so_far, funtype, NULL_RTX, fndecl);
-
/* Make a vector to hold all the information about each arg. */
args = alloca (num_actuals * sizeof (struct arg_data));
memset (args, 0, num_actuals * sizeof (struct arg_data));
@@ -3016,13 +3018,13 @@ expand_call (tree exp, rtx target, int ignore)
structure_value_addr = convert_memory_address
(Pmode, structure_value_addr);
#endif
- emit_move_insn (struct_value_rtx,
+ emit_move_insn (struct_value,
force_reg (Pmode,
force_operand (structure_value_addr,
NULL_RTX)));
- if (GET_CODE (struct_value_rtx) == REG)
- use_reg (&call_fusage, struct_value_rtx);
+ if (GET_CODE (struct_value) == REG)
+ use_reg (&call_fusage, struct_value);
}
funexp = prepare_call_address (funexp, fndecl, &call_fusage,
@@ -3246,7 +3248,8 @@ expand_call (tree exp, rtx target, int ignore)
else
target = copy_to_reg (valreg);
-#ifdef PROMOTE_FUNCTION_RETURN
+ if (targetm.calls.promote_function_return(funtype))
+ {
/* If we promoted this return value, make the proper SUBREG. TARGET
might be const0_rtx here, so be careful. */
if (GET_CODE (target) == REG
@@ -3277,7 +3280,7 @@ expand_call (tree exp, rtx target, int ignore)
SUBREG_PROMOTED_VAR_P (target) = 1;
SUBREG_PROMOTED_UNSIGNED_SET (target, unsignedp);
}
-#endif
+ }
/* If size of args is variable or this was a constructor call for a stack
argument, restore saved stack-pointer value. */
@@ -3586,6 +3589,8 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
int initial_highest_arg_in_use = highest_outgoing_arg_in_use;
char *initial_stack_usage_map = stack_usage_map;
+ rtx struct_value = targetm.calls.struct_value_rtx (0, 0);
+
#ifdef REG_PARM_STACK_SPACE
#ifdef MAYBE_REG_PARM_STACK_SPACE
reg_parm_stack_space = MAYBE_REG_PARM_STACK_SPACE;
@@ -3638,7 +3643,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
if (outmode != VOIDmode)
{
tfom = (*lang_hooks.types.type_for_mode) (outmode, 0);
- if (aggregate_value_p (tfom))
+ if (aggregate_value_p (tfom, 0))
{
#ifdef PCC_STATIC_STRUCT_RETURN
rtx pointer_reg
@@ -3693,7 +3698,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
/* If there's a structure value address to be passed,
either pass it in the special place, or pass it as an extra argument. */
- if (mem_value && struct_value_rtx == 0 && ! pcc_struct_value)
+ if (mem_value && struct_value == 0 && ! pcc_struct_value)
{
rtx addr = XEXP (mem_value, 0);
nargs++;
@@ -4068,14 +4073,14 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
}
/* Pass the function the address in which to return a structure value. */
- if (mem_value != 0 && struct_value_rtx != 0 && ! pcc_struct_value)
+ if (mem_value != 0 && struct_value != 0 && ! pcc_struct_value)
{
- emit_move_insn (struct_value_rtx,
+ emit_move_insn (struct_value,
force_reg (Pmode,
force_operand (XEXP (mem_value, 0),
NULL_RTX)));
- if (GET_CODE (struct_value_rtx) == REG)
- use_reg (&call_fusage, struct_value_rtx);
+ if (GET_CODE (struct_value) == REG)
+ use_reg (&call_fusage, struct_value);
}
/* Don't allow popping to be deferred, since then