root/include/asm-i386/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. test_bit
  5. find_first_zero_bit
  6. find_next_zero_bit
  7. ffz

   1 #ifndef _I386_BITOPS_H
   2 #define _I386_BITOPS_H
   3 
   4 /*
   5  * Copyright 1992, Linus Torvalds.
   6  */
   7 
   8 /*
   9  * These have to be done with inline assembly: that way the bit-setting
  10  * is guaranteed to be atomic. All bit operations return 0 if the bit
  11  * was cleared before the operation and != 0 if it was not.
  12  *
  13  * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
  14  */
  15 
  16 #ifdef __SMP__
  17 #define LOCK_PREFIX "lock ; "
  18 #else
  19 #define LOCK_PREFIX ""
  20 #endif
  21 
  22 /*
  23  * Some hacks to defeat gcc over-optimizations..
  24  */
  25 struct __dummy { unsigned long a[100]; };
  26 #define ADDR (*(struct __dummy *) addr)
  27 #define CONST_ADDR (*(const struct __dummy *) addr)
  28 
  29 extern __inline__ int set_bit(int nr, void * addr)
     /* [previous][next][first][last][top][bottom][index][help] */
  30 {
  31         int oldbit;
  32 
  33         __asm__ __volatile__(LOCK_PREFIX
  34                 "btsl %2,%1\n\tsbbl %0,%0"
  35                 :"=r" (oldbit),"=m" (ADDR)
  36                 :"ir" (nr));
  37         return oldbit;
  38 }
  39 
  40 extern __inline__ int clear_bit(int nr, void * addr)
     /* [previous][next][first][last][top][bottom][index][help] */
  41 {
  42         int oldbit;
  43 
  44         __asm__ __volatile__(LOCK_PREFIX
  45                 "btrl %2,%1\n\tsbbl %0,%0"
  46                 :"=r" (oldbit),"=m" (ADDR)
  47                 :"ir" (nr));
  48         return oldbit;
  49 }
  50 
  51 extern __inline__ int change_bit(int nr, void * addr)
     /* [previous][next][first][last][top][bottom][index][help] */
  52 {
  53         int oldbit;
  54 
  55         __asm__ __volatile__(LOCK_PREFIX
  56                 "btcl %2,%1\n\tsbbl %0,%0"
  57                 :"=r" (oldbit),"=m" (ADDR)
  58                 :"ir" (nr));
  59         return oldbit;
  60 }
  61 
  62 /*
  63  * This routine doesn't need to be atomic, but it's faster to code it
  64  * this way.
  65  */
  66 extern __inline__ int test_bit(int nr, const void * addr)
     /* [previous][next][first][last][top][bottom][index][help] */
  67 {
  68         int oldbit;
  69 
  70         __asm__ __volatile__("btl %2,%1\n\tsbbl %0,%0"
  71                 :"=r" (oldbit)
  72                 :"m" (CONST_ADDR),"ir" (nr));
  73         return oldbit;
  74 }
  75 
  76 /*
  77  * Find-bit routines..
  78  */
  79 extern __inline__ int find_first_zero_bit(void * addr, unsigned size)
     /* [previous][next][first][last][top][bottom][index][help] */
  80 {
  81         int res;
  82 
  83         if (!size)
  84                 return 0;
  85         __asm__("
  86                 cld
  87                 movl $-1,%%eax
  88                 xorl %%edx,%%edx
  89                 repe; scasl
  90                 je 1f
  91                 xorl -4(%%edi),%%eax
  92                 subl $4,%%edi
  93                 bsfl %%eax,%%edx
  94 1:              subl %%ebx,%%edi
  95                 shll $3,%%edi
  96                 addl %%edi,%%edx"
  97                 :"=d" (res)
  98                 :"c" ((size + 31) >> 5), "D" (addr), "b" (addr)
  99                 :"ax", "cx", "di");
 100         return res;
 101 }
 102 
 103 extern __inline__ int find_next_zero_bit (void * addr, int size, int offset)
     /* [previous][next][first][last][top][bottom][index][help] */
 104 {
 105         unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
 106         int set = 0, bit = offset & 31, res;
 107         
 108         if (bit) {
 109                 /*
 110                  * Look for zero in first byte
 111                  */
 112                 __asm__("
 113                         bsfl %1,%0
 114                         jne 1f
 115                         movl $32, %0
 116 1:                      "
 117                         : "=r" (set)
 118                         : "r" (~(*p >> bit)));
 119                 if (set < (32 - bit))
 120                         return set + offset;
 121                 set = 32 - bit;
 122                 p++;
 123         }
 124         /*
 125          * No zero yet, search remaining full bytes for a zero
 126          */
 127         res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr));
 128         return (offset + set + res);
 129 }
 130 
 131 /*
 132  * ffz = Find First Zero in word. Undefined if no zero exists,
 133  * so code should check against ~0UL first..
 134  */
 135 extern __inline__ unsigned long ffz(unsigned long word)
     /* [previous][next][first][last][top][bottom][index][help] */
 136 {
 137         __asm__("bsfl %1,%0"
 138                 :"=r" (word)
 139                 :"r" (~word));
 140         return word;
 141 }
 142 
 143 #endif /* _I386_BITOPS_H */

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