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

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