diff options
-rw-r--r-- | gcc/ChangeLog | 27 | ||||
-rw-r--r-- | gcc/calls.c | 49 | ||||
-rw-r--r-- | gcc/config/i386/i386-protos.h | 3 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 30 | ||||
-rw-r--r-- | gcc/config/i386/i386.h | 23 | ||||
-rw-r--r-- | gcc/dse.c | 5 | ||||
-rw-r--r-- | gcc/expr.c | 6 | ||||
-rw-r--r-- | gcc/function.c | 29 | ||||
-rw-r--r-- | gcc/target-def.h | 19 | ||||
-rw-r--r-- | gcc/target.h | 20 | ||||
-rw-r--r-- | gcc/targhooks.c | 43 | ||||
-rw-r--r-- | gcc/targhooks.h | 6 |
12 files changed, 184 insertions, 76 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d1cb9a912ea..38fd8a4ad5b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,32 @@ 2010-06-29 Nathan Froyd <froydnj@codesourcery.com> + * calls.c, dse.c, expr.c, function.c: Call targetm.calls.function_arg, + targetm.calls.function_incoming_arg, and + targetm.calls.function_arg_advance instead of FUNCTION_ARG, + FUNCTION_INCOMING_ARG, and FUNCTION_ARG_ADVANCE, respectively. + * target.h (struct gcc_target): Add function_arg_advance, + function_arg, and function_incoming_arg fields. + * target-def.h (TARGET_FUNCTION_ARG_ADVANCE, TARGET_FUNCTION_ARG): + (TARGET_FUNCTION_INCOMING_ARG): Define. + (TARGET_CALLS): Add TARGET_FUNCTION_ARG_ADVANCE, TARGET_FUNCTION_ARG, + and TARGET_FUNCTION_INCOMING_ARG. + * targhooks.h (default_function_arg_advance): Declare. + (default_function_arg, default_function_incoming_arg): Declare. + * targhooks.c (default_function_arg_advance): New function. + (default_function_arg, default_function_incoming_arg): New function. + * config/i386/i386.c (function_arg_advance): Rename to... + (ix86_function_arg_advance): ...this. Make static. + (function_arg): Rename to... + (ix86_function_arg): ...this. Make static. + (TARGET_FUNCTION_ARG_ADVANCE): Define. + (TARGET_FUNCTION_ARG): Define. + * config/i386/i386.h (FUNCTION_ARG_ADVANCE): Delete. + (FUNCTION_ARG): Delete. + * config/i386/i386-protos.h (function_arg_advance): Delete prototype. + (function_arg): Delete prototype. + +2010-06-29 Nathan Froyd <froydnj@codesourcery.com> + * reginfo.c (init_reg_sets_1): Adjust comments. * combine-stack-adj.c (rest_of_handle_stack_adjustments): Likewise. * calls.c (prepare_call_address): Likewise. diff --git a/gcc/calls.c b/gcc/calls.c index c6d4706733a..3b06ad397de 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -228,7 +228,7 @@ prepare_call_address (tree fndecl, rtx funexp, rtx static_chain_value, It is zero if this call doesn't want a structure value. NEXT_ARG_REG is the rtx that results from executing - FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1) + targetm.calls.function_arg (&args_so_far, VOIDmode, void_type_node, true) just after all the args have had their registers assigned. This could be whatever you like, but normally it is the first arg-register beyond those used for args in this call, @@ -1127,17 +1127,18 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED, args[i].unsignedp = unsignedp; args[i].mode = mode; - args[i].reg = FUNCTION_ARG (*args_so_far, mode, type, - argpos < n_named_args); -#ifdef FUNCTION_INCOMING_ARG + args[i].reg = targetm.calls.function_arg (args_so_far, mode, type, + argpos < n_named_args); + /* If this is a sibling call and the machine has register windows, the register window has to be unwinded before calling the routine, so arguments have to go into the incoming registers. */ - args[i].tail_call_reg = FUNCTION_INCOMING_ARG (*args_so_far, mode, type, - argpos < n_named_args); -#else - args[i].tail_call_reg = args[i].reg; -#endif + if (targetm.calls.function_incoming_arg != targetm.calls.function_arg) + args[i].tail_call_reg + = targetm.calls.function_incoming_arg (args_so_far, mode, type, + argpos < n_named_args); + else + args[i].tail_call_reg = args[i].reg; if (args[i].reg) args[i].partial @@ -1192,8 +1193,8 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED, /* Increment ARGS_SO_FAR, which has info about which arg-registers have been used, etc. */ - FUNCTION_ARG_ADVANCE (*args_so_far, TYPE_MODE (type), type, - argpos < n_named_args); + targetm.calls.function_arg_advance (args_so_far, TYPE_MODE (type), + type, argpos < n_named_args); } } @@ -2828,14 +2829,15 @@ expand_call (tree exp, rtx target, int ignore) /* Set up next argument register. For sibling calls on machines with register windows this should be the incoming register. */ -#ifdef FUNCTION_INCOMING_ARG if (pass == 0) - next_arg_reg = FUNCTION_INCOMING_ARG (args_so_far, VOIDmode, - void_type_node, 1); + next_arg_reg = targetm.calls.function_incoming_arg (&args_so_far, + VOIDmode, + void_type_node, + true); else -#endif - next_arg_reg = FUNCTION_ARG (args_so_far, VOIDmode, - void_type_node, 1); + next_arg_reg = targetm.calls.function_arg (&args_so_far, + VOIDmode, void_type_node, + true); /* All arguments and registers used for the call must be set up by now! */ @@ -3422,7 +3424,8 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, argvec[count].mode = Pmode; argvec[count].partial = 0; - argvec[count].reg = FUNCTION_ARG (args_so_far, Pmode, NULL_TREE, 1); + argvec[count].reg = targetm.calls.function_arg (&args_so_far, + Pmode, NULL_TREE, true); gcc_assert (targetm.calls.arg_partial_bytes (&args_so_far, Pmode, NULL_TREE, 1) == 0); @@ -3438,7 +3441,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, || reg_parm_stack_space > 0) args_size.constant += argvec[count].locate.size.constant; - FUNCTION_ARG_ADVANCE (args_so_far, Pmode, (tree) 0, 1); + targetm.calls.function_arg_advance (&args_so_far, Pmode, (tree) 0, true); count++; } @@ -3497,7 +3500,8 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, argvec[count].value = val; argvec[count].mode = mode; - argvec[count].reg = FUNCTION_ARG (args_so_far, mode, NULL_TREE, 1); + argvec[count].reg = targetm.calls.function_arg (&args_so_far, mode, + NULL_TREE, true); argvec[count].partial = targetm.calls.arg_partial_bytes (&args_so_far, mode, NULL_TREE, 1); @@ -3517,7 +3521,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, || reg_parm_stack_space > 0) args_size.constant += argvec[count].locate.size.constant; - FUNCTION_ARG_ADVANCE (args_so_far, mode, (tree) 0, 1); + targetm.calls.function_arg_advance (&args_so_far, mode, (tree) 0, true); } /* If this machine requires an external definition for library @@ -3826,7 +3830,8 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, build_function_type (tfom, NULL_TREE), original_args_size.constant, args_size.constant, struct_value_size, - FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1), + targetm.calls.function_arg (&args_so_far, + VOIDmode, void_type_node, true), valreg, old_inhibit_defer_pop + 1, call_fusage, flags, & args_so_far); diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index f3facb3598f..4a0e3062212 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -180,9 +180,6 @@ extern void ix86_expand_truncdf_32 (rtx, rtx); #ifdef TREE_CODE extern void init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree); -extern rtx function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree, int); -extern void function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, - tree, int); #endif /* TREE_CODE */ #endif /* RTX_CODE */ diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 39308db4332..d94b47f191a 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -6061,9 +6061,13 @@ function_arg_advance_ms_64 (CUMULATIVE_ARGS *cum, HOST_WIDE_INT bytes, } } -void -function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, - tree type, int named) +/* Update the data in CUM to advance over an argument of mode MODE and + data type TYPE. (TYPE is null for libcalls where that information + may not be available.) */ + +static void +ix86_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, + const_tree type, int named) { HOST_WIDE_INT bytes, words; @@ -6298,9 +6302,19 @@ function_arg_ms_64 (CUMULATIVE_ARGS *cum, enum machine_mode mode, return gen_reg_or_parallel (mode, orig_mode, regno); } -rtx -function_arg (CUMULATIVE_ARGS *cum, enum machine_mode omode, - tree type, int named) +/* Return where to put the arguments to a function. + Return zero to push the argument on the stack, or a hard register in which to store the argument. + + MODE is the argument's machine mode. TYPE is the data type of the + argument. It is null for libcalls where that information may not be + available. CUM gives information about the preceding args and about + the function being called. NAMED is nonzero if this argument is a + named parameter (otherwise it is an extra parameter matching an + ellipsis). */ + +static rtx +ix86_function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode omode, + const_tree type, int named) { enum machine_mode mode = omode; HOST_WIDE_INT bytes, words; @@ -30874,6 +30888,10 @@ ix86_enum_va_list (int idx, const char **pname, tree *ptree) #define TARGET_SETUP_INCOMING_VARARGS ix86_setup_incoming_varargs #undef TARGET_MUST_PASS_IN_STACK #define TARGET_MUST_PASS_IN_STACK ix86_must_pass_in_stack +#undef TARGET_FUNCTION_ARG_ADVANCE +#define TARGET_FUNCTION_ARG_ADVANCE ix86_function_arg_advance +#undef TARGET_FUNCTION_ARG +#define TARGET_FUNCTION_ARG ix86_function_arg #undef TARGET_PASS_BY_REFERENCE #define TARGET_PASS_BY_REFERENCE ix86_pass_by_reference #undef TARGET_INTERNAL_ARG_POINTER diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 05adfc5894e..afe05f9f6db 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -1591,29 +1591,6 @@ typedef struct ix86_args { #define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS) \ init_cumulative_args (&(CUM), (FNTYPE), (LIBNAME), (FNDECL)) -/* Update the data in CUM to advance over an argument - of mode MODE and data type TYPE. - (TYPE is null for libcalls where that information may not be available.) */ - -#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \ - function_arg_advance (&(CUM), (MODE), (TYPE), (NAMED)) - -/* Define where to put the arguments to a function. - Value is zero to push the argument on the stack, - or a hard register in which to store the argument. - - MODE is the argument's machine mode. - TYPE is the data type of the argument (as a tree). - This is null for libcalls where that information may - not be available. - CUM is a variable of type CUMULATIVE_ARGS which gives info about - the preceding args and about the function being called. - NAMED is nonzero if this argument is a named parameter - (otherwise it is an extra parameter matching an ellipsis). */ - -#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \ - function_arg (&(CUM), (MODE), (TYPE), (NAMED)) - /* Output assembler code to FILE to increment profiler label # LABELNO for profiling a function entry. */ diff --git a/gcc/dse.c b/gcc/dse.c index 5cb467c934d..98861f11044 100644 --- a/gcc/dse.c +++ b/gcc/dse.c @@ -2326,7 +2326,8 @@ get_call_args (rtx call_insn, tree fn, rtx *args, int nargs) arg = TREE_CHAIN (arg), idx++) { enum machine_mode mode = TYPE_MODE (TREE_VALUE (arg)); - rtx reg = FUNCTION_ARG (args_so_far, mode, NULL_TREE, 1), link, tmp; + rtx reg, link, tmp; + reg = targetm.calls.function_arg (&args_so_far, mode, NULL_TREE, true); if (!reg || !REG_P (reg) || GET_MODE (reg) != mode || GET_MODE_CLASS (mode) != MODE_INT) return false; @@ -2360,7 +2361,7 @@ get_call_args (rtx call_insn, tree fn, rtx *args, int nargs) if (tmp) args[idx] = tmp; - FUNCTION_ARG_ADVANCE (args_so_far, mode, NULL_TREE, 1); + targetm.calls.function_arg_advance (&args_so_far, mode, NULL_TREE, true); } if (arg != void_list_node || idx != nargs) return false; diff --git a/gcc/expr.c b/gcc/expr.c index 4f659872574..2763dc91991 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -1276,12 +1276,14 @@ block_move_libcall_safe_for_call_parm (void) for ( ; arg != void_list_node ; arg = TREE_CHAIN (arg)) { enum machine_mode mode = TYPE_MODE (TREE_VALUE (arg)); - rtx tmp = FUNCTION_ARG (args_so_far, mode, NULL_TREE, 1); + rtx tmp = targetm.calls.function_arg (&args_so_far, mode, + NULL_TREE, true); if (!tmp || !REG_P (tmp)) return false; if (targetm.calls.arg_partial_bytes (&args_so_far, mode, NULL, 1)) return false; - FUNCTION_ARG_ADVANCE (args_so_far, mode, NULL_TREE, 1); + targetm.calls.function_arg_advance (&args_so_far, mode, + NULL_TREE, true); } } return true; diff --git a/gcc/function.c b/gcc/function.c index f58d3d1b4e6..8a03c5ac42c 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -2374,13 +2374,10 @@ assign_parm_find_entry_rtl (struct assign_parm_data_all *all, return; } -#ifdef FUNCTION_INCOMING_ARG - entry_parm = FUNCTION_INCOMING_ARG (all->args_so_far, data->promoted_mode, - data->passed_type, data->named_arg); -#else - entry_parm = FUNCTION_ARG (all->args_so_far, data->promoted_mode, - data->passed_type, data->named_arg); -#endif + entry_parm = targetm.calls.function_incoming_arg (&all->args_so_far, + data->promoted_mode, + data->passed_type, + data->named_arg); if (entry_parm == 0) data->promoted_mode = data->passed_mode; @@ -2404,13 +2401,9 @@ assign_parm_find_entry_rtl (struct assign_parm_data_all *all, if (targetm.calls.pretend_outgoing_varargs_named (&all->args_so_far)) { rtx tem; -#ifdef FUNCTION_INCOMING_ARG - tem = FUNCTION_INCOMING_ARG (all->args_so_far, data->promoted_mode, - data->passed_type, true); -#else - tem = FUNCTION_ARG (all->args_so_far, data->promoted_mode, - data->passed_type, true); -#endif + tem = targetm.calls.function_incoming_arg (&all->args_so_far, + data->promoted_mode, + data->passed_type, true); in_regs = tem != NULL; } } @@ -3275,8 +3268,8 @@ assign_parms (tree fndecl) set_decl_incoming_rtl (parm, data.entry_parm, data.passed_pointer); /* Update info on where next arg arrives in registers. */ - FUNCTION_ARG_ADVANCE (all.args_so_far, data.promoted_mode, - data.passed_type, data.named_arg); + targetm.calls.function_arg_advance (&all.args_so_far, data.promoted_mode, + data.passed_type, data.named_arg); assign_parm_adjust_stack_rtl (&data); @@ -3465,8 +3458,8 @@ gimplify_parameters (void) continue; /* Update info on where next arg arrives in registers. */ - FUNCTION_ARG_ADVANCE (all.args_so_far, data.promoted_mode, - data.passed_type, data.named_arg); + targetm.calls.function_arg_advance (&all.args_so_far, data.promoted_mode, + data.passed_type, data.named_arg); /* ??? Once upon a time variable_size stuffed parameter list SAVE_EXPRs (amongst others) onto a pending sizes list. This diff --git a/gcc/target-def.h b/gcc/target-def.h index 7342ba7715f..a0c2ca60f1a 100644 --- a/gcc/target-def.h +++ b/gcc/target-def.h @@ -712,6 +712,22 @@ #define TARGET_CALLEE_COPIES hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false #define TARGET_ARG_PARTIAL_BYTES hook_int_CUMULATIVE_ARGS_mode_tree_bool_0 +#ifndef TARGET_FUNCTION_ARG_ADVANCE +#define TARGET_FUNCTION_ARG_ADVANCE default_function_arg_advance +#endif + +#ifndef TARGET_FUNCTION_ARG +#define TARGET_FUNCTION_ARG default_function_arg +#endif + +#ifndef TARGET_FUNCTION_INCOMING_ARG +#ifndef FUNCTION_INCOMING_ARG +#define TARGET_FUNCTION_INCOMING_ARG TARGET_FUNCTION_ARG +#else +#define TARGET_FUNCTION_INCOMING_ARG default_function_incoming_arg +#endif +#endif + #define TARGET_FUNCTION_VALUE default_function_value #define TARGET_LIBCALL_VALUE default_libcall_value #define TARGET_FUNCTION_VALUE_REGNO_P default_function_value_regno_p @@ -739,6 +755,9 @@ TARGET_MUST_PASS_IN_STACK, \ TARGET_CALLEE_COPIES, \ TARGET_ARG_PARTIAL_BYTES, \ + TARGET_FUNCTION_ARG_ADVANCE, \ + TARGET_FUNCTION_ARG, \ + TARGET_FUNCTION_INCOMING_ARG, \ TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN, \ TARGET_FUNCTION_VALUE, \ TARGET_LIBCALL_VALUE, \ diff --git a/gcc/target.h b/gcc/target.h index 1d4ab4103f2..6ced77061cf 100644 --- a/gcc/target.h +++ b/gcc/target.h @@ -1020,6 +1020,26 @@ struct gcc_target int (* arg_partial_bytes) (CUMULATIVE_ARGS *ca, enum machine_mode mode, tree type, bool named); + /* Update the state in CA to advance past an argument in the + argument list. The values MODE, TYPE, and NAMED describe that + argument. */ + void (*function_arg_advance) (CUMULATIVE_ARGS *ca, + enum machine_mode mode, const_tree type, + bool named); + + /* Return zero if the argument described by the state of CA should + be placed on a stack, or a hard register in which to store the + argument. The values MODE, TYPE, and NAMED describe that + argument. */ + rtx (*function_arg) (const CUMULATIVE_ARGS *ca, + enum machine_mode mode, const_tree type, bool named); + + /* Likewise, but for machines with register windows. Return the + location where the argument will appear to the callee. */ + rtx (*function_incoming_arg) (const CUMULATIVE_ARGS *ca, + enum machine_mode mode, + const_tree type, bool named); + /* Return the diagnostic message string if function without a prototype is not allowed for this 'val' argument; NULL otherwise. */ const char *(*invalid_arg_for_unprototyped_fn) (const_tree typelist, diff --git a/gcc/targhooks.c b/gcc/targhooks.c index b0ef5c6127e..f2fe0795fbc 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -544,6 +544,49 @@ hook_int_CUMULATIVE_ARGS_mode_tree_bool_0 ( } void +default_function_arg_advance (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, + enum machine_mode mode ATTRIBUTE_UNUSED, + const_tree type ATTRIBUTE_UNUSED, + bool named ATTRIBUTE_UNUSED) +{ +#ifdef FUNCTION_ARG_ADVANCE + CUMULATIVE_ARGS args = *ca; + FUNCTION_ARG_ADVANCE (args, mode, CONST_CAST_TREE (type), named); + *ca = args; +#else + gcc_unreachable (); +#endif +} + +rtx +default_function_arg (const CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, + enum machine_mode mode ATTRIBUTE_UNUSED, + const_tree type ATTRIBUTE_UNUSED, + bool named ATTRIBUTE_UNUSED) +{ +#ifdef FUNCTION_ARG + return FUNCTION_ARG (*(CONST_CAST (CUMULATIVE_ARGS *, ca)), mode, + CONST_CAST_TREE (type), named); +#else + gcc_unreachable (); +#endif +} + +rtx +default_function_incoming_arg (const CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, + enum machine_mode mode ATTRIBUTE_UNUSED, + const_tree type ATTRIBUTE_UNUSED, + bool named ATTRIBUTE_UNUSED) +{ +#ifdef FUNCTION_INCOMING_ARG + return FUNCTION_INCOMING_ARG (*(CONST_CAST (CUMULATIVE_ARGS *, ca)), mode, + CONST_CAST_TREE (type), named); +#else + gcc_unreachable (); +#endif +} + +void hook_void_bitmap (bitmap regs ATTRIBUTE_UNUSED) { } diff --git a/gcc/targhooks.h b/gcc/targhooks.h index e24f85ecede..393b12f1367 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -101,6 +101,12 @@ extern int hook_int_CUMULATIVE_ARGS_mode_tree_bool_0 (CUMULATIVE_ARGS *, enum machine_mode, tree, bool); extern const char *hook_invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree); +extern void default_function_arg_advance + (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool); +extern rtx default_function_arg + (const CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool); +extern rtx default_function_incoming_arg + (const CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool); extern bool hook_bool_const_rtx_commutative_p (const_rtx, int); extern rtx default_function_value (const_tree, const_tree, bool); extern rtx default_libcall_value (enum machine_mode, const_rtx); |