summaryrefslogtreecommitdiff
path: root/arch/mips/include/asm/bitops.h
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/include/asm/bitops.h')
-rw-r--r--arch/mips/include/asm/bitops.h62
1 files changed, 41 insertions, 21 deletions
diff --git a/arch/mips/include/asm/bitops.h b/arch/mips/include/asm/bitops.h
index a74769940fbd..89f73d1a4ea4 100644
--- a/arch/mips/include/asm/bitops.h
+++ b/arch/mips/include/asm/bitops.h
@@ -16,50 +16,48 @@
#include <linux/bits.h>
#include <linux/compiler.h>
#include <linux/types.h>
+#include <asm/asm.h>
#include <asm/barrier.h>
#include <asm/byteorder.h> /* sigh ... */
#include <asm/compiler.h>
#include <asm/cpu-features.h>
-#include <asm/isa-rev.h>
-#include <asm/llsc.h>
#include <asm/sgidefs.h>
-#include <asm/war.h>
#define __bit_op(mem, insn, inputs...) do { \
- unsigned long temp; \
+ unsigned long __temp; \
\
asm volatile( \
" .set push \n" \
" .set " MIPS_ISA_LEVEL " \n" \
" " __SYNC(full, loongson3_war) " \n" \
- "1: " __LL "%0, %1 \n" \
+ "1: " __stringify(LONG_LL) " %0, %1 \n" \
" " insn " \n" \
- " " __SC "%0, %1 \n" \
- " " __SC_BEQZ "%0, 1b \n" \
+ " " __stringify(LONG_SC) " %0, %1 \n" \
+ " " __stringify(SC_BEQZ) " %0, 1b \n" \
" .set pop \n" \
- : "=&r"(temp), "+" GCC_OFF_SMALL_ASM()(mem) \
+ : "=&r"(__temp), "+" GCC_OFF_SMALL_ASM()(mem) \
: inputs \
: __LLSC_CLOBBER); \
} while (0)
#define __test_bit_op(mem, ll_dst, insn, inputs...) ({ \
- unsigned long orig, temp; \
+ unsigned long __orig, __temp; \
\
asm volatile( \
" .set push \n" \
" .set " MIPS_ISA_LEVEL " \n" \
" " __SYNC(full, loongson3_war) " \n" \
- "1: " __LL ll_dst ", %2 \n" \
+ "1: " __stringify(LONG_LL) " " ll_dst ", %2\n" \
" " insn " \n" \
- " " __SC "%1, %2 \n" \
- " " __SC_BEQZ "%1, 1b \n" \
+ " " __stringify(LONG_SC) " %1, %2 \n" \
+ " " __stringify(SC_BEQZ) " %1, 1b \n" \
" .set pop \n" \
- : "=&r"(orig), "=&r"(temp), \
+ : "=&r"(__orig), "=&r"(__temp), \
"+" GCC_OFF_SMALL_ASM()(mem) \
: inputs \
: __LLSC_CLOBBER); \
\
- orig; \
+ __orig; \
})
/*
@@ -75,7 +73,8 @@ int __mips_test_and_clear_bit(unsigned long nr,
volatile unsigned long *addr);
int __mips_test_and_change_bit(unsigned long nr,
volatile unsigned long *addr);
-
+bool __mips_xor_is_negative_byte(unsigned long mask,
+ volatile unsigned long *addr);
/*
* set_bit - Atomically set a bit in memory
@@ -98,7 +97,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
}
if ((MIPS_ISA_REV >= 2) && __builtin_constant_p(bit) && (bit >= 16)) {
- __bit_op(*m, __INS "%0, %3, %2, 1", "i"(bit), "r"(~0));
+ __bit_op(*m, __stringify(LONG_INS) " %0, %3, %2, 1", "i"(bit), "r"(~0));
return;
}
@@ -126,7 +125,7 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
}
if ((MIPS_ISA_REV >= 2) && __builtin_constant_p(bit)) {
- __bit_op(*m, __INS "%0, $0, %2, 1", "i"(bit));
+ __bit_op(*m, __stringify(LONG_INS) " %0, $0, %2, 1", "i"(bit));
return;
}
@@ -234,8 +233,8 @@ static inline int test_and_clear_bit(unsigned long nr,
res = __mips_test_and_clear_bit(nr, addr);
} else if ((MIPS_ISA_REV >= 2) && __builtin_constant_p(nr)) {
res = __test_bit_op(*m, "%1",
- __EXT "%0, %1, %3, 1;"
- __INS "%1, $0, %3, 1",
+ __stringify(LONG_EXT) " %0, %1, %3, 1;"
+ __stringify(LONG_INS) " %1, $0, %3, 1",
"i"(bit));
} else {
orig = __test_bit_op(*m, "%0",
@@ -281,6 +280,28 @@ static inline int test_and_change_bit(unsigned long nr,
return res;
}
+static inline bool xor_unlock_is_negative_byte(unsigned long mask,
+ volatile unsigned long *p)
+{
+ unsigned long orig;
+ bool res;
+
+ smp_mb__before_atomic();
+
+ if (!kernel_uses_llsc) {
+ res = __mips_xor_is_negative_byte(mask, p);
+ } else {
+ orig = __test_bit_op(*p, "%0",
+ "xor\t%1, %0, %3",
+ "ir"(mask));
+ res = (orig & BIT(7)) != 0;
+ }
+
+ smp_llsc_mb();
+
+ return res;
+}
+
#undef __bit_op
#undef __test_bit_op
@@ -435,7 +456,7 @@ static inline int fls(unsigned int x)
*
* This is defined the same way as
* the libc and compiler builtin ffs routines, therefore
- * differs in spirit from the above ffz (man ffs).
+ * differs in spirit from the below ffz (man ffs).
*/
static inline int ffs(int word)
{
@@ -446,7 +467,6 @@ static inline int ffs(int word)
}
#include <asm-generic/bitops/ffz.h>
-#include <asm-generic/bitops/find.h>
#ifdef __KERNEL__