diff options
author | dj <dj@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-09-04 03:18:05 +0000 |
---|---|---|
committer | dj <dj@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-09-04 03:18:05 +0000 |
commit | 455507905e358525176b45e9c2c49e0d35e79927 (patch) | |
tree | 99ad51d803293a4cc8d3ad48596aa725cf1cc596 /gcc/calls.c | |
parent | 9d344979cab6242e4366ca8d9c5d924daa9112f5 (diff) | |
download | gcc-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.c | 61 |
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 |