aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/pa/pa.c
diff options
context:
space:
mode:
authorJohn David Anglin <danglin@gcc.gnu.org>2016-07-16 15:59:33 +0000
committerJohn David Anglin <danglin@gcc.gnu.org>2016-07-16 15:59:33 +0000
commit730a27a251b1f6f8664cb952c2c2fc24d42a426d (patch)
tree7aa3b83d0344090824f99eab5019a10d7cbd4537 /gcc/config/pa/pa.c
parenta9356b1242b57fc99b2200e6c3d5039c9d4948fe (diff)
downloadgcc-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.c103
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