diff options
author | John David Anglin <danglin@gcc.gnu.org> | 2016-07-16 15:59:33 +0000 |
---|---|---|
committer | John David Anglin <danglin@gcc.gnu.org> | 2016-07-16 15:59:33 +0000 |
commit | 730a27a251b1f6f8664cb952c2c2fc24d42a426d (patch) | |
tree | 7aa3b83d0344090824f99eab5019a10d7cbd4537 /gcc/config/pa/pa.c | |
parent | a9356b1242b57fc99b2200e6c3d5039c9d4948fe (diff) | |
download | gcc-730a27a251b1f6f8664cb952c2c2fc24d42a426d.zip gcc-730a27a251b1f6f8664cb952c2c2fc24d42a426d.tar.gz gcc-730a27a251b1f6f8664cb952c2c2fc24d42a426d.tar.bz2 |
pa.c (hppa_profile_hook): Allocate stack space for register parameters.
* config/pa/pa.c (hppa_profile_hook): Allocate stack space for
register parameters. Remove code to initialize argument pointer
on TARGET_64BIT. Optimize call to _mcount when it can be reached
using a pc-relative branch. Cleanup conditional code.
* config/pa/pa.md (call_mcount): New expander.
(call_mcount_nonpic): New insn.
(call_mcount_pic): New insn and split.
(call_mcount_pic_post_reload): New insn.
(call_mcount_64bit): New insn and split.
(call_mcount_64bit_post_reload): New insn.
From-SVN: r238414
Diffstat (limited to 'gcc/config/pa/pa.c')
-rw-r--r-- | gcc/config/pa/pa.c | 103 |
1 files changed, 61 insertions, 42 deletions
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index 2b5a579..67aa55b 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -4532,63 +4532,78 @@ hppa_profile_hook (int label_no) lcla2 and load_offset_label_address insn patterns. */ rtx reg = gen_reg_rtx (SImode); rtx_code_label *label_rtx = gen_label_rtx (); - rtx begin_label_rtx; + rtx mcount = gen_rtx_MEM (Pmode, gen_rtx_SYMBOL_REF (Pmode, "_mcount")); + int reg_parm_stack_space = REG_PARM_STACK_SPACE (NULL_TREE); + rtx arg_bytes, begin_label_rtx; rtx_insn *call_insn; char begin_label_name[16]; + bool use_mcount_pcrel_call; + + /* If we can reach _mcount with a pc-relative call, we can optimize + loading the address of the current function. This requires linker + long branch stub support. */ + if (!TARGET_PORTABLE_RUNTIME + && !TARGET_LONG_CALLS + && (TARGET_SOM || flag_function_sections)) + use_mcount_pcrel_call = TRUE; + else + use_mcount_pcrel_call = FALSE; ASM_GENERATE_INTERNAL_LABEL (begin_label_name, FUNC_BEGIN_PROLOG_LABEL, label_no); begin_label_rtx = gen_rtx_SYMBOL_REF (SImode, ggc_strdup (begin_label_name)); - if (TARGET_64BIT) - emit_move_insn (arg_pointer_rtx, - gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx, - GEN_INT (64))); - emit_move_insn (gen_rtx_REG (word_mode, 26), gen_rtx_REG (word_mode, 2)); - /* The address of the function is loaded into %r25 with an instruction- - relative sequence that avoids the use of relocations. The sequence - is split so that the load_offset_label_address instruction can - occupy the delay slot of the call to _mcount. */ - if (TARGET_PA_20) - emit_insn (gen_lcla2 (reg, label_rtx)); - else - emit_insn (gen_lcla1 (reg, label_rtx)); - - emit_insn (gen_load_offset_label_address (gen_rtx_REG (SImode, 25), - reg, begin_label_rtx, label_rtx)); - -#if !NO_DEFERRED_PROFILE_COUNTERS - { - rtx count_label_rtx, addr, r24; - char count_label_name[16]; + if (!use_mcount_pcrel_call) + { + /* The address of the function is loaded into %r25 with an instruction- + relative sequence that avoids the use of relocations. The sequence + is split so that the load_offset_label_address instruction can + occupy the delay slot of the call to _mcount. */ + if (TARGET_PA_20) + emit_insn (gen_lcla2 (reg, label_rtx)); + else + emit_insn (gen_lcla1 (reg, label_rtx)); - funcdef_nos.safe_push (label_no); - ASM_GENERATE_INTERNAL_LABEL (count_label_name, "LP", label_no); - count_label_rtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (count_label_name)); + emit_insn (gen_load_offset_label_address (gen_rtx_REG (SImode, 25), + reg, + begin_label_rtx, + label_rtx)); + } - addr = force_reg (Pmode, count_label_rtx); - r24 = gen_rtx_REG (Pmode, 24); - emit_move_insn (r24, addr); + if (!NO_DEFERRED_PROFILE_COUNTERS) + { + rtx count_label_rtx, addr, r24; + char count_label_name[16]; - call_insn = - emit_call_insn (gen_call (gen_rtx_MEM (Pmode, - gen_rtx_SYMBOL_REF (Pmode, - "_mcount")), - GEN_INT (TARGET_64BIT ? 24 : 12))); + funcdef_nos.safe_push (label_no); + ASM_GENERATE_INTERNAL_LABEL (count_label_name, "LP", label_no); + count_label_rtx = gen_rtx_SYMBOL_REF (Pmode, + ggc_strdup (count_label_name)); - use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), r24); - } -#else + addr = force_reg (Pmode, count_label_rtx); + r24 = gen_rtx_REG (Pmode, 24); + emit_move_insn (r24, addr); - call_insn = - emit_call_insn (gen_call (gen_rtx_MEM (Pmode, - gen_rtx_SYMBOL_REF (Pmode, - "_mcount")), - GEN_INT (TARGET_64BIT ? 16 : 8))); + arg_bytes = GEN_INT (TARGET_64BIT ? 24 : 12); + if (use_mcount_pcrel_call) + call_insn = emit_call_insn (gen_call_mcount (mcount, arg_bytes, + begin_label_rtx)); + else + call_insn = emit_call_insn (gen_call (mcount, arg_bytes)); -#endif + use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), r24); + } + else + { + arg_bytes = GEN_INT (TARGET_64BIT ? 16 : 8); + if (use_mcount_pcrel_call) + call_insn = emit_call_insn (gen_call_mcount (mcount, arg_bytes, + begin_label_rtx)); + else + call_insn = emit_call_insn (gen_call (mcount, arg_bytes)); + } use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), gen_rtx_REG (SImode, 25)); use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), gen_rtx_REG (SImode, 26)); @@ -4596,6 +4611,10 @@ hppa_profile_hook (int label_no) /* Indicate the _mcount call cannot throw, nor will it execute a non-local goto. */ make_reg_eh_region_note_nothrow_nononlocal (call_insn); + + /* Allocate space for fixed arguments. */ + if (reg_parm_stack_space > crtl->outgoing_args_size) + crtl->outgoing_args_size = reg_parm_stack_space; } /* Fetch the return address for the frame COUNT steps up from |