diff options
author | Richard Henderson <rth@redhat.com> | 2009-09-22 08:11:37 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2009-09-22 08:11:37 -0700 |
commit | 531ca746f972a758565b0623288ea24162442248 (patch) | |
tree | 78521a0ca34823fbb38443911cb1b76f4bd93d6c /gcc/builtins.c | |
parent | 2df373c2eb9148f995614d5405f0e4b500de4e0d (diff) | |
download | gcc-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.c | 61 |
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; } |