root/include/asm-alpha/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. ffz_b
  6. ffz
  7. find_next_zero_bit

   1 #ifndef _ALPHA_BITOPS_H
   2 #define _ALPHA_BITOPS_H
   3 
   4 /*
   5  * Copyright 1994, 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 64 is the LSB of (addr+1).
  14  */
  15 
  16 extern __inline__ unsigned long set_bit(unsigned long nr, void * addr)
     /* [previous][next][first][last][top][bottom][index][help] */
  17 {
  18         unsigned long oldbit;
  19         unsigned long temp;
  20         unsigned int * m = ((unsigned int *) addr) + (nr >> 5);
  21 
  22         __asm__ __volatile__(
  23                 "\n1:\t"
  24                 "ldl_l %0,%1\n\t"
  25                 "and %0,%3,%2\n\t"
  26                 "bne %2,2f\n\t"
  27                 "xor %0,%3,%0\n\t"
  28                 "stl_c %0,%1\n\t"
  29                 "beq %0,1b\n"
  30                 "2:"
  31                 :"=&r" (temp),
  32                  "=m" (*m),
  33                  "=&r" (oldbit)
  34                 :"r" (1UL << (nr & 31)),
  35                  "m" (*m));
  36         return oldbit != 0;
  37 }
  38 
  39 extern __inline__ unsigned long clear_bit(unsigned long nr, void * addr)
     /* [previous][next][first][last][top][bottom][index][help] */
  40 {
  41         unsigned long oldbit;
  42         unsigned long temp;
  43         unsigned int * m = ((unsigned int *) addr) + (nr >> 5);
  44 
  45         __asm__ __volatile__(
  46                 "\n1:\t"
  47                 "ldl_l %0,%1\n\t"
  48                 "and %0,%3,%2\n\t"
  49                 "beq %2,2f\n\t"
  50                 "xor %0,%3,%0\n\t"
  51                 "stl_c %0,%1\n\t"
  52                 "beq %0,1b\n"
  53                 "2:"
  54                 :"=&r" (temp),
  55                  "=m" (*m),
  56                  "=&r" (oldbit)
  57                 :"r" (1UL << (nr & 31)),
  58                  "m" (*m));
  59         return oldbit != 0;
  60 }
  61 
  62 extern __inline__ unsigned long change_bit(unsigned long nr, void * addr)
     /* [previous][next][first][last][top][bottom][index][help] */
  63 {
  64         unsigned long oldbit;
  65         unsigned long temp;
  66         unsigned int * m = ((unsigned int *) addr) + (nr >> 5);
  67 
  68         __asm__ __volatile__(
  69                 "\n1:\t"
  70                 "ldl_l %0,%1\n\t"
  71                 "and %0,%3,%2\n\t"
  72                 "xor %0,%3,%0\n\t"
  73                 "stl_c %0,%1\n\t"
  74                 "beq %0,1b\n"
  75                 :"=&r" (temp),
  76                  "=m" (*m),
  77                  "=&r" (oldbit)
  78                 :"r" (1UL << (nr & 31)),
  79                  "m" (*m));
  80         return oldbit != 0;
  81 }
  82 
  83 extern __inline__ unsigned long test_bit(int nr, const void * addr)
     /* [previous][next][first][last][top][bottom][index][help] */
  84 {
  85         return 1UL & (((const int *) addr)[nr >> 5] >> (nr & 31));
  86 }
  87 
  88 /*
  89  * ffz = Find First Zero in word. Undefined if no zero exists,
  90  * so code should check against ~0UL first..
  91  *
  92  * Do a binary search on the bits.  Due to the nature of large
  93  * constants on the alpha, it is worthwhile to split the search.
  94  */
  95 extern inline unsigned long ffz_b(unsigned long x)
     /* [previous][next][first][last][top][bottom][index][help] */
  96 {
  97         unsigned long sum = 0;
  98 
  99         x = ~x & -~x;           /* set first 0 bit, clear others */
 100         if (x & 0xF0) sum += 4;
 101         if (x & 0xCC) sum += 2;
 102         if (x & 0xAA) sum += 1;
 103 
 104         return sum;
 105 }
 106 
 107 extern inline unsigned long ffz(unsigned long word)
     /* [previous][next][first][last][top][bottom][index][help] */
 108 {
 109         unsigned long bits, qofs, bofs;
 110 
 111         __asm__("cmpbge %1,%2,%0" : "=r"(bits) : "r"(word), "r"(~0UL));
 112         qofs = ffz_b(bits);
 113         __asm__("extbl %1,%2,%0" : "=r"(bits) : "r"(word), "r"(qofs));
 114         bofs = ffz_b(bits);
 115 
 116         return qofs*8 + bofs;
 117 }
 118 
 119 /*
 120  * Find next zero bit in a bitmap reasonably efficiently..
 121  */
 122 extern inline unsigned long find_next_zero_bit(void * addr, unsigned long size, unsigned long offset)
     /* [previous][next][first][last][top][bottom][index][help] */
 123 {
 124         unsigned long * p = ((unsigned long *) addr) + (offset >> 6);
 125         unsigned long result = offset & ~63UL;
 126         unsigned long tmp;
 127 
 128         if (offset >= size)
 129                 return size;
 130         size -= result;
 131         offset &= 63UL;
 132         if (offset) {
 133                 tmp = *(p++);
 134                 tmp |= ~0UL >> (64-offset);
 135                 if (size < 64)
 136                         goto found_first;
 137                 if (~tmp)
 138                         goto found_middle;
 139                 size -= 64;
 140                 result += 64;
 141         }
 142         while (size & ~63UL) {
 143                 if (~(tmp = *(p++)))
 144                         goto found_middle;
 145                 result += 64;
 146                 size -= 64;
 147         }
 148         if (!size)
 149                 return result;
 150         tmp = *p;
 151 found_first:
 152         tmp |= ~0UL << size;
 153 found_middle:
 154         return result + ffz(tmp);
 155 }
 156 
 157 /*
 158  * The optimizer actually does good code for this case..
 159  */
 160 #define find_first_zero_bit(addr, size) \
 161         find_next_zero_bit((addr), (size), 0)
 162 
 163 #endif /* _ALPHA_BITOPS_H */

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