aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/config/pa/pa.c49
-rw-r--r--gcc/config/pa/pa.md53
3 files changed, 74 insertions, 38 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ab9c361..4af2b92 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index 8c8aebb..f724c43 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -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
diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md
index aa0bfcb..6f0cdcff 100644
--- a/gcc/config/pa/pa.md
+++ b/gcc/config/pa/pa.md
@@ -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)]
""