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,
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;
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
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)]
""