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

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