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.
  64  */
  65 extern __inline__ int test_bit(int nr, const void * addr)
     /* [previous][next][first][last][top][bottom][index][help] */
  66 {
  67         return 1UL & (((const unsigned int *) addr)[nr >> 5] >> (nr & 31));
  68 }
  69 
  70 /*
  71  * Find-bit routines..
  72  */
  73 extern __inline__ int find_first_zero_bit(void * addr, unsigned size)
     /* [previous][next][first][last][top][bottom][index][help] */
  74 {
  75         int res;
  76 
  77         if (!size)
  78                 return 0;
  79         __asm__("
  80                 cld
  81                 movl $-1,%%eax
  82                 xorl %%edx,%%edx
  83                 repe; scasl
  84                 je 1f
  85                 xorl -4(%%edi),%%eax
  86                 subl $4,%%edi
  87                 bsfl %%eax,%%edx
  88 1:              subl %%ebx,%%edi
  89                 shll $3,%%edi
  90                 addl %%edi,%%edx"
  91                 :"=d" (res)
  92                 :"c" ((size + 31) >> 5), "D" (addr), "b" (addr)
  93                 :"ax", "cx", "di");
  94         return res;
  95 }
  96 
  97 extern __inline__ int find_next_zero_bit (void * addr, int size, int offset)
     /* [previous][next][first][last][top][bottom][index][help] */
  98 {
  99         unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
 100         int set = 0, bit = offset & 31, res;
 101         
 102         if (bit) {
 103                 /*
 104                  * Look for zero in first byte
 105                  */
 106                 __asm__("
 107                         bsfl %1,%0
 108                         jne 1f
 109                         movl $32, %0
 110 1:                      "
 111                         : "=r" (set)
 112                         : "r" (~(*p >> bit)));
 113                 if (set < (32 - bit))
 114                         return set + offset;
 115                 set = 32 - bit;
 116                 p++;
 117         }
 118         /*
 119          * No zero yet, search remaining full bytes for a zero
 120          */
 121         res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr));
 122         return (offset + set + res);
 123 }
 124 
 125 /*
 126  * ffz = Find First Zero in word. Undefined if no zero exists,
 127  * so code should check against ~0UL first..
 128  */
 129 extern __inline__ unsigned long ffz(unsigned long word)
     /* [previous][next][first][last][top][bottom][index][help] */
 130 {
 131         __asm__("bsfl %1,%0"
 132                 :"=r" (word)
 133                 :"r" (~word));
 134         return word;
 135 }
 136 
 137 #endif /* _I386_BITOPS_H */

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