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

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