emit_move_insn (mem, fnaddr);
}
+static void
+output_asm_nops (const char *user, int hw)
+{
+ asm_fprintf (asm_out_file, "\t# NOPs for %s (%d halfwords)\n", user, hw);
+ while (hw > 0)
+ {
+ if (TARGET_CPU_ZARCH && hw >= 3)
+ {
+ output_asm_insn ("brcl\t0,0", NULL);
+ hw -= 3;
+ }
+ else if (hw >= 2)
+ {
+ output_asm_insn ("bc\t0,0", NULL);
+ hw -= 2;
+ }
+ else
+ {
+ output_asm_insn ("bcr\t0,0", NULL);
+ hw -= 1;
+ }
+ }
+}
+
/* Output assembler code to FILE to increment profiler label # LABELNO
for profiling a function entry. */
if (flag_fentry)
{
- if (cfun->static_chain_decl)
+ if (flag_nop_mcount)
+ output_asm_nops ("-mnop-mcount", /* brasl */ 3);
+ else if (cfun->static_chain_decl)
warning (OPT_Wcannot_profile, "nested functions cannot be profiled "
"with -mfentry on s390");
else
}
else if (TARGET_64BIT)
{
- output_asm_insn ("stg\t%0,%1", op);
- output_asm_insn ("larl\t%2,%3", op);
- output_asm_insn ("brasl\t%0,%4", op);
- output_asm_insn ("lg\t%0,%1", op);
+ if (flag_nop_mcount)
+ output_asm_nops ("-mnop-mcount", /* stg */ 3 + /* larl */ 3 +
+ /* brasl */ 3 + /* lg */ 3);
+ else
+ {
+ output_asm_insn ("stg\t%0,%1", op);
+ output_asm_insn ("larl\t%2,%3", op);
+ output_asm_insn ("brasl\t%0,%4", op);
+ output_asm_insn ("lg\t%0,%1", op);
+ }
}
else if (TARGET_CPU_ZARCH)
{
- output_asm_insn ("st\t%0,%1", op);
- output_asm_insn ("larl\t%2,%3", op);
- output_asm_insn ("brasl\t%0,%4", op);
- output_asm_insn ("l\t%0,%1", op);
+ if (flag_nop_mcount)
+ output_asm_nops ("-mnop-mcount", /* st */ 2 + /* larl */ 3 +
+ /* brasl */ 3 + /* l */ 2);
+ else
+ {
+ output_asm_insn ("st\t%0,%1", op);
+ output_asm_insn ("larl\t%2,%3", op);
+ output_asm_insn ("brasl\t%0,%4", op);
+ output_asm_insn ("l\t%0,%1", op);
+ }
}
else if (!flag_pic)
{
op[6] = gen_label_rtx ();
- output_asm_insn ("st\t%0,%1", op);
- output_asm_insn ("bras\t%2,%l6", op);
- output_asm_insn (".long\t%4", op);
- output_asm_insn (".long\t%3", op);
- targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[6]));
- output_asm_insn ("l\t%0,0(%2)", op);
- output_asm_insn ("l\t%2,4(%2)", op);
- output_asm_insn ("basr\t%0,%0", op);
- output_asm_insn ("l\t%0,%1", op);
+ if (flag_nop_mcount)
+ output_asm_nops ("-mnop-mcount", /* st */ 2 + /* bras */ 2 +
+ /* .long */ 2 + /* .long */ 2 + /* l */ 2 +
+ /* l */ 2 + /* basr */ 1 + /* l */ 2);
+ else
+ {
+ output_asm_insn ("st\t%0,%1", op);
+ output_asm_insn ("bras\t%2,%l6", op);
+ output_asm_insn (".long\t%4", op);
+ output_asm_insn (".long\t%3", op);
+ targetm.asm_out.internal_label (file, "L",
+ CODE_LABEL_NUMBER (op[6]));
+ output_asm_insn ("l\t%0,0(%2)", op);
+ output_asm_insn ("l\t%2,4(%2)", op);
+ output_asm_insn ("basr\t%0,%0", op);
+ output_asm_insn ("l\t%0,%1", op);
+ }
}
else
{
op[5] = gen_label_rtx ();
op[6] = gen_label_rtx ();
- output_asm_insn ("st\t%0,%1", op);
- output_asm_insn ("bras\t%2,%l6", op);
- targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[5]));
- output_asm_insn (".long\t%4-%l5", op);
- output_asm_insn (".long\t%3-%l5", op);
- targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[6]));
- output_asm_insn ("lr\t%0,%2", op);
- output_asm_insn ("a\t%0,0(%2)", op);
- output_asm_insn ("a\t%2,4(%2)", op);
- output_asm_insn ("basr\t%0,%0", op);
- output_asm_insn ("l\t%0,%1", op);
+ if (flag_nop_mcount)
+ output_asm_nops ("-mnop-mcount", /* st */ 2 + /* bras */ 2 +
+ /* .long */ 2 + /* .long */ 2 + /* lr */ 1 +
+ /* a */ 2 + /* a */ 2 + /* basr */ 1 + /* l */ 2);
+ else
+ {
+ output_asm_insn ("st\t%0,%1", op);
+ output_asm_insn ("bras\t%2,%l6", op);
+ targetm.asm_out.internal_label (file, "L",
+ CODE_LABEL_NUMBER (op[5]));
+ output_asm_insn (".long\t%4-%l5", op);
+ output_asm_insn (".long\t%3-%l5", op);
+ targetm.asm_out.internal_label (file, "L",
+ CODE_LABEL_NUMBER (op[6]));
+ output_asm_insn ("lr\t%0,%2", op);
+ output_asm_insn ("a\t%0,0(%2)", op);
+ output_asm_insn ("a\t%2,4(%2)", op);
+ output_asm_insn ("basr\t%0,%0", op);
+ output_asm_insn ("l\t%0,%1", op);
+ }
}
if (flag_record_mcount)