This source file includes following definitions.
- set_bit
 
- clear_bit
 
- change_bit
 
- set_bit
 
- clear_bit
 
- change_bit
 
- test_bit
 
- find_first_zero_bit
 
- find_next_zero_bit
 
- ffz
 
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 #ifndef __ASM_MIPS_BITOPS_H
  11 #define __ASM_MIPS_BITOPS_H
  12 
  13 #ifdef __R4000__
  14 
  15 #include <asm/mipsregs.h>
  16 
  17 
  18 
  19 
  20 extern __inline__ int set_bit(int nr, void *addr)
     
  21 {
  22         int     mask, retval, mw;
  23 
  24         addr += ((nr >> 3) & ~3);
  25         mask = 1 << (nr & 0x1f);
  26         do {
  27                 mw = load_linked(addr);
  28                 retval = (mask & mw) != 0;
  29                 }
  30         while (!store_conditional(addr, mw|mask));
  31 
  32         return retval;
  33 }
  34 
  35 extern __inline__ int clear_bit(int nr, void *addr)
     
  36 {
  37         int     mask, retval, mw;
  38 
  39         addr += ((nr >> 3) & ~3);
  40         mask = 1 << (nr & 0x1f);
  41         do {
  42                 mw = load_linked(addr);
  43                 retval = (mask & mw) != 0;
  44                 }
  45         while (!store_conditional(addr, mw & ~mask));
  46 
  47         return retval;
  48 }
  49 
  50 extern __inline__ int change_bit(int nr, void *addr)
     
  51 {
  52         int     mask, retval, mw;
  53 
  54         addr += ((nr >> 3) & ~3);
  55         mask = 1 << (nr & 0x1f);
  56         do {
  57                 mw = load_linked(addr);
  58                 retval = (mask & mw) != 0;
  59                 }
  60         while (!store_conditional(addr, mw ^ mask));
  61 
  62         return retval;
  63 }
  64 
  65 #else 
  66 
  67 #include <asm/system.h>
  68 
  69 #ifdef __KERNEL__
  70 
  71 
  72 
  73 
  74 #define __flags unsigned long flags
  75 #define __cli() cli()
  76 #define __save_flags(x) save_flags(x)
  77 #define __restore_flags(x) restore_flags(x)
  78 #endif 
  79 
  80 extern __inline__ int set_bit(int nr, void * addr)
     
  81 {
  82         int     mask, retval;
  83         int     *a = addr;
  84         __flags;
  85 
  86         a += nr >> 5;
  87         mask = 1 << (nr & 0x1f);
  88         __save_flags(flags);
  89         __cli();
  90         retval = (mask & *a) != 0;
  91         *a |= mask;
  92         __restore_flags(flags);
  93 
  94         return retval;
  95 }
  96 
  97 extern __inline__ int clear_bit(int nr, void * addr)
     
  98 {
  99         int     mask, retval;
 100         int     *a = addr;
 101         __flags;
 102 
 103         a += nr >> 5;
 104         mask = 1 << (nr & 0x1f);
 105         __save_flags(flags);
 106         __cli();
 107         retval = (mask & *a) != 0;
 108         *a &= ~mask;
 109         __restore_flags(flags);
 110 
 111         return retval;
 112 }
 113 
 114 extern __inline__ int change_bit(int nr, void * addr)
     
 115 {
 116         int     mask, retval;
 117         int     *a = addr;
 118         __flags;
 119 
 120         a += nr >> 5;
 121         mask = 1 << (nr & 0x1f);
 122         __save_flags(flags);
 123         __cli();
 124         retval = (mask & *a) != 0;
 125         *a ^= mask;
 126         __restore_flags(flags);
 127 
 128         return retval;
 129 }
 130 
 131 #undef __flags
 132 #undef __cli()
 133 #undef __save_flags(x)
 134 #undef __restore_flags(x)
 135 
 136 #endif 
 137 
 138 extern __inline__ int test_bit(int nr, void *addr)
     
 139 {
 140         int     mask;
 141         unsigned long   *a;
 142 
 143         a = addr;
 144         addr += nr >> 5;
 145         mask = 1 << (nr & 0x1f);
 146         return ((mask & *a) != 0);
 147 }
 148 
 149 extern __inline__ int find_first_zero_bit (void *addr, unsigned size)
     
 150 {
 151         int res;
 152 
 153         if (!size)
 154                 return 0;
 155 
 156         __asm__(".set\tnoreorder\n\t"
 157                 ".set\tnoat\n"
 158                 "1:\tsubu\t$1,%2,%0\n\t"
 159                 "blez\t$1,2f\n\t"
 160                 "lw\t$1,(%4)\n\t"
 161                 "addiu\t%4,%4,4\n\t"
 162                 "beql\t%1,$1,1b\n\t"
 163                 "addiu\t%0,%0,32\n\t"
 164                 "li\t%1,1\n"
 165                 "1:\tand\t%4,$1,%1\n\t"
 166                 "beq\t$0,%4,2f\n\t"
 167                 "sll\t%1,%1,1\n\t"
 168                 "bne\t$0,%1,1b\n\t"
 169                 "add\t%0,%0,1\n\t"
 170                 ".set\tat\n\t"
 171                 ".set\treorder\n"
 172                 "2:"
 173                 : "=r" (res)
 174                 : "r" ((unsigned int) 0xffffffff),
 175                   "r" (size),
 176                   "0" ((signed int) 0),
 177                   "r" (addr)
 178                 : "$1");
 179 
 180         return res;
 181 }
 182 
 183 extern __inline__ int find_next_zero_bit (void * addr, int size, int offset)
     
 184 {
 185         unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
 186         int set = 0, bit = offset & 31, res;
 187         
 188         if (bit) {
 189                 
 190 
 191 
 192                 __asm__(".set\tnoreorder\n\t"
 193                         ".set\tnoat\n"
 194                         "1:\tand\t$1,%2,%1\n\t"
 195                         "beq\t$0,$1,2f\n\t"
 196                         "sll\t%2,%2,1\n\t"
 197                         "bne\t$0,%2,1b\n\t"
 198                         "addiu\t%0,%0,1\n\t"
 199                         ".set\tat\n\t"
 200                         ".set\treorder\n"
 201                         : "=r" (set)
 202                         : "r" (*p >> bit),
 203                           "r" (1),
 204                           "0" (0)
 205                         : "$1");
 206                 if (set < (32 - bit))
 207                         return set + offset;
 208                 set = 32 - bit;
 209                 p++;
 210         }
 211         
 212 
 213 
 214         res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr));
 215         return (offset + set + res);
 216 }
 217 
 218 
 219 
 220 
 221 
 222 extern __inline__ unsigned long ffz(unsigned long word)
     
 223 {
 224         unsigned int    __res;
 225         unsigned int    mask = 1;
 226 
 227         __asm__ __volatile__ (
 228                 ".set\tnoreorder\n\t"
 229                 ".set\tnoat\n\t"
 230                 "li\t%2,1\n"
 231                 "1:\tand\t$1,%2,%1\n\t"
 232                 "beq\t$0,$1,2f\n\t"
 233                 "sll\t%2,%2,1\n\t"
 234                 "bne\t$0,%2,1b\n\t"
 235                 "add\t%0,%0,1\n\t"
 236                 ".set\tat\n\t"
 237                 ".set\treorder\n"
 238                 "2:\n\t"
 239                 : "=r" (__res), "=r" (word), "=r" (mask)
 240                 : "1" (~(word)),
 241                   "2" (mask),
 242                   "0" (0)
 243                 : "$1");
 244 
 245         return __res;
 246 }
 247 
 248 #endif