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