/* Remember where the set_got_placeholder is located. */
rtx_insn *set_got_insn;
+
+ /* Remember where mcount args are stored so we can insert set_got_insn
+ after. */
+ rtx_insn *set_mcount_arg_insn;
};
/* Zero initialization is OK for all current fields. */
EH_RETURN_STACKADJ_RTX));
}
+/* Worker for PROFILE_HOOK.
+ The OpenRISC profile hook uses the link register which will get clobbered by
+ the GOT setup RTX. This sets up a placeholder to allow injecting of the GOT
+ setup RTX to avoid clobbering. */
+
+void
+or1k_profile_hook (void)
+{
+ rtx a1 = gen_rtx_REG (Pmode, 3);
+ rtx ra = get_hard_reg_initial_val (Pmode, LR_REGNUM);
+ rtx fun = gen_rtx_SYMBOL_REF (Pmode, "_mcount");
+
+ /* Keep track of where we setup the _mcount argument so we can insert the
+ GOT setup RTX after it. */
+ cfun->machine->set_mcount_arg_insn = emit_move_insn (a1, ra);
+
+ emit_library_call (fun, LCT_NORMAL, VOIDmode, a1, Pmode);
+}
+
/* Worker for TARGET_INIT_PIC_REG.
Initialize the cfun->machine->set_got_insn rtx and insert it at the entry
of the current function. The rtx is just a temporary placeholder for
static void
or1k_init_pic_reg (void)
{
- start_sequence ();
- cfun->machine->set_got_insn
- = emit_insn (gen_set_got_tmp (pic_offset_table_rtx));
+ if (crtl->profile)
+ cfun->machine->set_got_insn =
+ emit_insn_after (gen_set_got_tmp (pic_offset_table_rtx),
+ cfun->machine->set_mcount_arg_insn);
+ else
+ {
+ start_sequence ();
+
+ cfun->machine->set_got_insn =
+ emit_insn (gen_set_got_tmp (pic_offset_table_rtx));
- rtx_insn *seq = get_insns ();
- end_sequence ();
+ rtx_insn *seq = get_insns ();
+ end_sequence ();
- edge entry_edge = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun));
- insert_insn_on_edge (seq, entry_edge);
- commit_one_edge_insertion (entry_edge);
+ edge entry_edge = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun));
+ insert_insn_on_edge (seq, entry_edge);
+ commit_one_edge_insertion (entry_edge);
+ }
}
#undef TARGET_INIT_PIC_REG
{
/* ??? While IRA checks accesses_prior_frames, reload does not.
We do want the frame pointer for this case. */
- return (crtl->accesses_prior_frames || crtl->profile);
+ return (crtl->accesses_prior_frames);
}
/* Expand the "eh_return" pattern.
/* Emit rtl for profiling. Output assembler code to call "_mcount" for
profiling a function entry. */
-#define PROFILE_HOOK(LABEL) \
- { \
- rtx fun, ra; \
- ra = get_hard_reg_initial_val (Pmode, LR_REGNUM); \
- fun = gen_rtx_SYMBOL_REF (Pmode, "_mcount"); \
- emit_library_call (fun, LCT_NORMAL, VOIDmode, ra, Pmode); \
- }
+#define PROFILE_HOOK(LABEL) or1k_profile_hook()
/* All the work is done in PROFILE_HOOK, but this is still required. */
#define FUNCTION_PROFILER(STREAM, LABELNO) do { } while (0)