pa.c (hppa_profile_hook): Split gen_call_profiler into separate insns.

* pa.c (hppa_profile_hook): Split gen_call_profiler into separate
	insns.  Use the regular call expander for the call to the profiler.
	* pa.md (call_profiler): Delete.
	(load_offset_label_address): New insn to load the address of the
	current function for the profiler.
	(lcla1, lcla2): New insns to output a code label and load its address.

Co-Authored-By: John David Anglin <dave.anglin@nrc-cnrc.gc.ca>

From-SVN: r74004
This commit is contained in:
Randolph Chung 2003-11-27 20:02:36 +00:00 committed by John David Anglin
parent a27b9e3c6f
commit a3d4c92f8a
3 changed files with 74 additions and 38 deletions

View File

@ -1,3 +1,13 @@
2003-11-27 Randolph Chung <tausq@debian.org>
John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
* pa.c (hppa_profile_hook): Split gen_call_profiler into separate
insns. Use the regular call expander for the call to the profiler.
* pa.md (call_profiler): Delete.
(load_offset_label_address): New insn to load the address of the
current function for the profiler.
(lcla1, lcla2): New insns to output a code label and load its address.
2003-11-27 Kazu Hirata <kazu@cs.umass.edu>
* final.c (final_scan_insn): Remove commented-out code.

View File

@ -4039,12 +4039,17 @@ hppa_pic_save_rtx (void)
void
hppa_profile_hook (int label_no)
{
/* We use SImode for the address of the function in both 32 and
64-bit code to avoid having to provide DImode versions of the
lcla2 and load_offset_label_address insn patterns. */
rtx reg = gen_reg_rtx (SImode);
rtx label_rtx = gen_label_rtx ();
rtx begin_label_rtx, call_insn;
char begin_label_name[16];
ASM_GENERATE_INTERNAL_LABEL (begin_label_name, FUNC_BEGIN_PROLOG_LABEL,
label_no);
begin_label_rtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (begin_label_name));
begin_label_rtx = gen_rtx_SYMBOL_REF (SImode, ggc_strdup (begin_label_name));
if (TARGET_64BIT)
emit_move_insn (arg_pointer_rtx,
@ -4053,6 +4058,18 @@ hppa_profile_hook (int label_no)
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 a 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));
#ifndef NO_PROFILE_COUNTERS
{
rtx count_label_rtx, addr, r24;
@ -4065,35 +4082,31 @@ hppa_profile_hook (int label_no)
r24 = gen_rtx_REG (Pmode, 24);
emit_move_insn (r24, addr);
/* %r25 is set from within the output pattern. */
call_insn =
emit_call_insn (gen_call_profiler (gen_rtx_SYMBOL_REF (Pmode, "_mcount"),
GEN_INT (TARGET_64BIT ? 24 : 12),
begin_label_rtx));
emit_call_insn (gen_call (gen_rtx_MEM (Pmode,
gen_rtx_SYMBOL_REF (Pmode,
"_mcount")),
GEN_INT (TARGET_64BIT ? 24 : 12)));
use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), r24);
}
#else
/* %r25 is set from within the output pattern. */
call_insn =
emit_call_insn (gen_call_profiler (gen_rtx_SYMBOL_REF (Pmode, "_mcount"),
GEN_INT (TARGET_64BIT ? 16 : 8),
begin_label_rtx));
emit_call_insn (gen_call (gen_rtx_MEM (Pmode,
gen_rtx_SYMBOL_REF (Pmode,
"_mcount")),
GEN_INT (TARGET_64BIT ? 16 : 8)));
#endif
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));
/* Indicate the _mcount call cannot throw, nor will it execute a
non-local goto. */
REG_NOTES (call_insn)
= gen_rtx_EXPR_LIST (REG_EH_REGION, constm1_rtx, REG_NOTES (call_insn));
if (flag_pic)
{
use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
if (TARGET_64BIT)
use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ());
}
}
/* Fetch the return address for the frame COUNT steps up from

View File

@ -6152,35 +6152,48 @@
DONE;
}")
;; Special because we use the value placed in %r2 by the bl instruction
;; from within its delay slot to set the value for the 2nd parameter to
;; the call.
(define_insn "call_profiler"
[(call (mem:SI (match_operand 0 "call_operand_address" ""))
(match_operand 1 "" ""))
(use (match_operand 2 "" ""))
(use (reg:SI 25))
(use (reg:SI 26))
(clobber (reg:SI 2))]
; Used by hppa_profile_hook to load the starting address of the current
; function; operand 1 contains the address of the label in operand 3
(define_insn "load_offset_label_address"
[(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (match_operand:SI 1 "register_operand" "r")
(minus:SI (match_operand:SI 2 "" "")
(label_ref:SI (match_operand 3 "" "")))))]
""
"ldo %2-%l3(%1),%0"
[(set_attr "type" "multi")
(set_attr "length" "4")])
; Output a code label and load its address.
(define_insn "lcla1"
[(set (match_operand:SI 0 "register_operand" "=r")
(label_ref:SI (match_operand 1 "" "")))
(const_int 0)]
"!TARGET_PA_20"
"*
{
rtx xoperands[3];
output_arg_descriptor (insn);
xoperands[0] = operands[0];
xoperands[1] = operands[2];
xoperands[2] = gen_label_rtx ();
output_asm_insn (\"{bl|b,l} %0,%%r2\;ldo %1-%2(%%r2),%%r25\", xoperands);
output_asm_insn (\"bl .+8,%0\;depi 0,31,2,%0\", operands);
(*targetm.asm_out.internal_label) (asm_out_file, \"L\",
CODE_LABEL_NUMBER (xoperands[2]));
CODE_LABEL_NUMBER (operands[1]));
return \"\";
}"
[(set_attr "type" "multi")
(set_attr "length" "8")])
(define_insn "lcla2"
[(set (match_operand:SI 0 "register_operand" "=r")
(label_ref:SI (match_operand 1 "" "")))
(const_int 0)]
"TARGET_PA_20"
"*
{
(*targetm.asm_out.internal_label) (asm_out_file, \"L\",
CODE_LABEL_NUMBER (operands[1]));
return \"mfia %0\";
}"
[(set_attr "type" "move")
(set_attr "length" "4")])
(define_insn "blockage"
[(unspec_volatile [(const_int 2)] 0)]
""