This source file includes following definitions.
- set_bit
- clear_bit
- change_bit
- test_bit
- ffz
- find_next_zero_bit
1 #ifndef _ALPHA_BITOPS_H
2 #define _ALPHA_BITOPS_H
3
4
5
6
7
8
9
10
11
12
13
14
15
16 extern __inline__ unsigned long set_bit(unsigned long nr, void * addr)
17 {
18 unsigned long oldbit;
19 unsigned long temp;
20
21 __asm__ __volatile__(
22 "\n1:\t"
23 "ldq_l %0,%1\n\t"
24 "and %0,%3,%2\n\t"
25 "bne %2,2f\n\t"
26 "xor %0,%3,%0\n\t"
27 "stq_c %0,%1\n\t"
28 "beq %0,1b\n"
29 "2:"
30 :"=&r" (temp),
31 "=m" (((unsigned long *) addr)[nr >> 6]),
32 "=&r" (oldbit)
33 :"r" (1UL << (nr & 63)),
34 "m" (((unsigned long *) addr)[nr >> 6]));
35 return oldbit;
36 }
37
38 extern __inline__ unsigned long clear_bit(unsigned long nr, void * addr)
39 {
40 unsigned long oldbit;
41 unsigned long temp;
42
43 __asm__ __volatile__(
44 "\n1:\t"
45 "ldq_l %0,%1\n\t"
46 "and %0,%3,%2\n\t"
47 "beq %2,2f\n\t"
48 "xor %0,%3,%0\n\t"
49 "stq_c %0,%1\n\t"
50 "beq %0,1b\n"
51 "2:"
52 :"=&r" (temp),
53 "=m" (((unsigned long *) addr)[nr >> 6]),
54 "=&r" (oldbit)
55 :"r" (1UL << (nr & 63)),
56 "m" (((unsigned long *) addr)[nr >> 6]));
57 return oldbit;
58 }
59
60 extern __inline__ unsigned long change_bit(unsigned long nr, void * addr)
61 {
62 unsigned long oldbit;
63 unsigned long temp;
64
65 __asm__ __volatile__(
66 "\n1:\t"
67 "ldq_l %0,%1\n\t"
68 "and %0,%3,%2\n\t"
69 "xor %0,%3,%0\n\t"
70 "stq_c %0,%1\n\t"
71 "beq %0,1b\n"
72 :"=&r" (temp),
73 "=m" (((unsigned long *) addr)[nr >> 6]),
74 "=&r" (oldbit)
75 :"r" (1UL << (nr & 63)),
76 "m" (((unsigned long *) addr)[nr >> 6]));
77 return oldbit;
78 }
79
80 extern __inline__ unsigned long test_bit(int nr, void * addr)
81 {
82 return 1UL & (((unsigned long *) addr)[nr >> 6] >> (nr & 63));
83 }
84
85
86
87
88
89
90
91
92
93
94 extern inline unsigned long ffz(unsigned long word)
95 {
96 unsigned long result = 0;
97 unsigned long tmp;
98
99 __asm__("cmpbge %1,%0,%0"
100 :"=r" (tmp)
101 :"r" (word), "0" (~0UL));
102 while (tmp & 1) {
103 word >>= 8;
104 tmp >>= 1;
105 result += 8;
106 }
107 while (word & 1) {
108 result++;
109 word >>= 1;
110 }
111 return result;
112 }
113
114
115
116
117 extern inline unsigned long find_next_zero_bit(void * addr, unsigned long size, unsigned long offset)
118 {
119 unsigned long * p = ((unsigned long *) addr) + (offset >> 6);
120 unsigned long result = offset & ~63UL;
121 unsigned long tmp;
122
123 if (offset >= size)
124 return size;
125 size -= result;
126 offset &= 63UL;
127 if (offset) {
128 tmp = *(p++);
129 tmp |= ~0UL >> (64-offset);
130 if (size < 64)
131 goto found_first;
132 if (~tmp)
133 goto found_middle;
134 size -= 64;
135 result += 64;
136 }
137 while (size & ~63UL) {
138 if (~(tmp = *(p++)))
139 goto found_middle;
140 result += 64;
141 size -= 64;
142 }
143 if (!size)
144 return result;
145 tmp = *p;
146 found_first:
147 tmp |= ~0UL << size;
148 found_middle:
149 return result + ffz(tmp);
150 }
151
152
153
154
155 #define find_first_zero_bit(addr, size) \
156 find_next_zero_bit((addr), (size), 0)
157
158 #endif