bitops.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. #ifndef _H8300_BITOPS_H
  2. #define _H8300_BITOPS_H
  3. /*
  4. * Copyright 1992, Linus Torvalds.
  5. * Copyright 2002, Yoshinori Sato
  6. */
  7. #include <linux/compiler.h>
  8. #ifdef __KERNEL__
  9. #ifndef _LINUX_BITOPS_H
  10. #error only <linux/bitops.h> can be included directly
  11. #endif
  12. /*
  13. * Function prototypes to keep gcc -Wall happy
  14. */
  15. /*
  16. * ffz = Find First Zero in word. Undefined if no zero exists,
  17. * so code should check against ~0UL first..
  18. */
  19. static inline unsigned long ffz(unsigned long word)
  20. {
  21. unsigned long result;
  22. result = -1;
  23. __asm__("1:\n\t"
  24. "shlr.l %2\n\t"
  25. "adds #1,%0\n\t"
  26. "bcs 1b"
  27. : "=r"(result)
  28. : "0"(result), "r"(word));
  29. return result;
  30. }
  31. #define H8300_GEN_BITOP(FNAME, OP) \
  32. static inline void FNAME(int nr, volatile unsigned long *addr) \
  33. { \
  34. unsigned char *b_addr; \
  35. unsigned char bit = nr & 7; \
  36. \
  37. b_addr = (unsigned char *)addr + ((nr >> 3) ^ 3); \
  38. if (__builtin_constant_p(nr)) { \
  39. __asm__(OP " %1,%0" : "+WU"(*b_addr) : "i"(nr & 7)); \
  40. } else { \
  41. __asm__(OP " %s1,%0" : "+WU"(*b_addr) : "r"(bit)); \
  42. } \
  43. }
  44. /*
  45. * clear_bit() doesn't provide any barrier for the compiler.
  46. */
  47. #define smp_mb__before_clear_bit() barrier()
  48. #define smp_mb__after_clear_bit() barrier()
  49. H8300_GEN_BITOP(set_bit, "bset")
  50. H8300_GEN_BITOP(clear_bit, "bclr")
  51. H8300_GEN_BITOP(change_bit, "bnot")
  52. #define __set_bit(nr, addr) set_bit((nr), (addr))
  53. #define __clear_bit(nr, addr) clear_bit((nr), (addr))
  54. #define __change_bit(nr, addr) change_bit((nr), (addr))
  55. #undef H8300_GEN_BITOP
  56. static inline int test_bit(int nr, const unsigned long *addr)
  57. {
  58. int ret = 0;
  59. unsigned char *b_addr;
  60. unsigned char bit = nr & 7;
  61. b_addr = (unsigned char *)addr + ((nr >> 3) ^ 3);
  62. if (__builtin_constant_p(nr)) {
  63. __asm__("bld %Z2,%1\n\t"
  64. "rotxl %0\n\t"
  65. : "=r"(ret)
  66. : "WU"(*b_addr), "i"(nr & 7), "0"(ret) : "cc");
  67. } else {
  68. __asm__("btst %w2,%1\n\t"
  69. "beq 1f\n\t"
  70. "inc.l #1,%0\n"
  71. "1:"
  72. : "=r"(ret)
  73. : "WU"(*b_addr), "r"(bit), "0"(ret) : "cc");
  74. }
  75. return ret;
  76. }
  77. #define __test_bit(nr, addr) test_bit(nr, addr)
  78. #define H8300_GEN_TEST_BITOP(FNNAME, OP) \
  79. static inline int FNNAME(int nr, void *addr) \
  80. { \
  81. int retval = 0; \
  82. char ccrsave; \
  83. unsigned char *b_addr; \
  84. unsigned char bit = nr & 7; \
  85. \
  86. b_addr = (unsigned char *)addr + ((nr >> 3) ^ 3); \
  87. if (__builtin_constant_p(nr)) { \
  88. __asm__("stc ccr,%s2\n\t" \
  89. "orc #0x80,ccr\n\t" \
  90. "bld %4,%1\n\t" \
  91. OP " %4,%1\n\t" \
  92. "rotxl.l %0\n\t" \
  93. "ldc %s2,ccr" \
  94. : "=r"(retval), "+WU" (*b_addr), "=&r"(ccrsave) \
  95. : "0"(retval), "i"(nr & 7) : "cc"); \
  96. } else { \
  97. __asm__("stc ccr,%t3\n\t" \
  98. "orc #0x80,ccr\n\t" \
  99. "btst %s3,%1\n\t" \
  100. OP " %s3,%1\n\t" \
  101. "beq 1f\n\t" \
  102. "inc.l #1,%0\n\t" \
  103. "1:\n" \
  104. "ldc %t3,ccr" \
  105. : "=r"(retval), "+WU" (*b_addr) \
  106. : "0" (retval), "r"(bit) : "cc"); \
  107. } \
  108. return retval; \
  109. } \
  110. \
  111. static inline int __ ## FNNAME(int nr, void *addr) \
  112. { \
  113. int retval = 0; \
  114. unsigned char *b_addr; \
  115. unsigned char bit = nr & 7; \
  116. \
  117. b_addr = (unsigned char *)addr + ((nr >> 3) ^ 3); \
  118. if (__builtin_constant_p(nr)) { \
  119. __asm__("bld %3,%1\n\t" \
  120. OP " %3,%1\n\t" \
  121. "rotxl.l %0\n\t" \
  122. : "=r"(retval), "+WU"(*b_addr) \
  123. : "0" (retval), "i"(nr & 7)); \
  124. } else { \
  125. __asm__("btst %s3,%1\n\t" \
  126. OP " %s3,%1\n\t" \
  127. "beq 1f\n\t" \
  128. "inc.l #1,%0\n\t" \
  129. "1:" \
  130. : "=r"(retval), "+WU"(*b_addr) \
  131. : "0" (retval), "r"(bit)); \
  132. } \
  133. return retval; \
  134. }
  135. H8300_GEN_TEST_BITOP(test_and_set_bit, "bset")
  136. H8300_GEN_TEST_BITOP(test_and_clear_bit, "bclr")
  137. H8300_GEN_TEST_BITOP(test_and_change_bit, "bnot")
  138. #undef H8300_GEN_TEST_BITOP
  139. #include <asm-generic/bitops/ffs.h>
  140. static inline unsigned long __ffs(unsigned long word)
  141. {
  142. unsigned long result;
  143. result = -1;
  144. __asm__("1:\n\t"
  145. "shlr.l %2\n\t"
  146. "adds #1,%0\n\t"
  147. "bcc 1b"
  148. : "=r" (result)
  149. : "0"(result), "r"(word));
  150. return result;
  151. }
  152. #include <asm-generic/bitops/find.h>
  153. #include <asm-generic/bitops/sched.h>
  154. #include <asm-generic/bitops/hweight.h>
  155. #include <asm-generic/bitops/lock.h>
  156. #include <asm-generic/bitops/le.h>
  157. #include <asm-generic/bitops/ext2-atomic.h>
  158. #endif /* __KERNEL__ */
  159. #include <asm-generic/bitops/fls.h>
  160. #include <asm-generic/bitops/__fls.h>
  161. #include <asm-generic/bitops/fls64.h>
  162. #endif /* _H8300_BITOPS_H */