aboutsummaryrefslogtreecommitdiff
path: root/gcc/builtins.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2009-09-22 08:11:37 -0700
committerRichard Henderson <rth@gcc.gnu.org>2009-09-22 08:11:37 -0700
commit531ca746f972a758565b0623288ea24162442248 (patch)
tree78521a0ca34823fbb38443911cb1b76f4bd93d6c /gcc/builtins.c
parent2df373c2eb9148f995614d5405f0e4b500de4e0d (diff)
downloadgcc-531ca746f972a758565b0623288ea24162442248.zip
gcc-531ca746f972a758565b0623288ea24162442248.tar.gz
gcc-531ca746f972a758565b0623288ea24162442248.tar.bz2
re PR target/41246 (should "sorry" when regparm=3 and nested functions are encountered)
PR target/41246 * target.h (struct gcc_target): Add asm_out.trampoline_template, calls.static_chain, calls.trampoline_init, calls.trampoline_adjust_address. * target-def.h (TARGET_ASM_TRAMPOLINE_TEMPLATE): New. (TARGET_STATIC_CHAIN, TARGET_TRAMPOLINE_INIT): New. (TARGET_TRAMPOLINE_ADJUST_ADDRESS): New. * builtins.c (expand_builtin_setjmp_receiver): Use targetm.calls.static_chain; only clobber registers. (expand_builtin_init_trampoline): Use targetm.calls.trampoline_init; set up memory attributes properly for the trampoline block. (expand_builtin_adjust_trampoline): Use targetm.calls.trampoline_adjust_address. * calls.c (prepare_call_address): Add fndecl argument. Use targetm.calls.static_chain. * df-scan.c (df_need_static_chain_reg): Remove. (df_get_entry_block_def_set): Use targetm.calls.static_chain; consolodate static chain handling. * doc/tm.texi: Document new hooks. * emit-rtl.c (static_chain_rtx, static_chain_incoming_rtx): Remove. (init_emit_regs): Don't initialize them. * expr.h (prepare_call_address): Update decl. * final.c (profile_function): Use targetm.calls.static_chain. * function.c (expand_function_start): Likewise. * rtl.h (static_chain_rtx, static_chain_incoming_rtx): Remove. * stmt.c (expand_nl_goto_receiver): Use targetm.calls.static_chain; only clobber registers. * targhooks.c (default_static_chain): New. (default_asm_trampoline_template, default_trampoline_init): New. (default_trampoline_adjust_address): New. * targhooks.h: Declare them. * varasm.c (assemble_trampoline_template): Use targetm.asm_out.trampoline_template. Make the memory block const and set its size. From-SVN: r151983
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r--gcc/builtins.c61
1 files changed, 37 insertions, 24 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c
index fddb36c..7227481 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -755,13 +755,17 @@ expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
void
expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
{
+ rtx chain;
+
/* Clobber the FP when we get here, so we have to make sure it's
marked as used by this function. */
emit_use (hard_frame_pointer_rtx);
/* Mark the static chain as clobbered here so life information
doesn't get messed up for it. */
- emit_clobber (static_chain_rtx);
+ chain = targetm.calls.static_chain (current_function_decl, true);
+ if (chain && REG_P (chain))
+ emit_clobber (chain);
/* Now put in the code to restore the frame pointer, and argument
pointer, if needed. */
@@ -839,11 +843,8 @@ expand_builtin_longjmp (rtx buf_addr, rtx value)
buf_addr = force_reg (Pmode, buf_addr);
- /* We used to store value in static_chain_rtx, but that fails if pointers
- are smaller than integers. We instead require that the user must pass
- a second argument of 1, because that is what builtin_setjmp will
- return. This also makes EH slightly more efficient, since we are no
- longer copying around a value that we don't care about. */
+ /* We require that the user must pass a second argument of 1, because
+ that is what builtin_setjmp will return. */
gcc_assert (value == const1_rtx);
last = get_last_insn ();
@@ -1590,7 +1591,7 @@ expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
}
/* All arguments and registers used for the call are set up by now! */
- function = prepare_call_address (function, NULL, &call_fusage, 0, 0);
+ function = prepare_call_address (NULL, function, NULL, &call_fusage, 0, 0);
/* Ensure address is valid. SYMBOL_REF is already valid, so no need,
and we don't want to load it into a register as an optimization,
@@ -5815,10 +5816,7 @@ static rtx
expand_builtin_init_trampoline (tree exp)
{
tree t_tramp, t_func, t_chain;
- rtx r_tramp, r_func, r_chain;
-#ifdef TRAMPOLINE_TEMPLATE
- rtx blktramp;
-#endif
+ rtx m_tramp, r_tramp, r_chain, tmp;
if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE,
POINTER_TYPE, VOID_TYPE))
@@ -5829,20 +5827,36 @@ expand_builtin_init_trampoline (tree exp)
t_chain = CALL_EXPR_ARG (exp, 2);
r_tramp = expand_normal (t_tramp);
- r_func = expand_normal (t_func);
+ m_tramp = gen_rtx_MEM (BLKmode, r_tramp);
+ MEM_NOTRAP_P (m_tramp) = 1;
+
+ /* The TRAMP argument should be the address of a field within the
+ local function's FRAME decl. Let's see if we can fill in the
+ to fill in the MEM_ATTRs for this memory. */
+ if (TREE_CODE (t_tramp) == ADDR_EXPR)
+ set_mem_attributes_minus_bitpos (m_tramp, TREE_OPERAND (t_tramp, 0),
+ true, 0);
+
+ tmp = round_trampoline_addr (r_tramp);
+ if (tmp != r_tramp)
+ {
+ m_tramp = change_address (m_tramp, BLKmode, tmp);
+ set_mem_align (m_tramp, TRAMPOLINE_ALIGNMENT);
+ set_mem_size (m_tramp, GEN_INT (TRAMPOLINE_SIZE));
+ }
+
+ /* The FUNC argument should be the address of the nested function.
+ Extract the actual function decl to pass to the hook. */
+ gcc_assert (TREE_CODE (t_func) == ADDR_EXPR);
+ t_func = TREE_OPERAND (t_func, 0);
+ gcc_assert (TREE_CODE (t_func) == FUNCTION_DECL);
+
r_chain = expand_normal (t_chain);
/* Generate insns to initialize the trampoline. */
- r_tramp = round_trampoline_addr (r_tramp);
-#ifdef TRAMPOLINE_TEMPLATE
- blktramp = gen_rtx_MEM (BLKmode, r_tramp);
- set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
- emit_block_move (blktramp, assemble_trampoline_template (),
- GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
-#endif
- trampolines_created = 1;
- INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
+ targetm.calls.trampoline_init (m_tramp, t_func, r_chain);
+ trampolines_created = 1;
return const0_rtx;
}
@@ -5856,9 +5870,8 @@ expand_builtin_adjust_trampoline (tree exp)
tramp = expand_normal (CALL_EXPR_ARG (exp, 0));
tramp = round_trampoline_addr (tramp);
-#ifdef TRAMPOLINE_ADJUST_ADDRESS
- TRAMPOLINE_ADJUST_ADDRESS (tramp);
-#endif
+ if (targetm.calls.trampoline_adjust_address)
+ tramp = targetm.calls.trampoline_adjust_address (tramp);
return tramp;
}