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: Paul Burton <paul.burton@mips.com>
Patchwork: https://patchwork.linux-mips.org/patch/21037/
Cc: linux-mips@linux-mips.org
This commit is contained in:
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user