summaryrefslogtreecommitdiffstats
path: root/include/asm-alpha/bitops.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm-alpha/bitops.h')
-rw-r--r--include/asm-alpha/bitops.h85
1 files changed, 72 insertions, 13 deletions
diff --git a/include/asm-alpha/bitops.h b/include/asm-alpha/bitops.h
index 2a6f33a64..bec44fe54 100644
--- a/include/asm-alpha/bitops.h
+++ b/include/asm-alpha/bitops.h
@@ -17,7 +17,7 @@
* bit 0 is the LSB of addr; bit 64 is the LSB of (addr+1).
*/
-extern __inline__ unsigned long set_bit(unsigned long nr, void * addr)
+extern __inline__ void set_bit(unsigned long nr, void * addr)
{
unsigned long oldbit;
unsigned long temp;
@@ -31,16 +31,75 @@ extern __inline__ unsigned long set_bit(unsigned long nr, void * addr)
" stl_c %0,%1\n"
" beq %0,3f\n"
"2:\n"
- ".text 2\n"
+ ".section .text2,\"ax\"\n"
"3: br 1b\n"
- ".text"
+ ".previous"
+ :"=&r" (temp), "=m" (*m), "=&r" (oldbit)
+ :"Ir" (1UL << (nr & 31)), "m" (*m));
+}
+
+extern __inline__ void clear_bit(unsigned long nr, void * addr)
+{
+ unsigned long oldbit;
+ unsigned long temp;
+ unsigned int * m = ((unsigned int *) addr) + (nr >> 5);
+
+ __asm__ __volatile__(
+ "1: ldl_l %0,%1\n"
+ " and %0,%3,%2\n\t"
+ " beq %2,2f\n\t"
+ " xor %0,%3,%0\n\t"
+ " stl_c %0,%1\n\t"
+ " beq %0,3f\n"
+ "2:\n"
+ ".section .text2,\"ax\"\n"
+ "3: br 1b\n"
+ ".previous"
+ :"=&r" (temp), "=m" (*m), "=&r" (oldbit)
+ :"Ir" (1UL << (nr & 31)), "m" (*m));
+}
+
+extern __inline__ void change_bit(unsigned long nr, void * addr)
+{
+ unsigned long temp;
+ unsigned int * m = ((unsigned int *) addr) + (nr >> 5);
+
+ __asm__ __volatile__(
+ "1: ldl_l %0,%1\n"
+ " xor %0,%2,%0\n\t"
+ " stl_c %0,%1\n\t"
+ " beq %0,3f\n"
+ ".section .text2,\"ax\"\n"
+ "3: br 1b\n"
+ ".previous"
+ :"=&r" (temp), "=m" (*m)
+ :"Ir" (1UL << (nr & 31)), "m" (*m));
+}
+
+extern __inline__ unsigned long test_and_set_bit(unsigned long nr, void * addr)
+{
+ unsigned long oldbit;
+ unsigned long temp;
+ unsigned int * m = ((unsigned int *) addr) + (nr >> 5);
+
+ __asm__ __volatile__(
+ "1: ldl_l %0,%1\n"
+ " and %0,%3,%2\n"
+ " bne %2,2f\n"
+ " xor %0,%3,%0\n"
+ " stl_c %0,%1\n"
+ " beq %0,3f\n"
+ "2:\n"
+ ".section .text2,\"ax\"\n"
+ "3: br 1b\n"
+ ".previous"
:"=&r" (temp), "=m" (*m), "=&r" (oldbit)
:"Ir" (1UL << (nr & 31)), "m" (*m));
return oldbit != 0;
}
-extern __inline__ unsigned long clear_bit(unsigned long nr, void * addr)
+extern __inline__ unsigned long test_and_clear_bit(unsigned long nr, void * addr)
{
unsigned long oldbit;
unsigned long temp;
@@ -54,16 +113,16 @@ extern __inline__ unsigned long clear_bit(unsigned long nr, void * addr)
" stl_c %0,%1\n\t"
" beq %0,3f\n"
"2:\n"
- ".text 2\n"
+ ".section .text2,\"ax\"\n"
"3: br 1b\n"
- ".text"
+ ".previous"
:"=&r" (temp), "=m" (*m), "=&r" (oldbit)
:"Ir" (1UL << (nr & 31)), "m" (*m));
return oldbit != 0;
}
-extern __inline__ unsigned long change_bit(unsigned long nr, void * addr)
+extern __inline__ unsigned long test_and_change_bit(unsigned long nr, void * addr)
{
unsigned long oldbit;
unsigned long temp;
@@ -75,9 +134,9 @@ extern __inline__ unsigned long change_bit(unsigned long nr, void * addr)
" xor %0,%3,%0\n\t"
" stl_c %0,%1\n\t"
" beq %0,3f\n"
- ".text 2\n"
+ ".section .text2,\"ax\"\n"
"3: br 1b\n"
- ".text"
+ ".previous"
:"=&r" (temp), "=m" (*m), "=&r" (oldbit)
:"Ir" (1UL << (nr & 31)), "m" (*m));
@@ -166,15 +225,15 @@ found_middle:
#ifdef __KERNEL__
-#define ext2_set_bit set_bit
-#define ext2_clear_bit clear_bit
+#define ext2_set_bit test_and_set_bit
+#define ext2_clear_bit test_and_clear_bit
#define ext2_test_bit test_bit
#define ext2_find_first_zero_bit find_first_zero_bit
#define ext2_find_next_zero_bit find_next_zero_bit
/* Bitmap functions for the minix filesystem. */
-#define minix_set_bit(nr,addr) set_bit(nr,addr)
-#define minix_clear_bit(nr,addr) clear_bit(nr,addr)
+#define minix_set_bit(nr,addr) test_and_set_bit(nr,addr)
+#define minix_clear_bit(nr,addr) test_and_clear_bit(nr,addr)
#define minix_test_bit(nr,addr) test_bit(nr,addr)
#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)