All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] MIPS: Fix delay slot bug in `atomic*_sub_if_positive' for R10000_LLSC_WAR
@ 2017-11-19  3:29 Joshua Kinard
  0 siblings, 0 replies; only message in thread
From: Joshua Kinard @ 2017-11-19  3:29 UTC (permalink / raw)
  To: Ralf Baechle, James Hogan, Maciej W. Rozycki; +Cc: Linux/MIPS

From: Joshua Kinard <kumba@gentoo.org>

This patch fixes an old bug in MIPS ll/sc atomics, in the
`atomic_sub_if_positive' and `atomic64_sub_if_positive' functions, for
the R10000_LLSC_WAR case where the result of the subu/dsubu instruction
would potentially not be made available to the sc/scd instruction due
to being in the delay-slot of the branch-likely (beqzl) instruction.

This also removes the need for the `noreorder' directive, allowing GAS
to use delay slot scheduling as needed.

The same fix is also applied to the standard branch (beqz) case in
preparation for a follow-up patch that will cleanup/merge the
R10000_LLSC_WAR and non-R10K sections together.

Cc: linux-mips@linux-mips.org
Signed-off-by: Joshua Kinard <kumba@gentoo.org>
Tested-by: Joshua Kinard <kumba@gentoo.org>

---
 arch/mips/include/asm/atomic.h |   32 +++++++++++--------------------
 1 file changed, 12 insertions(+), 20 deletions(-)

diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h
index 0ab176bdb8e8..0babf2775d8e 100644
--- a/arch/mips/include/asm/atomic.h
+++ b/arch/mips/include/asm/atomic.h
@@ -225,12 +225,10 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
 		"	.set	arch=r4000				\n"
 		"1:	ll	%1, %2		# atomic_sub_if_positive\n"
 		"	subu	%0, %1, %3				\n"
+		"	move	%1, %0					\n"
 		"	bltz	%0, 1f					\n"
-		"	sc	%0, %2					\n"
-		"	.set	noreorder				\n"
-		"	beqzl	%0, 1b					\n"
-		"	 subu	%0, %1, %3				\n"
-		"	.set	reorder					\n"
+		"	sc	%1, %2					\n"
+		"	beqzl	%1, 1b					\n"
 		"1:							\n"
 		"	.set	mips0					\n"
 		: "=&r" (result), "=&r" (temp),
@@ -244,12 +242,10 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
 		"	.set	"MIPS_ISA_LEVEL"			\n"
 		"1:	ll	%1, %2		# atomic_sub_if_positive\n"
 		"	subu	%0, %1, %3				\n"
+		"	move	%1, %0					\n"
 		"	bltz	%0, 1f					\n"
-		"	sc	%0, %2					\n"
-		"	.set	noreorder				\n"
-		"	beqz	%0, 1b					\n"
-		"	 subu	%0, %1, %3				\n"
-		"	.set	reorder					\n"
+		"	sc	%1, %2					\n"
+		"	beqz	%1, 1b					\n"
 		"1:							\n"
 		"	.set	mips0					\n"
 		: "=&r" (result), "=&r" (temp),
@@ -570,12 +566,10 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
 		"	.set	arch=r4000				\n"
 		"1:	lld	%1, %2		# atomic64_sub_if_positive\n"
 		"	dsubu	%0, %1, %3				\n"
+		"	move	%1, %0					\n"
 		"	bltz	%0, 1f					\n"
-		"	scd	%0, %2					\n"
-		"	.set	noreorder				\n"
-		"	beqzl	%0, 1b					\n"
-		"	 dsubu	%0, %1, %3				\n"
-		"	.set	reorder					\n"
+		"	scd	%1, %2					\n"
+		"	beqzl	%1, 1b					\n"
 		"1:							\n"
 		"	.set	mips0					\n"
 		: "=&r" (result), "=&r" (temp),
@@ -589,12 +583,10 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
 		"	.set	"MIPS_ISA_LEVEL"			\n"
 		"1:	lld	%1, %2		# atomic64_sub_if_positive\n"
 		"	dsubu	%0, %1, %3				\n"
+		"	move	%1, %0					\n"
 		"	bltz	%0, 1f					\n"
-		"	scd	%0, %2					\n"
-		"	.set	noreorder				\n"
-		"	beqz	%0, 1b					\n"
-		"	 dsubu	%0, %1, %3				\n"
-		"	.set	reorder					\n"
+		"	scd	%1, %2					\n"
+		"	beqz	%1, 1b					\n"
 		"1:							\n"
 		"	.set	mips0					\n"
 		: "=&r" (result), "=&r" (temp),

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2017-11-19  3:33 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-19  3:29 [PATCH] MIPS: Fix delay slot bug in `atomic*_sub_if_positive' for R10000_LLSC_WAR Joshua Kinard

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.