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. find_first_zero_bit
  5. test_bit
  6. find_next_zero_bit
  7. 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 by Ralf Baechle
   9  */
  10 #ifndef __ASM_MIPS_BITOPS_H
  11 #define __ASM_MIPS_BITOPS_H
  12 
  13 #include <asm/mipsregs.h>
  14 
  15 #if defined(__R4000__)
  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 extern __inline__ int find_first_zero_bit (void *addr, unsigned size)
     /* [previous][next][first][last][top][bottom][index][help] */
  66 {
  67         int res;
  68 
  69         if (!size)
  70                 return 0;
  71 
  72         __asm__(".set\tnoreorder\n\t"
  73                 ".set\tnoat\n"
  74                 "1:\tsubu\t$1,%2,%0\n\t"
  75                 "blez\t$1,2f\n\t"
  76                 "lw\t$1,(%4)\n\t"
  77                 "addiu\t%4,%4,4\n\t"
  78                 "beql\t%1,$1,1b\n\t"
  79                 "addiu\t%0,%0,32\n\t"
  80                 "li\t%1,1\n"
  81                 "1:\tand\t%4,$1,%1\n\t"
  82                 "beq\t$0,%4,2f\n\t"
  83                 "sll\t%1,%1,1\n\t"
  84                 "bne\t$0,%1,1b\n\t"
  85                 "add\t%0,%0,1\n\t"
  86                 ".set\tat\n\t"
  87                 ".set\treorder\n"
  88                 "2:"
  89                 : "=d" (res)
  90                 : "d" ((unsigned int) 0xffffffff),
  91                   "d" (size),
  92                   "0" ((signed int) 0),
  93                   "d" (addr)
  94                 : "$1");
  95 
  96         return res;
  97 }
  98 
  99 #else /* !defined(__R4000__) */
 100 
 101 #define __USE_PORTABLE_STRINGS_H
 102 
 103 #define __USE_GENERIC_set_bit
 104 #define __USE_GENERIC_clear_bit
 105 #define __USE_GENERIC_change_bit
 106 #define __USE_GENERIC_find_first_zero_bit
 107 
 108 #endif /* !defined(__R4000__) */
 109 
 110 extern __inline__ int test_bit(int nr, void *addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 111 {
 112         int     mask;
 113         unsigned long   *a;
 114 
 115         a = addr;
 116         addr += nr >> 5;
 117         mask = 1 << (nr & 0x1f);
 118         return ((mask & *a) != 0);
 119 }
 120 
 121 extern __inline__ int find_next_zero_bit (void * addr, int size, int offset)
     /* [previous][next][first][last][top][bottom][index][help] */
 122 {
 123         unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
 124         int set = 0, bit = offset & 31, res;
 125         
 126         if (bit) {
 127                 /*
 128                  * Look for zero in first byte
 129                  */
 130                 __asm__(".set\tnoreorder\n\t"
 131                         ".set\tnoat\n"
 132                         "1:\tand\t$1,%2,%1\n\t"
 133                         "beq\t$0,$1,2f\n\t"
 134                         "sll\t%2,%2,1\n\t"
 135                         "bne\t$0,%2,1b\n\t"
 136                         "addiu\t%0,%0,1\n\t"
 137                         ".set\tat\n\t"
 138                         ".set\treorder\n"
 139                         : "=r" (set)
 140                         : "r" (*p >> bit),
 141                           "r" (1),
 142                           "0" (0)
 143                         : "$1");
 144                 if (set < (32 - bit))
 145                         return set + offset;
 146                 set = 32 - bit;
 147                 p++;
 148         }
 149         /*
 150          * No zero yet, search remaining full bytes for a zero
 151          */
 152         res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr));
 153         return (offset + set + res);
 154 }
 155 
 156 /*
 157  * ffz = Find First Zero in word. Undefined if no zero exists,
 158  * so code should check against ~0UL first..
 159  */
 160 extern __inline__ unsigned long ffz(unsigned long word)
     /* [previous][next][first][last][top][bottom][index][help] */
 161 {
 162         unsigned int    __res;
 163         unsigned int    mask = 1;
 164 
 165         __asm__ __volatile__ (
 166                 ".set\tnoreorder\n\t"
 167                 ".set\tnoat\n\t"
 168                 "li\t%2,1\n"
 169                 "1:\tand\t$1,%2,%1\n\t"
 170                 "beq\t$0,$1,2f\n\t"
 171                 "sll\t%2,%2,1\n\t"
 172                 "bne\t$0,%2,1b\n\t"
 173                 "add\t%0,%0,1\n\t"
 174                 ".set\tat\n\t"
 175                 ".set\treorder\n"
 176                 "2:\n\t"
 177                 : "=r" (__res), "=r" (word), "=r" (mask)
 178                 : "1" (~(word)),
 179                   "2" (mask),
 180                   "0" (0)
 181                 : "$1");
 182 
 183         return __res;
 184 }
 185 
 186 #ifdef __USE_PORTABLE_BITOPS_H
 187 #include <asm-generic/bitops.h>
 188 #endif
 189 
 190 #endif /* __ASM_MIPS_BITOPS_H */

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