summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/asm-h8300/bitops.h273
1 files changed, 126 insertions, 147 deletions
diff --git a/include/asm-h8300/bitops.h b/include/asm-h8300/bitops.h
index 30288d3ffe32..1d7382f84cb4 100644
--- a/include/asm-h8300/bitops.h
+++ b/include/asm-h8300/bitops.h
@@ -35,172 +35,151 @@ static __inline__ unsigned long ffz(unsigned long word)
return result;
}
-static __inline__ void set_bit(int nr, volatile unsigned long* addr)
-{
- volatile unsigned char *b_addr;
- b_addr = (volatile unsigned char *)addr + ((nr >> 3) ^ 3);
- __asm__("mov.l %1,er0\n\t"
- "bset r0l,%0"
- :"+m"(*b_addr)
- :"g"(nr & 7),"m"(*b_addr)
- :"er0");
+#define H8300_GEN_BITOP_CONST(OP,BIT) \
+ case BIT: \
+ __asm__(OP " #" #BIT ",@%0"::"r"(b_addr):"memory"); \
+ break;
+
+#define H8300_GEN_BITOP(FNAME,OP) \
+static __inline__ void FNAME(int nr, volatile unsigned long* addr) \
+{ \
+ volatile unsigned char *b_addr; \
+ b_addr = (volatile unsigned char *)addr + ((nr >> 3) ^ 3); \
+ if (__builtin_constant_p(nr)) { \
+ switch(nr & 7) { \
+ H8300_GEN_BITOP_CONST(OP,0) \
+ H8300_GEN_BITOP_CONST(OP,1) \
+ H8300_GEN_BITOP_CONST(OP,2) \
+ H8300_GEN_BITOP_CONST(OP,3) \
+ H8300_GEN_BITOP_CONST(OP,4) \
+ H8300_GEN_BITOP_CONST(OP,5) \
+ H8300_GEN_BITOP_CONST(OP,6) \
+ H8300_GEN_BITOP_CONST(OP,7) \
+ } \
+ } else { \
+ __asm__(OP " %w0,@%1"::"r"(nr),"r"(b_addr):"memory"); \
+ } \
}
-/* Bigendian is complexed... */
-#define __set_bit(nr, addr) set_bit((nr), (addr))
-
/*
* clear_bit() doesn't provide any barrier for the compiler.
*/
#define smp_mb__before_clear_bit() barrier()
#define smp_mb__after_clear_bit() barrier()
-static __inline__ void clear_bit(int nr, volatile unsigned long* addr)
-{
- volatile unsigned char *b_addr;
- b_addr = (volatile unsigned char *)addr + ((nr >> 3) ^ 3);
- __asm__("mov.l %1,er0\n\t"
- "bclr r0l,%0"
- :"+m"(*b_addr)
- :"g"(nr & 7),"m"(*b_addr)
- :"er0");
-}
-
-#define __clear_bit(nr, addr) clear_bit((nr), (addr))
-
-static __inline__ void change_bit(int nr, volatile unsigned long* addr)
-{
- volatile unsigned char *b_addr;
- b_addr = (volatile unsigned char *)addr + ((nr >> 3) ^ 3);
- __asm__("mov.l %1,er0\n\t"
- "bnot r0l,%0"
- :"+m"(*b_addr)
- :"g"(nr & 7),"m"(*b_addr)
- :"er0");
-}
+H8300_GEN_BITOP(set_bit ,"bset")
+H8300_GEN_BITOP(clear_bit ,"bclr")
+H8300_GEN_BITOP(change_bit,"bnot")
+#define __set_bit(nr,addr) set_bit((nr),(addr))
+#define __clear_bit(nr,addr) clear_bit((nr),(addr))
+#define __change_bit(nr,addr) change_bit((nr),(addr))
-#define __change_bit(nr, addr) change_bit((nr), (addr))
+#undef H8300_GEN_BITOP
+#undef H8300_GEN_BITOP_CONST
static __inline__ int test_bit(int nr, const unsigned long* addr)
{
- return (*((volatile unsigned char *)addr + ((nr >> 3) ^ 3)) & (1UL << (nr & 7))) != 0;
+ return (*((volatile unsigned char *)addr +
+ ((nr >> 3) ^ 3)) & (1UL << (nr & 7))) != 0;
}
#define __test_bit(nr, addr) test_bit(nr, addr)
-static __inline__ int test_and_set_bit(int nr, volatile unsigned long* addr)
-{
- int retval = 0;
- volatile unsigned char *a;
-
- a = (volatile unsigned char *)addr += ((nr >> 3) ^ 3); \
- __asm__("mov.l %4,er3\n\t"
- "stc ccr,r3h\n\t"
- "orc #0x80,ccr\n\t"
- "btst r3l,%1\n\t"
- "bset r3l,%1\n\t"
- "beq 1f\n\t"
- "inc.l #1,%0\n\t"
- "1:"
- "ldc r3h,ccr"
- : "=r"(retval),"+m"(*a)
- : "0" (retval),"m" (*a),"g"(nr & 7):"er3","memory");
- return retval;
+#define H8300_GEN_TEST_BITOP_CONST_INT(OP,BIT) \
+ case BIT: \
+ __asm__("stc ccr,%w1\n\t" \
+ "orc #0x80,ccr\n\t" \
+ "bld #" #BIT ",@%3\n\t" \
+ OP " #" #BIT ",@%3\n\t" \
+ "rotxl.l %0\n\t" \
+ "ldc %w1,ccr" \
+ : "=r"(retval),"=&r"(ccrsave) \
+ : "0" (retval),"r" (b_addr) \
+ : "memory"); \
+ break;
+
+#define H8300_GEN_TEST_BITOP_CONST(OP,BIT) \
+ case BIT: \
+ __asm__("bld #" #BIT ",@%2\n\t" \
+ OP " #" #BIT ",@%2\n\t" \
+ "rotxl.l %0\n\t" \
+ : "=r"(retval) \
+ : "0" (retval),"r" (b_addr) \
+ : "memory"); \
+ break;
+
+#define H8300_GEN_TEST_BITOP(FNNAME,OP) \
+static __inline__ int FNNAME(int nr, volatile void * addr) \
+{ \
+ int retval = 0; \
+ char ccrsave; \
+ volatile unsigned char *b_addr; \
+ b_addr = (volatile unsigned char *)addr + ((nr >> 3) ^ 3); \
+ if (__builtin_constant_p(nr)) { \
+ switch(nr & 7) { \
+ H8300_GEN_TEST_BITOP_CONST_INT(OP,0) \
+ H8300_GEN_TEST_BITOP_CONST_INT(OP,1) \
+ H8300_GEN_TEST_BITOP_CONST_INT(OP,2) \
+ H8300_GEN_TEST_BITOP_CONST_INT(OP,3) \
+ H8300_GEN_TEST_BITOP_CONST_INT(OP,4) \
+ H8300_GEN_TEST_BITOP_CONST_INT(OP,5) \
+ H8300_GEN_TEST_BITOP_CONST_INT(OP,6) \
+ H8300_GEN_TEST_BITOP_CONST_INT(OP,7) \
+ } \
+ } else { \
+ __asm__("stc ccr,%w1\n\t" \
+ "orc #0x80,ccr\n\t" \
+ "btst %w4,@%3\n\t" \
+ OP " %w4,@%3\n\t" \
+ "beq 1f\n\t" \
+ "inc.l #1,%0\n" \
+ "1:\n\t" \
+ "ldc %w1,ccr" \
+ : "=r"(retval),"=&r"(ccrsave) \
+ : "0" (retval),"r" (b_addr),"r"(nr) \
+ : "memory"); \
+ } \
+ return retval; \
+} \
+ \
+static __inline__ int __ ## FNNAME(int nr, volatile void * addr) \
+{ \
+ int retval = 0; \
+ volatile unsigned char *b_addr; \
+ b_addr = (volatile unsigned char *)addr + ((nr >> 3) ^ 3); \
+ if (__builtin_constant_p(nr)) { \
+ switch(nr & 7) { \
+ H8300_GEN_TEST_BITOP_CONST(OP,0) \
+ H8300_GEN_TEST_BITOP_CONST(OP,1) \
+ H8300_GEN_TEST_BITOP_CONST(OP,2) \
+ H8300_GEN_TEST_BITOP_CONST(OP,3) \
+ H8300_GEN_TEST_BITOP_CONST(OP,4) \
+ H8300_GEN_TEST_BITOP_CONST(OP,5) \
+ H8300_GEN_TEST_BITOP_CONST(OP,6) \
+ H8300_GEN_TEST_BITOP_CONST(OP,7) \
+ } \
+ } else { \
+ __asm__("btst %w3,@%2\n\t" \
+ OP " %w3,@%2\n\t" \
+ "beq 1f\n\t" \
+ "inc.l #1,%0\n" \
+ "1:" \
+ : "=r"(retval) \
+ : "0" (retval),"r" (b_addr),"r"(nr) \
+ : "memory"); \
+ } \
+ return retval; \
}
-static __inline__ int __test_and_set_bit(int nr, volatile unsigned long* addr)
-{
- int retval = 0;
- volatile unsigned char *a;
-
- a = (volatile unsigned char *)addr += ((nr >> 3) ^ 3); \
- __asm__("mov.l %4,er3\n\t"
- "btst r3l,%1\n\t"
- "bset r3l,%1\n\t"
- "beq 1f\n\t"
- "inc.l #1,%0\n\t"
- "1:"
- : "=r"(retval),"+m"(*a)
- : "0" (retval),"m" (*a),"g"(nr & 7):"er3","memory");
- return retval;
-}
-
-static __inline__ int test_and_clear_bit(int nr, volatile unsigned long* addr)
-{
- int retval = 0;
- volatile unsigned char *a;
-
- a = (volatile unsigned char *)addr += ((nr >> 3) ^ 3); \
- __asm__("mov.l %4,er3\n\t"
- "stc ccr,r3h\n\t"
- "orc #0x80,ccr\n\t"
- "btst r3l,%1\n\t"
- "bclr r3l,%1\n\t"
- "beq 1f\n\t"
- "inc.l #1,%0\n\t"
- "1:"
- "ldc r3h,ccr"
- : "=r"(retval),"+m"(*a)
- : "0" (retval),"m" (*a),"g"(nr & 7):"er3","memory");
- return retval;
-}
-
-static __inline__ int __test_and_clear_bit(int nr, volatile unsigned long* addr)
-{
- int retval = 0;
- volatile unsigned char *a;
-
- a = (volatile unsigned char *)addr += ((nr >> 3) ^ 3); \
- __asm__("mov.l %4,er3\n\t"
- "btst r3l,%1\n\t"
- "bclr r3l,%1\n\t"
- "beq 1f\n\t"
- "inc.l #1,%0\n\t"
- "1:"
- : "=r"(retval),"+m"(*a)
- : "0" (retval),"m" (*a),"g"(nr & 7):"er3","memory");
- return retval;
-}
-
-static __inline__ int test_and_change_bit(int nr, volatile unsigned long* addr)
-{
- int retval = 0;
- volatile unsigned char *a;
-
- a = (volatile unsigned char *)addr += ((nr >> 3) ^ 3); \
- __asm__("mov.l %4,er3\n\t"
- "stc ccr,r3h\n\t"
- "orc #0x80,ccr\n\t"
- "btst r3l,%1\n\t"
- "bnot r3l,%1\n\t"
- "beq 1f\n\t"
- "inc.l #1,%0\n\t"
- "1:"
- "ldc r3h,ccr"
- : "=r"(retval),"+m"(*a)
- : "0" (retval),"m" (*a),"g"(nr & 7):"er3","memory");
- return retval;
-}
-
-static __inline__ int __test_and_change_bit(int nr, volatile unsigned long* addr)
-{
- int retval = 0;
- volatile unsigned char *a;
-
- a = (volatile unsigned char *)addr += ((nr >> 3) ^ 3); \
- __asm__("mov.l %4,er3\n\t"
- "btst r3l,%1\n\t"
- "bnot r3l,%1\n\t"
- "beq 1f\n\t"
- "inc.l #1,%0\n\t"
- "1:"
- : "=r"(retval),"+m"(*a)
- : "0" (retval),"m" (*a),"g"(nr & 7):"er3","memory");
- return retval;
-}
+H8300_GEN_TEST_BITOP(test_and_set_bit, "bset")
+H8300_GEN_TEST_BITOP(test_and_clear_bit, "bclr")
+H8300_GEN_TEST_BITOP(test_and_change_bit,"bnot")
+#undef H8300_GEN_TEST_BITOP_CONST
+#undef H8300_GEN_TEST_BITOP_CONST_INT
+#undef H8300_GEN_TEST_BITOP
#define find_first_zero_bit(addr, size) \
- find_next_zero_bit((addr), (size), 0)
+ find_next_zero_bit((addr), (size), 0)
static __inline__ int find_next_zero_bit (void * addr, int size, int offset)
{
@@ -326,7 +305,7 @@ static __inline__ int ext2_test_bit(int nr, const volatile void * addr)
}
#define ext2_find_first_zero_bit(addr, size) \
- ext2_find_next_zero_bit((addr), (size), 0)
+ ext2_find_next_zero_bit((addr), (size), 0)
static __inline__ unsigned long ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
{