Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit 378ed6f0 authored by Paul Burton's avatar Paul Burton
Browse files

MIPS: Avoid using .set mips0 to restore ISA



We currently have 2 commonly used methods for switching ISA within
assembly code, then restoring the original ISA.

  1) Using a pair of .set push & .set pop directives. For example:

     .set	push
     .set	mips32r2
     <some_insn>
     .set	pop

  2) Using .set mips0 to restore the ISA originally specified on the
     command line. For example:

     .set	mips32r2
     <some_insn>
     .set	mips0

Unfortunately method 2 does not work with nanoMIPS toolchains, where the
assembler rejects the .set mips0 directive like so:

     Error: cannot change ISA from nanoMIPS to mips0

In preparation for supporting nanoMIPS builds, switch all instances of
method 2 in generic non-platform-specific code to use push & pop as in
method 1 instead. The .set push & .set pop is arguably cleaner anyway,
and if nothing else it's good to consistently use one method.

Signed-off-by: default avatarPaul Burton <paul.burton@mips.com>
Patchwork: https://patchwork.linux-mips.org/patch/21037/
Cc: linux-mips@linux-mips.org
parent 183b40f9
Loading
Loading
Loading
Loading
+18 −9
Original line number Diff line number Diff line
@@ -59,12 +59,13 @@ static __inline__ void atomic_##op(int i, atomic_t * v) \
		int temp;						      \
									      \
		__asm__ __volatile__(					      \
		"	.set	push					\n"   \
		"	.set	"MIPS_ISA_LEVEL"			\n"   \
		"1:	ll	%0, %1		# atomic_" #op "	\n"   \
		"	" #asm_op " %0, %2				\n"   \
		"	sc	%0, %1					\n"   \
		"\t" __scbeqz "	%0, 1b					\n"   \
		"	.set	mips0					\n"   \
		"	.set	pop					\n"   \
		: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (v->counter)	      \
		: "Ir" (i));						      \
	} else {							      \
@@ -85,13 +86,14 @@ static __inline__ int atomic_##op##_return_relaxed(int i, atomic_t * v) \
		int temp;						      \
									      \
		__asm__ __volatile__(					      \
		"	.set	push					\n"   \
		"	.set	"MIPS_ISA_LEVEL"			\n"   \
		"1:	ll	%1, %2		# atomic_" #op "_return	\n"   \
		"	" #asm_op " %0, %1, %3				\n"   \
		"	sc	%0, %2					\n"   \
		"\t" __scbeqz "	%0, 1b					\n"   \
		"	" #asm_op " %0, %1, %3				\n"   \
		"	.set	mips0					\n"   \
		"	.set	pop					\n"   \
		: "=&r" (result), "=&r" (temp),				      \
		  "+" GCC_OFF_SMALL_ASM() (v->counter)			      \
		: "Ir" (i));						      \
@@ -117,12 +119,13 @@ static __inline__ int atomic_fetch_##op##_relaxed(int i, atomic_t * v) \
		int temp;						      \
									      \
		__asm__ __volatile__(					      \
		"	.set	push					\n"   \
		"	.set	"MIPS_ISA_LEVEL"			\n"   \
		"1:	ll	%1, %2		# atomic_fetch_" #op "	\n"   \
		"	" #asm_op " %0, %1, %3				\n"   \
		"	sc	%0, %2					\n"   \
		"\t" __scbeqz "	%0, 1b					\n"   \
		"	.set	mips0					\n"   \
		"	.set	pop					\n"   \
		"	move	%0, %1					\n"   \
		: "=&r" (result), "=&r" (temp),				      \
		  "+" GCC_OFF_SMALL_ASM() (v->counter)			      \
@@ -188,17 +191,19 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
		int temp;

		__asm__ __volatile__(
		"	.set	push					\n"
		"	.set	"MIPS_ISA_LEVEL"			\n"
		"1:	ll	%1, %2		# atomic_sub_if_positive\n"
		"	.set	mips0					\n"
		"	.set	pop					\n"
		"	subu	%0, %1, %3				\n"
		"	move	%1, %0					\n"
		"	bltz	%0, 1f					\n"
		"	.set	push					\n"
		"	.set	"MIPS_ISA_LEVEL"			\n"
		"	sc	%1, %2					\n"
		"\t" __scbeqz "	%1, 1b					\n"
		"1:							\n"
		"	.set	mips0					\n"
		"	.set	pop					\n"
		: "=&r" (result), "=&r" (temp),
		  "+" GCC_OFF_SMALL_ASM() (v->counter)
		: "Ir" (i));
@@ -252,12 +257,13 @@ static __inline__ void atomic64_##op(long i, atomic64_t * v) \
		long temp;						      \
									      \
		__asm__ __volatile__(					      \
		"	.set	push					\n"   \
		"	.set	"MIPS_ISA_LEVEL"			\n"   \
		"1:	lld	%0, %1		# atomic64_" #op "	\n"   \
		"	" #asm_op " %0, %2				\n"   \
		"	scd	%0, %1					\n"   \
		"\t" __scbeqz "	%0, 1b					\n"   \
		"	.set	mips0					\n"   \
		"	.set	pop					\n"   \
		: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (v->counter)	      \
		: "Ir" (i));						      \
	} else {							      \
@@ -278,13 +284,14 @@ static __inline__ long atomic64_##op##_return_relaxed(long i, atomic64_t * v) \
		long temp;						      \
									      \
		__asm__ __volatile__(					      \
		"	.set	push					\n"   \
		"	.set	"MIPS_ISA_LEVEL"			\n"   \
		"1:	lld	%1, %2		# atomic64_" #op "_return\n"  \
		"	" #asm_op " %0, %1, %3				\n"   \
		"	scd	%0, %2					\n"   \
		"\t" __scbeqz "	%0, 1b					\n"   \
		"	" #asm_op " %0, %1, %3				\n"   \
		"	.set	mips0					\n"   \
		"	.set	pop					\n"   \
		: "=&r" (result), "=&r" (temp),				      \
		  "+" GCC_OFF_SMALL_ASM() (v->counter)			      \
		: "Ir" (i));						      \
@@ -310,13 +317,14 @@ static __inline__ long atomic64_fetch_##op##_relaxed(long i, atomic64_t * v) \
		long temp;						      \
									      \
		__asm__ __volatile__(					      \
		"	.set	push					\n"   \
		"	.set	"MIPS_ISA_LEVEL"			\n"   \
		"1:	lld	%1, %2		# atomic64_fetch_" #op "\n"   \
		"	" #asm_op " %0, %1, %3				\n"   \
		"	scd	%0, %2					\n"   \
		"\t" __scbeqz "	%0, 1b					\n"   \
		"	move	%0, %1					\n"   \
		"	.set	mips0					\n"   \
		"	.set	pop					\n"   \
		: "=&r" (result), "=&r" (temp),				      \
		  "+" GCC_OFF_SMALL_ASM() (v->counter)			      \
		: "Ir" (i));						      \
@@ -382,6 +390,7 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
		long temp;

		__asm__ __volatile__(
		"	.set	push					\n"
		"	.set	"MIPS_ISA_LEVEL"			\n"
		"1:	lld	%1, %2		# atomic64_sub_if_positive\n"
		"	dsubu	%0, %1, %3				\n"
@@ -390,7 +399,7 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
		"	scd	%1, %2					\n"
		"\t" __scbeqz "	%1, 1b					\n"
		"1:							\n"
		"	.set	mips0					\n"
		"	.set	pop					\n"
		: "=&r" (result), "=&r" (temp),
		  "+" GCC_OFF_SMALL_ASM() (v->counter)
		: "Ir" (i));
+28 −14
Original line number Diff line number Diff line
@@ -58,12 +58,13 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)

	if (kernel_uses_llsc && R10000_LLSC_WAR) {
		__asm__ __volatile__(
		"	.set	push					\n"
		"	.set	arch=r4000				\n"
		"1:	" __LL "%0, %1			# set_bit	\n"
		"	or	%0, %2					\n"
		"	" __SC	"%0, %1					\n"
		"	beqzl	%0, 1b					\n"
		"	.set	mips0					\n"
		"	.set	pop					\n"
		: "=&r" (temp), "=" GCC_OFF_SMALL_ASM() (*m)
		: "ir" (1UL << bit), GCC_OFF_SMALL_ASM() (*m));
#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
@@ -80,11 +81,12 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
	} else if (kernel_uses_llsc) {
		do {
			__asm__ __volatile__(
			"	.set	push				\n"
			"	.set	"MIPS_ISA_ARCH_LEVEL"		\n"
			"	" __LL "%0, %1		# set_bit	\n"
			"	or	%0, %2				\n"
			"	" __SC	"%0, %1				\n"
			"	.set	mips0				\n"
			"	.set	pop				\n"
			: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m)
			: "ir" (1UL << bit));
		} while (unlikely(!temp));
@@ -110,12 +112,13 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)

	if (kernel_uses_llsc && R10000_LLSC_WAR) {
		__asm__ __volatile__(
		"	.set	push					\n"
		"	.set	arch=r4000				\n"
		"1:	" __LL "%0, %1			# clear_bit	\n"
		"	and	%0, %2					\n"
		"	" __SC "%0, %1					\n"
		"	beqzl	%0, 1b					\n"
		"	.set	mips0					\n"
		"	.set	pop					\n"
		: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m)
		: "ir" (~(1UL << bit)));
#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
@@ -132,11 +135,12 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
	} else if (kernel_uses_llsc) {
		do {
			__asm__ __volatile__(
			"	.set	push				\n"
			"	.set	"MIPS_ISA_ARCH_LEVEL"		\n"
			"	" __LL "%0, %1		# clear_bit	\n"
			"	and	%0, %2				\n"
			"	" __SC "%0, %1				\n"
			"	.set	mips0				\n"
			"	.set	pop				\n"
			: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m)
			: "ir" (~(1UL << bit)));
		} while (unlikely(!temp));
@@ -176,12 +180,13 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
		unsigned long temp;

		__asm__ __volatile__(
		"	.set	push				\n"
		"	.set	arch=r4000			\n"
		"1:	" __LL "%0, %1		# change_bit	\n"
		"	xor	%0, %2				\n"
		"	" __SC	"%0, %1				\n"
		"	beqzl	%0, 1b				\n"
		"	.set	mips0				\n"
		"	.set	pop				\n"
		: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m)
		: "ir" (1UL << bit));
	} else if (kernel_uses_llsc) {
@@ -190,11 +195,12 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr)

		do {
			__asm__ __volatile__(
			"	.set	push				\n"
			"	.set	"MIPS_ISA_ARCH_LEVEL"		\n"
			"	" __LL "%0, %1		# change_bit	\n"
			"	xor	%0, %2				\n"
			"	" __SC	"%0, %1				\n"
			"	.set	mips0				\n"
			"	.set	pop				\n"
			: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m)
			: "ir" (1UL << bit));
		} while (unlikely(!temp));
@@ -223,13 +229,14 @@ static inline int test_and_set_bit(unsigned long nr,
		unsigned long temp;

		__asm__ __volatile__(
		"	.set	push					\n"
		"	.set	arch=r4000				\n"
		"1:	" __LL "%0, %1		# test_and_set_bit	\n"
		"	or	%2, %0, %3				\n"
		"	" __SC	"%2, %1					\n"
		"	beqzl	%2, 1b					\n"
		"	and	%2, %0, %3				\n"
		"	.set	mips0					\n"
		"	.set	pop					\n"
		: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res)
		: "r" (1UL << bit)
		: "memory");
@@ -239,11 +246,12 @@ static inline int test_and_set_bit(unsigned long nr,

		do {
			__asm__ __volatile__(
			"	.set	push				\n"
			"	.set	"MIPS_ISA_ARCH_LEVEL"		\n"
			"	" __LL "%0, %1	# test_and_set_bit	\n"
			"	or	%2, %0, %3			\n"
			"	" __SC	"%2, %1				\n"
			"	.set	mips0				\n"
			"	.set	pop				\n"
			: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res)
			: "r" (1UL << bit)
			: "memory");
@@ -277,13 +285,14 @@ static inline int test_and_set_bit_lock(unsigned long nr,
		unsigned long temp;

		__asm__ __volatile__(
		"	.set	push					\n"
		"	.set	arch=r4000				\n"
		"1:	" __LL "%0, %1		# test_and_set_bit	\n"
		"	or	%2, %0, %3				\n"
		"	" __SC	"%2, %1					\n"
		"	beqzl	%2, 1b					\n"
		"	and	%2, %0, %3				\n"
		"	.set	mips0					\n"
		"	.set	pop					\n"
		: "=&r" (temp), "+m" (*m), "=&r" (res)
		: "r" (1UL << bit)
		: "memory");
@@ -293,11 +302,12 @@ static inline int test_and_set_bit_lock(unsigned long nr,

		do {
			__asm__ __volatile__(
			"	.set	push				\n"
			"	.set	"MIPS_ISA_ARCH_LEVEL"		\n"
			"	" __LL "%0, %1	# test_and_set_bit	\n"
			"	or	%2, %0, %3			\n"
			"	" __SC	"%2, %1				\n"
			"	.set	mips0				\n"
			"	.set	pop				\n"
			: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res)
			: "r" (1UL << bit)
			: "memory");
@@ -332,6 +342,7 @@ static inline int test_and_clear_bit(unsigned long nr,
		unsigned long temp;

		__asm__ __volatile__(
		"	.set	push					\n"
		"	.set	arch=r4000				\n"
		"1:	" __LL	"%0, %1		# test_and_clear_bit	\n"
		"	or	%2, %0, %3				\n"
@@ -339,7 +350,7 @@ static inline int test_and_clear_bit(unsigned long nr,
		"	" __SC	"%2, %1					\n"
		"	beqzl	%2, 1b					\n"
		"	and	%2, %0, %3				\n"
		"	.set	mips0					\n"
		"	.set	pop					\n"
		: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res)
		: "r" (1UL << bit)
		: "memory");
@@ -365,12 +376,13 @@ static inline int test_and_clear_bit(unsigned long nr,

		do {
			__asm__ __volatile__(
			"	.set	push				\n"
			"	.set	"MIPS_ISA_ARCH_LEVEL"		\n"
			"	" __LL	"%0, %1 # test_and_clear_bit	\n"
			"	or	%2, %0, %3			\n"
			"	xor	%2, %3				\n"
			"	" __SC	"%2, %1				\n"
			"	.set	mips0				\n"
			"	.set	pop				\n"
			: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res)
			: "r" (1UL << bit)
			: "memory");
@@ -406,13 +418,14 @@ static inline int test_and_change_bit(unsigned long nr,
		unsigned long temp;

		__asm__ __volatile__(
		"	.set	push					\n"
		"	.set	arch=r4000				\n"
		"1:	" __LL	"%0, %1		# test_and_change_bit	\n"
		"	xor	%2, %0, %3				\n"
		"	" __SC	"%2, %1					\n"
		"	beqzl	%2, 1b					\n"
		"	and	%2, %0, %3				\n"
		"	.set	mips0					\n"
		"	.set	pop					\n"
		: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res)
		: "r" (1UL << bit)
		: "memory");
@@ -422,11 +435,12 @@ static inline int test_and_change_bit(unsigned long nr,

		do {
			__asm__ __volatile__(
			"	.set	push				\n"
			"	.set	"MIPS_ISA_ARCH_LEVEL"		\n"
			"	" __LL	"%0, %1 # test_and_change_bit	\n"
			"	xor	%2, %0, %3			\n"
			"	" __SC	"\t%2, %1			\n"
			"	.set	mips0				\n"
			"	.set	pop				\n"
			: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res)
			: "r" (1UL << bit)
			: "memory");
+4 −2
Original line number Diff line number Diff line
@@ -47,9 +47,10 @@ extern unsigned long __xchg_called_with_bad_pointer(void)
		__asm__ __volatile__(					\
		"	.set	push				\n"	\
		"	.set	noat				\n"	\
		"	.set	push				\n"	\
		"	.set	" MIPS_ISA_ARCH_LEVEL "		\n"	\
		"1:	" ld "	%0, %2		# __xchg_asm	\n"	\
		"	.set	mips0				\n"	\
		"	.set	pop				\n"	\
		"	move	$1, %z3				\n"	\
		"	.set	" MIPS_ISA_ARCH_LEVEL "		\n"	\
		"	" st "	$1, %1				\n"	\
@@ -117,10 +118,11 @@ static inline unsigned long __xchg(volatile void *ptr, unsigned long x,
		__asm__ __volatile__(					\
		"	.set	push				\n"	\
		"	.set	noat				\n"	\
		"	.set	push				\n"	\
		"	.set	"MIPS_ISA_ARCH_LEVEL"		\n"	\
		"1:	" ld "	%0, %2		# __cmpxchg_asm \n"	\
		"	bne	%0, %z3, 2f			\n"	\
		"	.set	mips0				\n"	\
		"	.set	pop				\n"	\
		"	move	$1, %z4				\n"	\
		"	.set	"MIPS_ISA_ARCH_LEVEL"		\n"	\
		"	" st "	$1, %1				\n"	\
+2 −1
Original line number Diff line number Diff line
@@ -21,12 +21,13 @@ static inline void edac_atomic_scrub(void *va, u32 size)
		 */

		__asm__ __volatile__ (
		"	.set	push					\n"
		"	.set	mips2					\n"
		"1:	ll	%0, %1		# edac_atomic_scrub	\n"
		"	addu	%0, $0					\n"
		"	sc	%0, %1					\n"
		"	beqz	%0, 1b					\n"
		"	.set	mips0					\n"
		"	.set	pop					\n"
		: "=&r" (temp), "=" GCC_OFF_SMALL_ASM() (*virt_addr)
		: GCC_OFF_SMALL_ASM() (*virt_addr));

+8 −6
Original line number Diff line number Diff line
@@ -24,9 +24,10 @@
		__asm__ __volatile__(					\
		"	.set	push				\n"	\
		"	.set	noat				\n"	\
		"	.set	push				\n"	\
		"	.set	arch=r4000			\n"	\
		"1:	ll	%1, %4	# __futex_atomic_op	\n"	\
		"	.set	mips0				\n"	\
		"	.set	pop				\n"	\
		"	" insn	"				\n"	\
		"	.set	arch=r4000			\n"	\
		"2:	sc	$1, %2				\n"	\
@@ -35,7 +36,6 @@
		"3:						\n"	\
		"	.insn					\n"	\
		"	.set	pop				\n"	\
		"	.set	mips0				\n"	\
		"	.section .fixup,\"ax\"			\n"	\
		"4:	li	%0, %6				\n"	\
		"	j	3b				\n"	\
@@ -53,9 +53,10 @@
		__asm__ __volatile__(					\
		"	.set	push				\n"	\
		"	.set	noat				\n"	\
		"	.set	push				\n"	\
		"	.set	"MIPS_ISA_ARCH_LEVEL"		\n"	\
		"1:	"user_ll("%1", "%4")" # __futex_atomic_op\n"	\
		"	.set	mips0				\n"	\
		"	.set	pop				\n"	\
		"	" insn	"				\n"	\
		"	.set	"MIPS_ISA_ARCH_LEVEL"		\n"	\
		"2:	"user_sc("$1", "%2")"			\n"	\
@@ -64,7 +65,6 @@
		"3:						\n"	\
		"	.insn					\n"	\
		"	.set	pop				\n"	\
		"	.set	mips0				\n"	\
		"	.section .fixup,\"ax\"			\n"	\
		"4:	li	%0, %6				\n"	\
		"	j	3b				\n"	\
@@ -137,10 +137,11 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
		"# futex_atomic_cmpxchg_inatomic			\n"
		"	.set	push					\n"
		"	.set	noat					\n"
		"	.set	push					\n"
		"	.set	arch=r4000				\n"
		"1:	ll	%1, %3					\n"
		"	bne	%1, %z4, 3f				\n"
		"	.set	mips0					\n"
		"	.set	pop					\n"
		"	move	$1, %z5					\n"
		"	.set	arch=r4000				\n"
		"2:	sc	$1, %2					\n"
@@ -166,10 +167,11 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
		"# futex_atomic_cmpxchg_inatomic			\n"
		"	.set	push					\n"
		"	.set	noat					\n"
		"	.set	push					\n"
		"	.set	"MIPS_ISA_ARCH_LEVEL"			\n"
		"1:	"user_ll("%1", "%3")"				\n"
		"	bne	%1, %z4, 3f				\n"
		"	.set	mips0					\n"
		"	.set	pop					\n"
		"	move	$1, %z5					\n"
		"	.set	"MIPS_ISA_ARCH_LEVEL"			\n"
		"2:	"user_sc("$1", "%2")"				\n"
Loading