[MIPS] If using branch likelies in MIPS sync code fill the delay slot

with a nop.

gcc/
	* config/mips/mips.c (mips_process_sync_loop): Place a 
	nop in the delay slot of the branch likely instruction.
	(mips_output_sync_loop): Ensure mips_branch_likely is 
	set before calling mips_output_sync_loop.
	(mips_sync_loop_insns): Likewise.

From-SVN: r217926
This commit is contained in:
Andrew Bennett 2014-11-21 14:34:55 +00:00 committed by Andrew Bennett
parent 4bec983122
commit 3b6eaaa53d
2 changed files with 22 additions and 4 deletions

View File

@ -1,3 +1,11 @@
2014-11-21 Andrew Bennett <andrew.bennett@imgtec.com>
* config/mips/mips.c (mips_process_sync_loop): Place a
nop in the delay slot of the branch likely instruction.
(mips_output_sync_loop): Ensure mips_branch_likely is
set before calling mips_output_sync_loop.
(mips_sync_loop_insns): Likewise.
2014-11-21 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
PR/target 63673

View File

@ -12997,7 +12997,14 @@ 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);
/* When using branch likely (-mfix-r10000), the delay slot instruction
will be annulled on false. The normal delay slot instructions
calculate the overall result of the atomic operation and must not
be annulled. To ensure this behaviour unconditionally use a NOP
in the delay slot for the branch likely case. */
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 +13012,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 +13036,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 +13063,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;
}