diff options
author | DJ Delorie <dj@redhat.com> | 2003-09-03 23:18:05 -0400 |
---|---|---|
committer | DJ Delorie <dj@gcc.gnu.org> | 2003-09-03 23:18:05 -0400 |
commit | 61f71b34471e03254cdadd61f1418f425101273f (patch) | |
tree | 99ad51d803293a4cc8d3ad48596aa725cf1cc596 /gcc/function.c | |
parent | b885908b11b9952ec25251e56ab7000d9349c163 (diff) | |
download | gcc-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.c | 74 |
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, + ¤t_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); } |