root/arch/xtensa/include/asm/bitops.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. __cntlz
  2. ffz
  3. __ffs
  4. ffs
  5. fls
  6. __fls
  7. set_bit
  8. clear_bit
  9. change_bit
  10. test_and_set_bit
  11. test_and_clear_bit
  12. test_and_change_bit
  13. set_bit
  14. clear_bit
  15. change_bit
  16. test_and_set_bit
  17. test_and_clear_bit
  18. test_and_change_bit

   1 /*
   2  * include/asm-xtensa/bitops.h
   3  *
   4  * Atomic operations that C can't guarantee us.Useful for resource counting etc.
   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  * Copyright (C) 2001 - 2007 Tensilica Inc.
  11  */
  12 
  13 #ifndef _XTENSA_BITOPS_H
  14 #define _XTENSA_BITOPS_H
  15 
  16 #ifndef _LINUX_BITOPS_H
  17 #error only <linux/bitops.h> can be included directly
  18 #endif
  19 
  20 #include <asm/processor.h>
  21 #include <asm/byteorder.h>
  22 #include <asm/barrier.h>
  23 
  24 #include <asm-generic/bitops/non-atomic.h>
  25 
  26 #if XCHAL_HAVE_NSA
  27 
  28 static inline unsigned long __cntlz (unsigned long x)
  29 {
  30         int lz;
  31         asm ("nsau %0, %1" : "=r" (lz) : "r" (x));
  32         return lz;
  33 }
  34 
  35 /*
  36  * ffz: Find first zero in word. Undefined if no zero exists.
  37  * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
  38  */
  39 
  40 static inline int ffz(unsigned long x)
  41 {
  42         return 31 - __cntlz(~x & -~x);
  43 }
  44 
  45 /*
  46  * __ffs: Find first bit set in word. Return 0 for bit 0
  47  */
  48 
  49 static inline unsigned long __ffs(unsigned long x)
  50 {
  51         return 31 - __cntlz(x & -x);
  52 }
  53 
  54 /*
  55  * ffs: Find first bit set in word. This is defined the same way as
  56  * the libc and compiler builtin ffs routines, therefore
  57  * differs in spirit from the above ffz (man ffs).
  58  */
  59 
  60 static inline int ffs(unsigned long x)
  61 {
  62         return 32 - __cntlz(x & -x);
  63 }
  64 
  65 /*
  66  * fls: Find last (most-significant) bit set in word.
  67  * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
  68  */
  69 
  70 static inline int fls (unsigned int x)
  71 {
  72         return 32 - __cntlz(x);
  73 }
  74 
  75 /**
  76  * __fls - find last (most-significant) set bit in a long word
  77  * @word: the word to search
  78  *
  79  * Undefined if no set bit exists, so code should check against 0 first.
  80  */
  81 static inline unsigned long __fls(unsigned long word)
  82 {
  83         return 31 - __cntlz(word);
  84 }
  85 #else
  86 
  87 /* Use the generic implementation if we don't have the nsa/nsau instructions. */
  88 
  89 # include <asm-generic/bitops/ffs.h>
  90 # include <asm-generic/bitops/__ffs.h>
  91 # include <asm-generic/bitops/ffz.h>
  92 # include <asm-generic/bitops/fls.h>
  93 # include <asm-generic/bitops/__fls.h>
  94 
  95 #endif
  96 
  97 #include <asm-generic/bitops/fls64.h>
  98 
  99 #if XCHAL_HAVE_EXCLUSIVE
 100 
 101 static inline void set_bit(unsigned int bit, volatile unsigned long *p)
 102 {
 103         unsigned long tmp;
 104         unsigned long mask = 1UL << (bit & 31);
 105 
 106         p += bit >> 5;
 107 
 108         __asm__ __volatile__(
 109                         "1:     l32ex   %0, %2\n"
 110                         "       or      %0, %0, %1\n"
 111                         "       s32ex   %0, %2\n"
 112                         "       getex   %0\n"
 113                         "       beqz    %0, 1b\n"
 114                         : "=&a" (tmp)
 115                         : "a" (mask), "a" (p)
 116                         : "memory");
 117 }
 118 
 119 static inline void clear_bit(unsigned int bit, volatile unsigned long *p)
 120 {
 121         unsigned long tmp;
 122         unsigned long mask = 1UL << (bit & 31);
 123 
 124         p += bit >> 5;
 125 
 126         __asm__ __volatile__(
 127                         "1:     l32ex   %0, %2\n"
 128                         "       and     %0, %0, %1\n"
 129                         "       s32ex   %0, %2\n"
 130                         "       getex   %0\n"
 131                         "       beqz    %0, 1b\n"
 132                         : "=&a" (tmp)
 133                         : "a" (~mask), "a" (p)
 134                         : "memory");
 135 }
 136 
 137 static inline void change_bit(unsigned int bit, volatile unsigned long *p)
 138 {
 139         unsigned long tmp;
 140         unsigned long mask = 1UL << (bit & 31);
 141 
 142         p += bit >> 5;
 143 
 144         __asm__ __volatile__(
 145                         "1:     l32ex   %0, %2\n"
 146                         "       xor     %0, %0, %1\n"
 147                         "       s32ex   %0, %2\n"
 148                         "       getex   %0\n"
 149                         "       beqz    %0, 1b\n"
 150                         : "=&a" (tmp)
 151                         : "a" (mask), "a" (p)
 152                         : "memory");
 153 }
 154 
 155 static inline int
 156 test_and_set_bit(unsigned int bit, volatile unsigned long *p)
 157 {
 158         unsigned long tmp, value;
 159         unsigned long mask = 1UL << (bit & 31);
 160 
 161         p += bit >> 5;
 162 
 163         __asm__ __volatile__(
 164                         "1:     l32ex   %1, %3\n"
 165                         "       or      %0, %1, %2\n"
 166                         "       s32ex   %0, %3\n"
 167                         "       getex   %0\n"
 168                         "       beqz    %0, 1b\n"
 169                         : "=&a" (tmp), "=&a" (value)
 170                         : "a" (mask), "a" (p)
 171                         : "memory");
 172 
 173         return value & mask;
 174 }
 175 
 176 static inline int
 177 test_and_clear_bit(unsigned int bit, volatile unsigned long *p)
 178 {
 179         unsigned long tmp, value;
 180         unsigned long mask = 1UL << (bit & 31);
 181 
 182         p += bit >> 5;
 183 
 184         __asm__ __volatile__(
 185                         "1:     l32ex   %1, %3\n"
 186                         "       and     %0, %1, %2\n"
 187                         "       s32ex   %0, %3\n"
 188                         "       getex   %0\n"
 189                         "       beqz    %0, 1b\n"
 190                         : "=&a" (tmp), "=&a" (value)
 191                         : "a" (~mask), "a" (p)
 192                         : "memory");
 193 
 194         return value & mask;
 195 }
 196 
 197 static inline int
 198 test_and_change_bit(unsigned int bit, volatile unsigned long *p)
 199 {
 200         unsigned long tmp, value;
 201         unsigned long mask = 1UL << (bit & 31);
 202 
 203         p += bit >> 5;
 204 
 205         __asm__ __volatile__(
 206                         "1:     l32ex   %1, %3\n"
 207                         "       xor     %0, %1, %2\n"
 208                         "       s32ex   %0, %3\n"
 209                         "       getex   %0\n"
 210                         "       beqz    %0, 1b\n"
 211                         : "=&a" (tmp), "=&a" (value)
 212                         : "a" (mask), "a" (p)
 213                         : "memory");
 214 
 215         return value & mask;
 216 }
 217 
 218 #elif XCHAL_HAVE_S32C1I
 219 
 220 static inline void set_bit(unsigned int bit, volatile unsigned long *p)
 221 {
 222         unsigned long tmp, value;
 223         unsigned long mask = 1UL << (bit & 31);
 224 
 225         p += bit >> 5;
 226 
 227         __asm__ __volatile__(
 228                         "1:     l32i    %1, %3, 0\n"
 229                         "       wsr     %1, scompare1\n"
 230                         "       or      %0, %1, %2\n"
 231                         "       s32c1i  %0, %3, 0\n"
 232                         "       bne     %0, %1, 1b\n"
 233                         : "=&a" (tmp), "=&a" (value)
 234                         : "a" (mask), "a" (p)
 235                         : "memory");
 236 }
 237 
 238 static inline void clear_bit(unsigned int bit, volatile unsigned long *p)
 239 {
 240         unsigned long tmp, value;
 241         unsigned long mask = 1UL << (bit & 31);
 242 
 243         p += bit >> 5;
 244 
 245         __asm__ __volatile__(
 246                         "1:     l32i    %1, %3, 0\n"
 247                         "       wsr     %1, scompare1\n"
 248                         "       and     %0, %1, %2\n"
 249                         "       s32c1i  %0, %3, 0\n"
 250                         "       bne     %0, %1, 1b\n"
 251                         : "=&a" (tmp), "=&a" (value)
 252                         : "a" (~mask), "a" (p)
 253                         : "memory");
 254 }
 255 
 256 static inline void change_bit(unsigned int bit, volatile unsigned long *p)
 257 {
 258         unsigned long tmp, value;
 259         unsigned long mask = 1UL << (bit & 31);
 260 
 261         p += bit >> 5;
 262 
 263         __asm__ __volatile__(
 264                         "1:     l32i    %1, %3, 0\n"
 265                         "       wsr     %1, scompare1\n"
 266                         "       xor     %0, %1, %2\n"
 267                         "       s32c1i  %0, %3, 0\n"
 268                         "       bne     %0, %1, 1b\n"
 269                         : "=&a" (tmp), "=&a" (value)
 270                         : "a" (mask), "a" (p)
 271                         : "memory");
 272 }
 273 
 274 static inline int
 275 test_and_set_bit(unsigned int bit, volatile unsigned long *p)
 276 {
 277         unsigned long tmp, value;
 278         unsigned long mask = 1UL << (bit & 31);
 279 
 280         p += bit >> 5;
 281 
 282         __asm__ __volatile__(
 283                         "1:     l32i    %1, %3, 0\n"
 284                         "       wsr     %1, scompare1\n"
 285                         "       or      %0, %1, %2\n"
 286                         "       s32c1i  %0, %3, 0\n"
 287                         "       bne     %0, %1, 1b\n"
 288                         : "=&a" (tmp), "=&a" (value)
 289                         : "a" (mask), "a" (p)
 290                         : "memory");
 291 
 292         return tmp & mask;
 293 }
 294 
 295 static inline int
 296 test_and_clear_bit(unsigned int bit, volatile unsigned long *p)
 297 {
 298         unsigned long tmp, value;
 299         unsigned long mask = 1UL << (bit & 31);
 300 
 301         p += bit >> 5;
 302 
 303         __asm__ __volatile__(
 304                         "1:     l32i    %1, %3, 0\n"
 305                         "       wsr     %1, scompare1\n"
 306                         "       and     %0, %1, %2\n"
 307                         "       s32c1i  %0, %3, 0\n"
 308                         "       bne     %0, %1, 1b\n"
 309                         : "=&a" (tmp), "=&a" (value)
 310                         : "a" (~mask), "a" (p)
 311                         : "memory");
 312 
 313         return tmp & mask;
 314 }
 315 
 316 static inline int
 317 test_and_change_bit(unsigned int bit, volatile unsigned long *p)
 318 {
 319         unsigned long tmp, value;
 320         unsigned long mask = 1UL << (bit & 31);
 321 
 322         p += bit >> 5;
 323 
 324         __asm__ __volatile__(
 325                         "1:     l32i    %1, %3, 0\n"
 326                         "       wsr     %1, scompare1\n"
 327                         "       xor     %0, %1, %2\n"
 328                         "       s32c1i  %0, %3, 0\n"
 329                         "       bne     %0, %1, 1b\n"
 330                         : "=&a" (tmp), "=&a" (value)
 331                         : "a" (mask), "a" (p)
 332                         : "memory");
 333 
 334         return tmp & mask;
 335 }
 336 
 337 #else
 338 
 339 #include <asm-generic/bitops/atomic.h>
 340 
 341 #endif /* XCHAL_HAVE_S32C1I */
 342 
 343 #include <asm-generic/bitops/find.h>
 344 #include <asm-generic/bitops/le.h>
 345 
 346 #include <asm-generic/bitops/ext2-atomic-setbit.h>
 347 
 348 #include <asm-generic/bitops/hweight.h>
 349 #include <asm-generic/bitops/lock.h>
 350 #include <asm-generic/bitops/sched.h>
 351 
 352 #endif  /* _XTENSA_BITOPS_H */

/* [<][>][^][v][top][bottom][index][help] */