bitops.h (12621B)
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 31static 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 41static 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 50static 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 71static 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 81static 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 90static 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 111static 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 121static 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 130static 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 151static inline int test_bit(int nr, const volatile unsigned long *vaddr) 152{ 153 return (vaddr[nr >> 5] & (1UL << (nr & 31))) != 0; 154} 155 156 157static 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 170static 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 182static 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 207static 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 220static 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 232static 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 257static 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 270static 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 282static 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/ffz.h> 315#else 316 317static inline int find_first_zero_bit(const unsigned long *vaddr, 318 unsigned size) 319{ 320 const unsigned long *p = vaddr; 321 int res = 32; 322 unsigned int words; 323 unsigned long num; 324 325 if (!size) 326 return 0; 327 328 words = (size + 31) >> 5; 329 while (!(num = ~*p++)) { 330 if (!--words) 331 goto out; 332 } 333 334 __asm__ __volatile__ ("bfffo %1{#0,#0},%0" 335 : "=d" (res) : "d" (num & -num)); 336 res ^= 31; 337out: 338 res += ((long)p - (long)vaddr - 4) * 8; 339 return res < size ? res : size; 340} 341#define find_first_zero_bit find_first_zero_bit 342 343static inline int find_next_zero_bit(const unsigned long *vaddr, int size, 344 int offset) 345{ 346 const unsigned long *p = vaddr + (offset >> 5); 347 int bit = offset & 31UL, res; 348 349 if (offset >= size) 350 return size; 351 352 if (bit) { 353 unsigned long num = ~*p++ & (~0UL << bit); 354 offset -= bit; 355 356 /* Look for zero in first longword */ 357 __asm__ __volatile__ ("bfffo %1{#0,#0},%0" 358 : "=d" (res) : "d" (num & -num)); 359 if (res < 32) { 360 offset += res ^ 31; 361 return offset < size ? offset : size; 362 } 363 offset += 32; 364 365 if (offset >= size) 366 return size; 367 } 368 /* No zero yet, search remaining full bytes for a zero */ 369 return offset + find_first_zero_bit(p, size - offset); 370} 371#define find_next_zero_bit find_next_zero_bit 372 373static inline int find_first_bit(const unsigned long *vaddr, unsigned size) 374{ 375 const unsigned long *p = vaddr; 376 int res = 32; 377 unsigned int words; 378 unsigned long num; 379 380 if (!size) 381 return 0; 382 383 words = (size + 31) >> 5; 384 while (!(num = *p++)) { 385 if (!--words) 386 goto out; 387 } 388 389 __asm__ __volatile__ ("bfffo %1{#0,#0},%0" 390 : "=d" (res) : "d" (num & -num)); 391 res ^= 31; 392out: 393 res += ((long)p - (long)vaddr - 4) * 8; 394 return res < size ? res : size; 395} 396#define find_first_bit find_first_bit 397 398static inline int find_next_bit(const unsigned long *vaddr, int size, 399 int offset) 400{ 401 const unsigned long *p = vaddr + (offset >> 5); 402 int bit = offset & 31UL, res; 403 404 if (offset >= size) 405 return size; 406 407 if (bit) { 408 unsigned long num = *p++ & (~0UL << bit); 409 offset -= bit; 410 411 /* Look for one in first longword */ 412 __asm__ __volatile__ ("bfffo %1{#0,#0},%0" 413 : "=d" (res) : "d" (num & -num)); 414 if (res < 32) { 415 offset += res ^ 31; 416 return offset < size ? offset : size; 417 } 418 offset += 32; 419 420 if (offset >= size) 421 return size; 422 } 423 /* No one yet, search remaining full bytes for a one */ 424 return offset + find_first_bit(p, size - offset); 425} 426#define find_next_bit find_next_bit 427 428/* 429 * ffz = Find First Zero in word. Undefined if no zero exists, 430 * so code should check against ~0UL first.. 431 */ 432static inline unsigned long ffz(unsigned long word) 433{ 434 int res; 435 436 __asm__ __volatile__ ("bfffo %1{#0,#0},%0" 437 : "=d" (res) : "d" (~word & -~word)); 438 return res ^ 31; 439} 440 441#endif 442 443#ifdef __KERNEL__ 444 445#if defined(CONFIG_CPU_HAS_NO_BITFIELDS) 446 447/* 448 * The newer ColdFire family members support a "bitrev" instruction 449 * and we can use that to implement a fast ffs. Older Coldfire parts, 450 * and normal 68000 parts don't have anything special, so we use the 451 * generic functions for those. 452 */ 453#if (defined(__mcfisaaplus__) || defined(__mcfisac__)) && \ 454 !defined(CONFIG_M68000) 455static inline unsigned long __ffs(unsigned long x) 456{ 457 __asm__ __volatile__ ("bitrev %0; ff1 %0" 458 : "=d" (x) 459 : "0" (x)); 460 return x; 461} 462 463static inline int ffs(int x) 464{ 465 if (!x) 466 return 0; 467 return __ffs(x) + 1; 468} 469 470#else 471#include <asm-generic/bitops/ffs.h> 472#include <asm-generic/bitops/__ffs.h> 473#endif 474 475#include <asm-generic/bitops/fls.h> 476#include <asm-generic/bitops/__fls.h> 477 478#else 479 480/* 481 * ffs: find first bit set. This is defined the same way as 482 * the libc and compiler builtin ffs routines, therefore 483 * differs in spirit from the above ffz (man ffs). 484 */ 485static inline int ffs(int x) 486{ 487 int cnt; 488 489 __asm__ ("bfffo %1{#0:#0},%0" 490 : "=d" (cnt) 491 : "dm" (x & -x)); 492 return 32 - cnt; 493} 494 495static inline unsigned long __ffs(unsigned long x) 496{ 497 return ffs(x) - 1; 498} 499 500/* 501 * fls: find last bit set. 502 */ 503static inline int fls(unsigned int x) 504{ 505 int cnt; 506 507 __asm__ ("bfffo %1{#0,#0},%0" 508 : "=d" (cnt) 509 : "dm" (x)); 510 return 32 - cnt; 511} 512 513static inline int __fls(int x) 514{ 515 return fls(x) - 1; 516} 517 518#endif 519 520/* Simple test-and-set bit locks */ 521#define test_and_set_bit_lock test_and_set_bit 522#define clear_bit_unlock clear_bit 523#define __clear_bit_unlock clear_bit_unlock 524 525#include <asm-generic/bitops/ext2-atomic.h> 526#include <asm-generic/bitops/fls64.h> 527#include <asm-generic/bitops/sched.h> 528#include <asm-generic/bitops/hweight.h> 529#include <asm-generic/bitops/le.h> 530#endif /* __KERNEL__ */ 531 532#endif /* _M68K_BITOPS_H */