root/include/asm-mips/bitops.h

/* [previous][next][first][last][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. set_bit
  2. clear_bit
  3. change_bit
  4. set_bit
  5. clear_bit
  6. change_bit
  7. test_bit
  8. find_first_zero_bit
  9. find_next_zero_bit
  10. ffz

   1 /*
   2  * include/asm-mips/bitops.h
   3  *
   4  * This file is subject to the terms and conditions of the GNU General Public
   5  * License.  See the file "COPYING" in the main directory of this archive
   6  * for more details.
   7  *
   8  * Copyright (c) 1994, 1995  Ralf Baechle
   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  * The following functions will only work for the R4000!
  19  */
  20 extern __inline__ int set_bit(int nr, void *addr)
     /* [previous][next][first][last][top][bottom][index][help] */
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
  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 /* !defined(__R4000__) */
  66 
  67 #include <asm/system.h>
  68 
  69 #ifdef __KERNEL__
  70 /*
  71  * Only disable interrupt for kernelmode stuff to keep some
  72  * usermode stuff alive
  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 /* __KERNEL__ */
  79 
  80 extern __inline__ int set_bit(int nr, void * addr)
     /* [previous][next][first][last][top][bottom][index][help] */
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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 /* !defined(__R4000__) */
 137 
 138 extern __inline__ int test_bit(int nr, void *addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 184 {
 185         unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
 186         int set = 0, bit = offset & 31, res;
 187         
 188         if (bit) {
 189                 /*
 190                  * Look for zero in first byte
 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          * No zero yet, search remaining full bytes for a zero
 213          */
 214         res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr));
 215         return (offset + set + res);
 216 }
 217 
 218 /*
 219  * ffz = Find First Zero in word. Undefined if no zero exists,
 220  * so code should check against ~0UL first..
 221  */
 222 extern __inline__ unsigned long ffz(unsigned long word)
     /* [previous][next][first][last][top][bottom][index][help] */
 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 /* __ASM_MIPS_BITOPS_H */

/* [previous][next][first][last][top][bottom][index][help] */