1 #ifndef _M68K_BITOPS_H 2 #define _M68K_BITOPS_H 3 /* 4 * Copyright 1992, Linus Torvalds. 5 * 6 * This file is subject to the terms and conditions of the GNU General Public 7 * License. See the file COPYING in the main directory of this archive 8 * for more details. 9 */ 10 11 #ifndef _LINUX_BITOPS_H 12 #error only <linux/bitops.h> can be included directly 13 #endif 14 15 #include <linux/compiler.h> 16 #include <asm/barrier.h> 17 18 /* 19 * Bit access functions vary across the ColdFire and 68k families. 20 * So we will break them out here, and then macro in the ones we want. 21 * 22 * ColdFire - supports standard bset/bclr/bchg with register operand only 23 * 68000 - supports standard bset/bclr/bchg with memory operand 24 * >= 68020 - also supports the bfset/bfclr/bfchg instructions 25 * 26 * Although it is possible to use only the bset/bclr/bchg with register 27 * operands on all platforms you end up with larger generated code. 28 * So we use the best form possible on a given platform. 29 */ 30 31 static inline void bset_reg_set_bit(int nr, volatile unsigned long *vaddr) 32 { 33 char *p = (char *)vaddr + (nr ^ 31) / 8; 34 35 __asm__ __volatile__ ("bset %1,(%0)" 36 : 37 : "a" (p), "di" (nr & 7) 38 : "memory"); 39 } 40 41 static inline void bset_mem_set_bit(int nr, volatile unsigned long *vaddr) 42 { 43 char *p = (char *)vaddr + (nr ^ 31) / 8; 44 45 __asm__ __volatile__ ("bset %1,%0" 46 : "+m" (*p) 47 : "di" (nr & 7)); 48 } 49 50 static inline void bfset_mem_set_bit(int nr, volatile unsigned long *vaddr) 51 { 52 __asm__ __volatile__ ("bfset %1{%0:#1}" 53 : 54 : "d" (nr ^ 31), "o" (*vaddr) 55 : "memory"); 56 } 57 58 #if defined(CONFIG_COLDFIRE) 59 #define set_bit(nr, vaddr) bset_reg_set_bit(nr, vaddr) 60 #elif defined(CONFIG_CPU_HAS_NO_BITFIELDS) 61 #define set_bit(nr, vaddr) bset_mem_set_bit(nr, vaddr) 62 #else 63 #define set_bit(nr, vaddr) (__builtin_constant_p(nr) ? \ 64 bset_mem_set_bit(nr, vaddr) : \ 65 bfset_mem_set_bit(nr, vaddr)) 66 #endif 67 68 #define __set_bit(nr, vaddr) set_bit(nr, vaddr) 69 70 71 static inline void bclr_reg_clear_bit(int nr, volatile unsigned long *vaddr) 72 { 73 char *p = (char *)vaddr + (nr ^ 31) / 8; 74 75 __asm__ __volatile__ ("bclr %1,(%0)" 76 : 77 : "a" (p), "di" (nr & 7) 78 : "memory"); 79 } 80 81 static inline void bclr_mem_clear_bit(int nr, volatile unsigned long *vaddr) 82 { 83 char *p = (char *)vaddr + (nr ^ 31) / 8; 84 85 __asm__ __volatile__ ("bclr %1,%0" 86 : "+m" (*p) 87 : "di" (nr & 7)); 88 } 89 90 static inline void bfclr_mem_clear_bit(int nr, volatile unsigned long *vaddr) 91 { 92 __asm__ __volatile__ ("bfclr %1{%0:#1}" 93 : 94 : "d" (nr ^ 31), "o" (*vaddr) 95 : "memory"); 96 } 97 98 #if defined(CONFIG_COLDFIRE) 99 #define clear_bit(nr, vaddr) bclr_reg_clear_bit(nr, vaddr) 100 #elif defined(CONFIG_CPU_HAS_NO_BITFIELDS) 101 #define clear_bit(nr, vaddr) bclr_mem_clear_bit(nr, vaddr) 102 #else 103 #define clear_bit(nr, vaddr) (__builtin_constant_p(nr) ? \ 104 bclr_mem_clear_bit(nr, vaddr) : \ 105 bfclr_mem_clear_bit(nr, vaddr)) 106 #endif 107 108 #define __clear_bit(nr, vaddr) clear_bit(nr, vaddr) 109 110 111 static inline void bchg_reg_change_bit(int nr, volatile unsigned long *vaddr) 112 { 113 char *p = (char *)vaddr + (nr ^ 31) / 8; 114 115 __asm__ __volatile__ ("bchg %1,(%0)" 116 : 117 : "a" (p), "di" (nr & 7) 118 : "memory"); 119 } 120 121 static inline void bchg_mem_change_bit(int nr, volatile unsigned long *vaddr) 122 { 123 char *p = (char *)vaddr + (nr ^ 31) / 8; 124 125 __asm__ __volatile__ ("bchg %1,%0" 126 : "+m" (*p) 127 : "di" (nr & 7)); 128 } 129 130 static inline void bfchg_mem_change_bit(int nr, volatile unsigned long *vaddr) 131 { 132 __asm__ __volatile__ ("bfchg %1{%0:#1}" 133 : 134 : "d" (nr ^ 31), "o" (*vaddr) 135 : "memory"); 136 } 137 138 #if defined(CONFIG_COLDFIRE) 139 #define change_bit(nr, vaddr) bchg_reg_change_bit(nr, vaddr) 140 #elif defined(CONFIG_CPU_HAS_NO_BITFIELDS) 141 #define change_bit(nr, vaddr) bchg_mem_change_bit(nr, vaddr) 142 #else 143 #define change_bit(nr, vaddr) (__builtin_constant_p(nr) ? \ 144 bchg_mem_change_bit(nr, vaddr) : \ 145 bfchg_mem_change_bit(nr, vaddr)) 146 #endif 147 148 #define __change_bit(nr, vaddr) change_bit(nr, vaddr) 149 150 151 static inline int test_bit(int nr, const unsigned long *vaddr) 152 { 153 return (vaddr[nr >> 5] & (1UL << (nr & 31))) != 0; 154 } 155 156 157 static inline int bset_reg_test_and_set_bit(int nr, 158 volatile unsigned long *vaddr) 159 { 160 char *p = (char *)vaddr + (nr ^ 31) / 8; 161 char retval; 162 163 __asm__ __volatile__ ("bset %2,(%1); sne %0" 164 : "=d" (retval) 165 : "a" (p), "di" (nr & 7) 166 : "memory"); 167 return retval; 168 } 169 170 static inline int bset_mem_test_and_set_bit(int nr, 171 volatile unsigned long *vaddr) 172 { 173 char *p = (char *)vaddr + (nr ^ 31) / 8; 174 char retval; 175 176 __asm__ __volatile__ ("bset %2,%1; sne %0" 177 : "=d" (retval), "+m" (*p) 178 : "di" (nr & 7)); 179 return retval; 180 } 181 182 static inline int bfset_mem_test_and_set_bit(int nr, 183 volatile unsigned long *vaddr) 184 { 185 char retval; 186 187 __asm__ __volatile__ ("bfset %2{%1:#1}; sne %0" 188 : "=d" (retval) 189 : "d" (nr ^ 31), "o" (*vaddr) 190 : "memory"); 191 return retval; 192 } 193 194 #if defined(CONFIG_COLDFIRE) 195 #define test_and_set_bit(nr, vaddr) bset_reg_test_and_set_bit(nr, vaddr) 196 #elif defined(CONFIG_CPU_HAS_NO_BITFIELDS) 197 #define test_and_set_bit(nr, vaddr) bset_mem_test_and_set_bit(nr, vaddr) 198 #else 199 #define test_and_set_bit(nr, vaddr) (__builtin_constant_p(nr) ? \ 200 bset_mem_test_and_set_bit(nr, vaddr) : \ 201 bfset_mem_test_and_set_bit(nr, vaddr)) 202 #endif 203 204 #define __test_and_set_bit(nr, vaddr) test_and_set_bit(nr, vaddr) 205 206 207 static inline int bclr_reg_test_and_clear_bit(int nr, 208 volatile unsigned long *vaddr) 209 { 210 char *p = (char *)vaddr + (nr ^ 31) / 8; 211 char retval; 212 213 __asm__ __volatile__ ("bclr %2,(%1); sne %0" 214 : "=d" (retval) 215 : "a" (p), "di" (nr & 7) 216 : "memory"); 217 return retval; 218 } 219 220 static inline int bclr_mem_test_and_clear_bit(int nr, 221 volatile unsigned long *vaddr) 222 { 223 char *p = (char *)vaddr + (nr ^ 31) / 8; 224 char retval; 225 226 __asm__ __volatile__ ("bclr %2,%1; sne %0" 227 : "=d" (retval), "+m" (*p) 228 : "di" (nr & 7)); 229 return retval; 230 } 231 232 static inline int bfclr_mem_test_and_clear_bit(int nr, 233 volatile unsigned long *vaddr) 234 { 235 char retval; 236 237 __asm__ __volatile__ ("bfclr %2{%1:#1}; sne %0" 238 : "=d" (retval) 239 : "d" (nr ^ 31), "o" (*vaddr) 240 : "memory"); 241 return retval; 242 } 243 244 #if defined(CONFIG_COLDFIRE) 245 #define test_and_clear_bit(nr, vaddr) bclr_reg_test_and_clear_bit(nr, vaddr) 246 #elif defined(CONFIG_CPU_HAS_NO_BITFIELDS) 247 #define test_and_clear_bit(nr, vaddr) bclr_mem_test_and_clear_bit(nr, vaddr) 248 #else 249 #define test_and_clear_bit(nr, vaddr) (__builtin_constant_p(nr) ? \ 250 bclr_mem_test_and_clear_bit(nr, vaddr) : \ 251 bfclr_mem_test_and_clear_bit(nr, vaddr)) 252 #endif 253 254 #define __test_and_clear_bit(nr, vaddr) test_and_clear_bit(nr, vaddr) 255 256 257 static inline int bchg_reg_test_and_change_bit(int nr, 258 volatile unsigned long *vaddr) 259 { 260 char *p = (char *)vaddr + (nr ^ 31) / 8; 261 char retval; 262 263 __asm__ __volatile__ ("bchg %2,(%1); sne %0" 264 : "=d" (retval) 265 : "a" (p), "di" (nr & 7) 266 : "memory"); 267 return retval; 268 } 269 270 static inline int bchg_mem_test_and_change_bit(int nr, 271 volatile unsigned long *vaddr) 272 { 273 char *p = (char *)vaddr + (nr ^ 31) / 8; 274 char retval; 275 276 __asm__ __volatile__ ("bchg %2,%1; sne %0" 277 : "=d" (retval), "+m" (*p) 278 : "di" (nr & 7)); 279 return retval; 280 } 281 282 static inline int bfchg_mem_test_and_change_bit(int nr, 283 volatile unsigned long *vaddr) 284 { 285 char retval; 286 287 __asm__ __volatile__ ("bfchg %2{%1:#1}; sne %0" 288 : "=d" (retval) 289 : "d" (nr ^ 31), "o" (*vaddr) 290 : "memory"); 291 return retval; 292 } 293 294 #if defined(CONFIG_COLDFIRE) 295 #define test_and_change_bit(nr, vaddr) bchg_reg_test_and_change_bit(nr, vaddr) 296 #elif defined(CONFIG_CPU_HAS_NO_BITFIELDS) 297 #define test_and_change_bit(nr, vaddr) bchg_mem_test_and_change_bit(nr, vaddr) 298 #else 299 #define test_and_change_bit(nr, vaddr) (__builtin_constant_p(nr) ? \ 300 bchg_mem_test_and_change_bit(nr, vaddr) : \ 301 bfchg_mem_test_and_change_bit(nr, vaddr)) 302 #endif 303 304 #define __test_and_change_bit(nr, vaddr) test_and_change_bit(nr, vaddr) 305 306 307 /* 308 * The true 68020 and more advanced processors support the "bfffo" 309 * instruction for finding bits. ColdFire and simple 68000 parts 310 * (including CPU32) do not support this. They simply use the generic 311 * functions. 312 */ 313 #if defined(CONFIG_CPU_HAS_NO_BITFIELDS) 314 #include <asm-generic/bitops/find.h> 315 #include <asm-generic/bitops/ffz.h> 316 #else 317 318 static inline int find_first_zero_bit(const unsigned long *vaddr, 319 unsigned size) 320 { 321 const unsigned long *p = vaddr; 322 int res = 32; 323 unsigned int words; 324 unsigned long num; 325 326 if (!size) 327 return 0; 328 329 words = (size + 31) >> 5; 330 while (!(num = ~*p++)) { 331 if (!--words) 332 goto out; 333 } 334 335 __asm__ __volatile__ ("bfffo %1{#0,#0},%0" 336 : "=d" (res) : "d" (num & -num)); 337 res ^= 31; 338 out: 339 res += ((long)p - (long)vaddr - 4) * 8; 340 return res < size ? res : size; 341 } 342 #define find_first_zero_bit find_first_zero_bit 343 344 static inline int find_next_zero_bit(const unsigned long *vaddr, int size, 345 int offset) 346 { 347 const unsigned long *p = vaddr + (offset >> 5); 348 int bit = offset & 31UL, res; 349 350 if (offset >= size) 351 return size; 352 353 if (bit) { 354 unsigned long num = ~*p++ & (~0UL << bit); 355 offset -= bit; 356 357 /* Look for zero in first longword */ 358 __asm__ __volatile__ ("bfffo %1{#0,#0},%0" 359 : "=d" (res) : "d" (num & -num)); 360 if (res < 32) { 361 offset += res ^ 31; 362 return offset < size ? offset : size; 363 } 364 offset += 32; 365 366 if (offset >= size) 367 return size; 368 } 369 /* No zero yet, search remaining full bytes for a zero */ 370 return offset + find_first_zero_bit(p, size - offset); 371 } 372 #define find_next_zero_bit find_next_zero_bit 373 374 static inline int find_first_bit(const unsigned long *vaddr, unsigned size) 375 { 376 const unsigned long *p = vaddr; 377 int res = 32; 378 unsigned int words; 379 unsigned long num; 380 381 if (!size) 382 return 0; 383 384 words = (size + 31) >> 5; 385 while (!(num = *p++)) { 386 if (!--words) 387 goto out; 388 } 389 390 __asm__ __volatile__ ("bfffo %1{#0,#0},%0" 391 : "=d" (res) : "d" (num & -num)); 392 res ^= 31; 393 out: 394 res += ((long)p - (long)vaddr - 4) * 8; 395 return res < size ? res : size; 396 } 397 #define find_first_bit find_first_bit 398 399 static inline int find_next_bit(const unsigned long *vaddr, int size, 400 int offset) 401 { 402 const unsigned long *p = vaddr + (offset >> 5); 403 int bit = offset & 31UL, res; 404 405 if (offset >= size) 406 return size; 407 408 if (bit) { 409 unsigned long num = *p++ & (~0UL << bit); 410 offset -= bit; 411 412 /* Look for one in first longword */ 413 __asm__ __volatile__ ("bfffo %1{#0,#0},%0" 414 : "=d" (res) : "d" (num & -num)); 415 if (res < 32) { 416 offset += res ^ 31; 417 return offset < size ? offset : size; 418 } 419 offset += 32; 420 421 if (offset >= size) 422 return size; 423 } 424 /* No one yet, search remaining full bytes for a one */ 425 return offset + find_first_bit(p, size - offset); 426 } 427 #define find_next_bit find_next_bit 428 429 /* 430 * ffz = Find First Zero in word. Undefined if no zero exists, 431 * so code should check against ~0UL first.. 432 */ 433 static inline unsigned long ffz(unsigned long word) 434 { 435 int res; 436 437 __asm__ __volatile__ ("bfffo %1{#0,#0},%0" 438 : "=d" (res) : "d" (~word & -~word)); 439 return res ^ 31; 440 } 441 442 #endif 443 444 #ifdef __KERNEL__ 445 446 #if defined(CONFIG_CPU_HAS_NO_BITFIELDS) 447 448 /* 449 * The newer ColdFire family members support a "bitrev" instruction 450 * and we can use that to implement a fast ffs. Older Coldfire parts, 451 * and normal 68000 parts don't have anything special, so we use the 452 * generic functions for those. 453 */ 454 #if (defined(__mcfisaaplus__) || defined(__mcfisac__)) && \ 455 !defined(CONFIG_M68000) && !defined(CONFIG_MCPU32) 456 static inline int __ffs(int x) 457 { 458 __asm__ __volatile__ ("bitrev %0; ff1 %0" 459 : "=d" (x) 460 : "0" (x)); 461 return x; 462 } 463 464 static inline int ffs(int x) 465 { 466 if (!x) 467 return 0; 468 return __ffs(x) + 1; 469 } 470 471 #else 472 #include <asm-generic/bitops/ffs.h> 473 #include <asm-generic/bitops/__ffs.h> 474 #endif 475 476 #include <asm-generic/bitops/fls.h> 477 #include <asm-generic/bitops/__fls.h> 478 479 #else 480 481 /* 482 * ffs: find first bit set. This is defined the same way as 483 * the libc and compiler builtin ffs routines, therefore 484 * differs in spirit from the above ffz (man ffs). 485 */ 486 static inline int ffs(int x) 487 { 488 int cnt; 489 490 __asm__ ("bfffo %1{#0:#0},%0" 491 : "=d" (cnt) 492 : "dm" (x & -x)); 493 return 32 - cnt; 494 } 495 #define __ffs(x) (ffs(x) - 1) 496 497 /* 498 * fls: find last bit set. 499 */ 500 static inline int fls(int x) 501 { 502 int cnt; 503 504 __asm__ ("bfffo %1{#0,#0},%0" 505 : "=d" (cnt) 506 : "dm" (x)); 507 return 32 - cnt; 508 } 509 510 static inline int __fls(int x) 511 { 512 return fls(x) - 1; 513 } 514 515 #endif 516 517 #include <asm-generic/bitops/ext2-atomic.h> 518 #include <asm-generic/bitops/le.h> 519 #include <asm-generic/bitops/fls64.h> 520 #include <asm-generic/bitops/sched.h> 521 #include <asm-generic/bitops/hweight.h> 522 #include <asm-generic/bitops/lock.h> 523 #endif /* __KERNEL__ */ 524 525 #endif /* _M68K_BITOPS_H */ 526