Functions |
static void | emit_call_1 (rtx, tree, tree, tree, HOST_WIDE_INT, HOST_WIDE_INT, HOST_WIDE_INT, rtx, rtx, int, rtx, int, cumulative_args_t) |
static void | precompute_register_parameters (int, struct arg_data *, int *) |
static int | store_one_arg (struct arg_data *, rtx, int, int, int) |
static void | store_unaligned_arguments_into_pseudos (struct arg_data *, int) |
static int | finalize_must_preallocate (int, int, struct arg_data *, struct args_size *) |
static void | precompute_arguments (int, struct arg_data *) |
static int | compute_argument_block_size (int, struct args_size *, tree, tree, int) |
static void | initialize_argument_information (int, struct arg_data *, struct args_size *, int, tree, tree, tree, tree, cumulative_args_t, int, rtx *, int *, int *, int *, bool *, bool) |
static void | compute_argument_addresses (struct arg_data *, rtx, int) |
static rtx | rtx_for_function_call (tree, tree) |
static void | load_register_parameters (struct arg_data *, int, rtx *, int, int, int *) |
static rtx | emit_library_call_value_1 (int, rtx, rtx, enum libcall_type, enum machine_mode, int, va_list) |
static int | special_function_p (const_tree, int) |
static int | check_sibcall_argument_overlap_1 (rtx) |
static int | check_sibcall_argument_overlap (rtx, struct arg_data *, int) |
static int | combine_pending_stack_adjustment_and_call (int, struct args_size *, unsigned int) |
static tree | split_complex_types (tree) |
static rtx | save_fixed_argument_area (int, rtx, int *, int *) |
static void | restore_fixed_argument_area (rtx, rtx, int, int) |
rtx | prepare_call_address (tree fndecl, rtx funexp, rtx static_chain_value, rtx *call_fusage, int reg_parm_seen, int sibcallp) |
static int | special_function_p () |
static int | decl_return_flags () |
int | setjmp_call_p () |
bool | gimple_alloca_call_p () |
bool | alloca_call_p () |
static bool | is_tm_builtin () |
int | flags_from_decl_or_type () |
int | call_expr_flags () |
static rtx | save_fixed_argument_area () |
static void | restore_fixed_argument_area () |
static void | store_unaligned_arguments_into_pseudos () |
static void | precompute_arguments () |
static void | compute_argument_addresses () |
static rtx | rtx_for_function_call () |
static rtx | internal_arg_pointer_based_exp (rtx, bool) |
static void | internal_arg_pointer_based_exp_scan () |
static int | internal_arg_pointer_based_exp_1 () |
static rtx | internal_arg_pointer_based_exp () |
static bool | mem_overlaps_already_clobbered_arg_p () |
static int | check_sibcall_argument_overlap_1 () |
static int | check_sibcall_argument_overlap () |
bool | shift_return_value () |
static rtx | avoid_likely_spilled_reg () |
rtx | expand_call () |
void | fixup_tail_calls () |
static tree | split_complex_types () |
void | emit_library_call (rtx orgfun, enum libcall_type fn_type, enum machine_mode outmode, int nargs,...) |
rtx | emit_library_call_value (rtx orgfun, rtx value, enum libcall_type fn_type, enum machine_mode outmode, int nargs,...) |
bool | must_pass_in_stack_var_size (enum machine_mode mode, const_tree type) |
bool | must_pass_in_stack_var_size_or_pad () |
static int combine_pending_stack_adjustment_and_call |
( |
int |
unadjusted_args_size, |
|
|
struct args_size * |
args_size, |
|
|
unsigned int |
preferred_unit_stack_boundary |
|
) |
| |
|
static |
We need to pop PENDING_STACK_ADJUST bytes. But, if the arguments
wouldn't fill up an even multiple of PREFERRED_UNIT_STACK_BOUNDARY
bytes, then we would need to push some additional bytes to pad the
arguments. So, we compute an adjust to the stack pointer for an
amount that will leave the stack under-aligned by UNADJUSTED_ARGS_SIZE
bytes. Then, when the arguments are pushed the stack will be perfectly
aligned. ARGS_SIZE->CONSTANT is set to the number of bytes that should
be popped after the call. Returns the adjustment.
References args_size::constant, and HOST_WIDE_INT.
Referenced by expand_call().
static void emit_call_1 |
( |
rtx |
funexp, |
|
|
tree |
fntree, |
|
|
tree |
fndecl, |
|
|
tree |
funtype, |
|
|
HOST_WIDE_INT |
stack_size, |
|
|
HOST_WIDE_INT |
rounded_stack_size, |
|
|
HOST_WIDE_INT |
struct_value_size, |
|
|
rtx |
next_arg_reg, |
|
|
rtx |
valreg, |
|
|
int |
old_inhibit_defer_pop, |
|
|
rtx |
call_fusage, |
|
|
int |
ecf_flags, |
|
|
cumulative_args_t |
args_so_far |
|
) |
| |
|
static |
Generate instructions to call function FUNEXP,
and optionally pop the results.
The CALL_INSN is the first insn generated.
FNDECL is the declaration node of the function. This is given to the
hook TARGET_RETURN_POPS_ARGS to determine whether this function pops
its own args.
FUNTYPE is the data type of the function. This is given to the hook
TARGET_RETURN_POPS_ARGS to determine whether this function pops its
own args. We used to allow an identifier for library functions, but
that doesn't work when the return type is an aggregate type and the
calling convention says that the pointer to this aggregate is to be
popped by the callee.
STACK_SIZE is the number of bytes of arguments on the stack,
ROUNDED_STACK_SIZE is that number rounded up to
PREFERRED_STACK_BOUNDARY; zero if the size is variable. This is
both to put into the call insn and to generate explicit popping
code if necessary.
STRUCT_VALUE_SIZE is the number of bytes wanted in a structure value.
It is zero if this call doesn't want a structure value.
NEXT_ARG_REG is the rtx that results from executing
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,
or 0 if all the arg-registers are used in this call.
It is passed on to `gen_call' so you can put this info in the call insn.
VALREG is a hard register in which a value is returned,
or 0 if the call does not return a value.
OLD_INHIBIT_DEFER_POP is the value that `inhibit_defer_pop' had before
the args to this call were processed.
We restore `inhibit_defer_pop' to that value.
CALL_FUSAGE is either empty or an EXPR_LIST of USE expressions that
denote registers used by the called function.
References add_function_usage_to(), add_reg_note(), adjust_stack(), anti_adjust_stack(), BUILT_IN_NORMAL, builtin_decl_explicit(), function::calls_setjmp, cfun, emit_call_insn(), gen_rtx_MEM(), get_call_rtx_from(), get_cumulative_args(), HOST_WIDE_INT, last_call_insn(), make_reg_eh_region_note(), set_mem_expr(), and targetm.
Referenced by emit_library_call_value_1(), and expand_call().
void emit_library_call |
( |
rtx |
orgfun, |
|
|
enum libcall_type |
fn_type, |
|
|
enum machine_mode |
outmode, |
|
|
int |
nargs, |
|
|
|
... |
|
) |
| |
Output a library call to function FUN (a SYMBOL_REF rtx)
(emitting the queue unless NO_QUEUE is nonzero),
for a value of mode OUTMODE,
with NARGS different arguments, passed as alternating rtx values
and machine_modes to convert them to.
FN_TYPE should be LCT_NORMAL for `normal' calls, LCT_CONST for
`const' calls, LCT_PURE for `pure' calls, or other LCT_ value for
other types of library calls.
References emit_library_call_value_1().
Referenced by expand_assignment(), expand_builtin_trap(), expand_main_function(), expand_mem_thread_fence(), probe_stack_range(), sjlj_emit_function_enter(), and sjlj_emit_function_exit().
rtx emit_library_call_value |
( |
rtx |
orgfun, |
|
|
rtx |
value, |
|
|
enum libcall_type |
fn_type, |
|
|
enum machine_mode |
outmode, |
|
|
int |
nargs, |
|
|
|
... |
|
) |
| |
Like emit_library_call except that an extra argument, VALUE,
comes second and says where to store the result.
(If VALUE is zero, this function chooses a convenient way
to return the value.
This function returns an rtx for where the value is to be found.
If VALUE is nonzero, VALUE is returned.
References emit_library_call_value_1().
Referenced by allocate_dynamic_stack_space(), convert_move(), expand_atomic_compare_and_swap(), expand_atomic_fetch_op(), expand_binop(), expand_builtin_memcmp(), expand_builtin_powi(), expand_fix(), expand_fixed_convert(), expand_float(), expand_twoval_binop_libfunc(), expand_unop(), maybe_emit_sync_lock_test_and_set(), prepare_cmp_insn(), prepare_float_lib_cmp(), and sjlj_emit_function_enter().
static rtx emit_library_call_value_1 |
( |
int |
retval, |
|
|
rtx |
orgfun, |
|
|
rtx |
value, |
|
|
enum libcall_type |
fn_type, |
|
|
enum machine_mode |
outmode, |
|
|
int |
nargs, |
|
|
va_list |
p |
|
) |
| |
|
static |
Output a library call to function FUN (a SYMBOL_REF rtx).
The RETVAL parameter specifies whether return value needs to be saved, other
parameters are documented in the emit_library_call function below.
References aggregate_value_p(), anti_adjust_stack(), assemble_external_libcall(), assign_stack_temp(), assign_temp(), BLOCK_OP_CALL_PARM, build_function_type(), build_pointer_type(), args_size::constant, convert_modes(), count, downward, emit_barrier_after(), emit_block_move(), emit_call_1(), emit_group_load(), emit_group_store(), emit_move_insn(), emit_push_insn(), expand_shift(), force_operand(), force_reg(), free(), gen_reg_rtx(), gen_rtx_MEM(), gen_rtx_REG(), get_identifier(), get_last_insn(), hard_function_value(), hard_libcall_value(), highest_outgoing_arg_in_use, last, LCT_CONST, LCT_NORETURN, LCT_NORMAL, LCT_PURE, LCT_RETURNS_TWICE, LCT_THROW, locate_and_pad_parm(), make_reg_eh_region_note_nothrow_nononlocal(), mark_addressable(), memcpy(), memset(), mode_for_size(), pack_cumulative_args(), pass_by_reference(), plus_constant(), pop_temp_slots(), prepare_call_address(), promote_function_mode(), push_block(), push_temp_slots(), reference_callee_copied(), restore_fixed_argument_area(), save_fixed_argument_area(), shift, shift_return_value(), stack_usage_map, targetm, lang_hooks_for_types::type_for_mode, lang_hooks::types, upward, use_group_regs(), use_reg(), use_regs(), validize_mem(), args_size::var, virtuals_instantiated, and word_mode.
Referenced by emit_library_call(), and emit_library_call_value().
Generate all the code for a CALL_EXPR exp
and return an rtx for its value.
Store the value in TARGET (specified as an rtx) if convenient.
If the value is stored in TARGET then TARGET is returned.
If IGNORE is nonzero, then we ignore the value of the function call.
References add_reg_note(), aggregate_value_p(), arg_data::aligned_regs, allocate_dynamic_stack_space(), anti_adjust_stack(), assign_temp(), avoid_likely_spilled_reg(), bitmap_clear(), BLOCK_OP_CALL_PARM, build_pointer_type(), function::calls_alloca, cfun, cgraph_rtl_info(), check_sibcall_argument_overlap(), combine_pending_stack_adjustment_and_call(), compute_argument_addresses(), compute_argument_block_size(), args_size::constant, copy_addr_to_reg(), copy_to_reg(), current_function_decl, dbg_cnt(), decl_function_context(), decl_return_flags(), lang_hooks::decls, do_pending_stack_adjust(), emit_barrier_after(), emit_block_move(), emit_call_1(), emit_group_move(), emit_group_move_into_temps(), emit_group_store(), emit_insn(), emit_move_insn(), emit_stack_restore(), emit_stack_save(), end_sequence(), expand_expr(), EXPAND_NORMAL, expand_normal(), finalize_must_preallocate(), fixup_args_size_notes(), flags_from_decl_or_type(), force_operand(), force_reg(), free(), gen_reg_rtx(), gen_rtx_MEM(), gen_rtx_REG(), gen_rtx_SUBREG(), get_callee_fndecl(), get_insns(), get_last_insn(), hard_function_value(), HAVE_sibcall_epilogue, highest_outgoing_arg_in_use, HOST_WIDE_INT, initialize_argument_information(), int_size_in_bytes(), internal_arg_pointer_exp_state, last, list_length(), load_register_parameters(), make_tree(), mark_reg_pointer(), memcpy(), memset(), function::nonlocal_goto_save_area, offset, lang_hooks_for_decls::ok_for_sibcall, pack_cumulative_args(), plus_constant(), precompute_arguments(), precompute_register_parameters(), cgraph_rtl_info::preferred_incoming_stack_boundary, prepare_call_address(), promote_function_mode(), push_block(), reg_mentioned_p(), restore_fixed_argument_area(), rtx_equal_p(), rtx_for_function_call(), SAVE_BLOCK, save_fixed_argument_area(), sbitmap_alloc(), sbitmap_free(), set_mem_attributes(), shift_return_value(), split_complex_types(), arg_data::stack, stack, stack_arg_under_construction, stack_protect_epilogue(), stack_usage_map, start_sequence(), store_one_arg(), store_unaligned_arguments_into_pseudos(), targetm, update_nonlocal_goto_save_area(), use_reg(), arg_data::value, args_size::var, and warning().
Referenced by expand_builtin(), expand_builtin_atomic_fetch_op(), expand_builtin_fork_or_exec(), expand_builtin_int_roundingfn_2(), expand_builtin_mathfn(), expand_builtin_mathfn_2(), expand_builtin_mathfn_3(), expand_builtin_mathfn_ternary(), expand_builtin_memset_args(), expand_builtin_strcmp(), expand_builtin_strncmp(), expand_errno_check(), expand_expr_real_1(), and stack_protect_epilogue().
void fixup_tail_calls |
( |
void |
| ) |
|
A sibling call sequence invalidates any REG_EQUIV notes made for
this function's incoming arguments.
At the start of RTL generation we know the only REG_EQUIV notes
in the rtl chain are those for incoming arguments, so we can look
for REG_EQUIV notes between the start of the function and the
NOTE_INSN_FUNCTION_BEG.
This is (slight) overkill. We could keep track of the highest
argument we clobber and be more selective in removing notes, but it
does not seem to be worth the effort.
References find_reg_note(), get_insns(), and remove_note().
Referenced by expand_stack_alignment(), and gimple_expand_cfg().
static void initialize_argument_information |
( |
int |
num_actuals, |
|
|
struct arg_data * |
args, |
|
|
struct args_size * |
args_size, |
|
|
int |
n_named_args, |
|
|
tree |
exp, |
|
|
tree |
struct_value_addr_value, |
|
|
tree |
fndecl, |
|
|
tree |
fntype, |
|
|
cumulative_args_t |
args_so_far, |
|
|
int |
reg_parm_stack_space, |
|
|
rtx * |
old_stack_level, |
|
|
int * |
old_pending_adj, |
|
|
int * |
must_preallocate, |
|
|
int * |
ecf_flags, |
|
|
bool * |
may_tailcall, |
|
|
bool |
call_from_thunk_p |
|
) |
| |
|
static |
Fill in ARGS_SIZE and ARGS array based on the parameters found in
CALL_EXPR EXP.
NUM_ACTUALS is the total number of parameters.
N_NAMED_ARGS is the total number of named arguments.
STRUCT_VALUE_ADDR_VALUE is the implicit argument for a struct return
value, or null.
FNDECL is the tree code for the target of this call (if known)
ARGS_SO_FAR holds state needed by the target to know where to place
the next argument.
REG_PARM_STACK_SPACE is the number of bytes of stack space reserved
for arguments which are passed in registers.
OLD_STACK_LEVEL is a pointer to an rtx which olds the old stack level
and may be modified by this routine.
OLD_PENDING_ADJ, MUST_PREALLOCATE and FLAGS are pointers to integer
flags which may may be modified by this routine.
MAY_TAILCALL is cleared if we encounter an invisible pass-by-reference
that requires allocation of stack space.
CALL_FROM_THUNK_P is true if this call is the jump from a thunk to
the thunked-to function.
References allocate_dynamic_stack_space(), assign_temp(), build_fold_addr_expr_loc(), compare_tree_int(), args_size::constant, copy(), emit_stack_save(), expr_size(), first_field(), gen_rtx_MEM(), GENERIC_STACK_CHECK, get_base_address(), get_cumulative_args(), int_size_in_bytes(), arg_data::locate, locate_and_pad_parm(), make_tree(), mark_addressable(), arg_data::mode, arg_data::partial, pass_by_reference(), arg_data::pass_on_stack, promote_function_mode(), reference_callee_copied(), arg_data::reg, SAVE_BLOCK, set_mem_attributes(), locate_and_pad_arg_data::size, store_expr(), arg_data::tail_call_reg, targetm, arg_data::tree_value, arg_data::unsignedp, args_size::var, and locate_and_pad_arg_data::where_pad.
Referenced by expand_call().
static void internal_arg_pointer_based_exp_scan |
( |
| ) |
|
|
static |
static void load_register_parameters |
( |
struct arg_data * |
args, |
|
|
int |
num_actuals, |
|
|
rtx * |
call_fusage, |
|
|
int |
flags, |
|
|
int |
is_sibcall, |
|
|
int * |
sibcall_failure |
|
) |
| |
|
static |
Do the register loads required for any wholly-register parms or any
parms which are passed both on the stack and in a register. Their
expressions were already evaluated.
Mark all register-parms as living through the call, putting these USE
insns in the CALL_INSN_FUNCTION_USAGE field.
When IS_SIBCALL, perform the check_sibcall_argument_overlap
checking, setting *SIBCALL_FAILURE if appropriate.
References check_sibcall_argument_overlap(), downward, emit_group_move(), emit_move_insn(), expand_shift(), gen_reg_rtx(), gen_rtx_REG(), get_last_insn(), int_size_in_bytes(), mem_overlaps_already_clobbered_arg_p(), move_block_to_reg(), arg_data::n_aligned_regs, operand_subword_force(), arg_data::partial, shift, locate_and_pad_arg_data::size, upward, use_group_regs(), use_reg_mode(), use_regs(), validize_mem(), and word_mode.
Referenced by expand_call().
static void precompute_register_parameters |
( |
int |
num_actuals, |
|
|
struct arg_data * |
args, |
|
|
int * |
reg_parm_seen |
|
) |
| |
|
static |
Precompute all register parameters as described by ARGS, storing values
into fields within the ARGS array.
NUM_ACTUALS indicates the total number elements in the ARGS array.
Set REG_PARM_SEEN if we encounter a register parameter.
References convert_modes(), copy_to_mode_reg(), emit_group_load_into_temps(), expand_normal(), force_reg(), int_size_in_bytes(), arg_data::mode, optimize_insn_for_speed_p(), arg_data::parallel_value, pop_temp_slots(), preserve_temp_slots(), push_temp_slots(), set_src_cost(), targetm, and arg_data::value.
Referenced by expand_call().
rtx prepare_call_address |
( |
tree |
fndecl, |
|
|
rtx |
funexp, |
|
|
rtx |
static_chain_value, |
|
|
rtx * |
call_fusage, |
|
|
int |
reg_parm_seen, |
|
|
int |
sibcallp |
|
) |
| |
static int store_one_arg |
( |
struct arg_data * |
arg, |
|
|
rtx |
argblock, |
|
|
int |
flags, |
|
|
int |
variable_size, |
|
|
int |
reg_parm_stack_space |
|
) |
| |
|
static |
Store a single argument for a function call
into the register or memory area where it must be passed.
*ARG describes the argument value and where to pass it.
ARGBLOCK is the address of the stack-block for all the arguments,
or 0 on a machine where arguments are pushed individually.
MAY_BE_ALLOCA nonzero says this could be a call to `alloca'
so must be careful about how the stack is used.
VARIABLE_SIZE nonzero says that this was a variable-sized outgoing
argument stack. This is used if ACCUMULATE_OUTGOING_ARGS to indicate
that we need not worry about saving and restoring the stack.
FNDECL is the declaration of the function we are calling.
Return nonzero if this arg should cause sibcall failure,
zero otherwise.
References locate_and_pad_arg_data::alignment_pad, assign_temp(), BLOCK_OP_CALL_PARM, locate_and_pad_arg_data::boundary, build_qualified_type(), args_size::constant, convert_modes(), do_pending_stack_adjust(), downward, emit_block_move(), emit_group_load_into_temps(), emit_move_insn(), emit_push_insn(), expand_expr(), EXPAND_NORMAL, EXPAND_STACK_PARM, gen_reg_rtx(), gen_rtx_MEM(), int_size_in_bytes(), arg_data::locate, mem_overlaps_already_clobbered_arg_p(), arg_data::mode, mode_for_size(), arg_data::n_aligned_regs, none, locate_and_pad_arg_data::offset, arg_data::parallel_value, arg_data::partial, arg_data::pass_on_stack, pop_temp_slots(), preserve_temp_slots(), push_temp_slots(), arg_data::reg, arg_data::save_area, locate_and_pad_arg_data::size, size_in_bytes(), arg_data::stack, stack_arg_under_construction, arg_data::stack_slot, stack_usage_map, arg_data::tail_call_reg, arg_data::tree_value, TYPE_QUAL_CONST, arg_data::unsignedp, validize_mem(), arg_data::value, args_size::var, and variable_size().
Referenced by expand_call().
static void store_unaligned_arguments_into_pseudos |
( |
| ) |
|
|
static |
If any elements in ARGS refer to parameters that are to be passed in
registers, but not in memory, and whose alignment does not permit a
direct copy into registers. Copy the values into a group of pseudos
which we will later copy into the appropriate hard registers.
Pseudos for each unaligned argument will be stored into the array
args[argnum].aligned_regs. The caller is responsible for deallocating
the aligned_regs array if it is nonzero.
References arg_data::aligned_regs, downward, emit_move_insn(), extract_bit_field(), gen_reg_rtx(), int_size_in_bytes(), arg_data::n_aligned_regs, operand_subword_force(), arg_data::partial, store_bit_field(), and word_mode.