This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
RE: [PATCH] If using branch likelies in MIPS sync code fill the delay slot with a nop
- From: Andrew Bennett <Andrew dot Bennett at imgtec dot com>
- To: "Moore, Catherine" <Catherine_Moore at mentor dot com>, Matthew Fortune <Matthew dot Fortune at imgtec dot com>, "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>
- Cc: "Rozycki, Maciej" <Maciej_Rozycki at mentor dot com>
- Date: Wed, 19 Nov 2014 14:18:14 +0000
- Subject: RE: [PATCH] If using branch likelies in MIPS sync code fill the delay slot with a nop
- Authentication-results: sourceware.org; auth=none
- References: <0DA23CC379F5F945ACB41CF394B9827720F331A8 at LEMAIL01 dot le dot imgtec dot org> <6D39441BF12EF246A7ABCE6654B0235320F73768 at LEMAIL01 dot le dot imgtec dot org> <FD3DCEAC5B03E9408544A1E416F1124201891165E6 at NA-MBX-01 dot mgc dot mentorg dot com>
> Yes, removing the second NOP is worth the additional effort.
The updated patch is below.
Ok to commit?
Regards,
Andrew
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 02268f3..368c6f0 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -12997,7 +12997,12 @@ mips_process_sync_loop (rtx_insn *insn, rtx *operands)
This will sometimes be a delayed branch; see the write code below
for details. */
mips_multi_add_insn (is_64bit_p ? "scd\t%0,%1" : "sc\t%0,%1", at, mem, NULL);
- mips_multi_add_insn ("beq%?\t%0,%.,1b", at, NULL);
+
+ /* We can not put the NEWVAL = $TMP3 or CMP = 1 operations in the delay slot
+ of the branch if it is a branch likely because they will not execute when
+ the atomic operation is successful, so place a NOP in there instead. */
+
+ mips_multi_add_insn ("beq%?\t%0,%.,1b%~", at, NULL);
/* if (INSN1 != MOVE && INSN1 != LI) NEWVAL = $TMP3 [delay slot]. */
if (insn1 != SYNC_INSN1_MOVE && insn1 != SYNC_INSN1_LI && tmp3 != newval)
@@ -13005,7 +13010,7 @@ mips_process_sync_loop (rtx_insn *insn, rtx *operands)
mips_multi_copy_insn (tmp3_insn);
mips_multi_set_operand (mips_multi_last_index (), 0, newval);
}
- else if (!(required_oldval && cmp))
+ else if (!(required_oldval && cmp) && !mips_branch_likely)
mips_multi_add_insn ("nop", NULL);
/* CMP = 1 -- either standalone or in a delay slot. */
@@ -13029,12 +13034,12 @@ mips_process_sync_loop (rtx_insn *insn, rtx *operands)
const char *
mips_output_sync_loop (rtx_insn *insn, rtx *operands)
{
- mips_process_sync_loop (insn, operands);
-
/* Use branch-likely instructions to work around the LL/SC R10000
errata. */
mips_branch_likely = TARGET_FIX_R10000;
+ mips_process_sync_loop (insn, operands);
+
mips_push_asm_switch (&mips_noreorder);
mips_push_asm_switch (&mips_nomacro);
mips_push_asm_switch (&mips_noat);
@@ -13056,6 +13061,9 @@ mips_output_sync_loop (rtx_insn *insn, rtx *operands)
unsigned int
mips_sync_loop_insns (rtx_insn *insn, rtx *operands)
{
+ /* Use branch-likely instructions to work around the LL/SC R10000
+ errata. */
+ mips_branch_likely = TARGET_FIX_R10000;
mips_process_sync_loop (insn, operands);
return mips_multi_num_insns;
}