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