This source file includes following definitions.
- set_bit
- clear_bit
- change_bit
- test_bit
- find_first_zero_bit
- find_next_zero_bit
- ffz
1 #ifndef _I386_BITOPS_H
2 #define _I386_BITOPS_H
3
4
5
6
7
8
9
10
11
12
13
14
15
16 #ifdef __SMP__
17 #define LOCK_PREFIX "lock ; "
18 #define SMPVOL volatile
19 #else
20 #define LOCK_PREFIX ""
21 #define SMPVOL
22 #endif
23
24
25
26
27 struct __dummy { unsigned long a[100]; };
28 #define ADDR (*(struct __dummy *) addr)
29 #define CONST_ADDR (*(const struct __dummy *) addr)
30
31 extern __inline__ int set_bit(int nr, SMPVOL void * addr)
32 {
33 int oldbit;
34
35 __asm__ __volatile__(LOCK_PREFIX
36 "btsl %2,%1\n\tsbbl %0,%0"
37 :"=r" (oldbit),"=m" (ADDR)
38 :"ir" (nr));
39 return oldbit;
40 }
41
42 extern __inline__ int clear_bit(int nr, SMPVOL void * addr)
43 {
44 int oldbit;
45
46 __asm__ __volatile__(LOCK_PREFIX
47 "btrl %2,%1\n\tsbbl %0,%0"
48 :"=r" (oldbit),"=m" (ADDR)
49 :"ir" (nr));
50 return oldbit;
51 }
52
53 extern __inline__ int change_bit(int nr, SMPVOL void * addr)
54 {
55 int oldbit;
56
57 __asm__ __volatile__(LOCK_PREFIX
58 "btcl %2,%1\n\tsbbl %0,%0"
59 :"=r" (oldbit),"=m" (ADDR)
60 :"ir" (nr));
61 return oldbit;
62 }
63
64
65
66
67 extern __inline__ int test_bit(int nr, const SMPVOL void * addr)
68 {
69 return 1UL & (((const unsigned int *) addr)[nr >> 5] >> (nr & 31));
70 }
71
72
73
74
75 extern __inline__ int find_first_zero_bit(void * addr, unsigned size)
76 {
77 int res;
78
79 if (!size)
80 return 0;
81 __asm__("
82 cld
83 movl $-1,%%eax
84 xorl %%edx,%%edx
85 repe; scasl
86 je 1f
87 xorl -4(%%edi),%%eax
88 subl $4,%%edi
89 bsfl %%eax,%%edx
90 1: subl %%ebx,%%edi
91 shll $3,%%edi
92 addl %%edi,%%edx"
93 :"=d" (res)
94 :"c" ((size + 31) >> 5), "D" (addr), "b" (addr)
95 :"ax", "cx", "di");
96 return res;
97 }
98
99 extern __inline__ int find_next_zero_bit (void * addr, int size, int offset)
100 {
101 unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
102 int set = 0, bit = offset & 31, res;
103
104 if (bit) {
105
106
107
108 __asm__("
109 bsfl %1,%0
110 jne 1f
111 movl $32, %0
112 1: "
113 : "=r" (set)
114 : "r" (~(*p >> bit)));
115 if (set < (32 - bit))
116 return set + offset;
117 set = 32 - bit;
118 p++;
119 }
120
121
122
123 res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr));
124 return (offset + set + res);
125 }
126
127
128
129
130
131 extern __inline__ unsigned long ffz(unsigned long word)
132 {
133 __asm__("bsfl %1,%0"
134 :"=r" (word)
135 :"r" (~word));
136 return word;
137 }
138
139 #endif