OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [include/] [asm-or32/] [bitops.h] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1276 phoenix
#ifdef __KERNEL__
2
#ifndef _OR32_BITOPS_H
3
#define _OR32_BITOPS_H
4
 
5
#include <linux/config.h>
6
#include <asm/byteorder.h>
7
#include <asm/system.h>
8
 
9
extern __inline__ int set_bit(int nr, void * a)
10
{
11
        int     * addr = a;
12
        int     mask, retval;
13
        unsigned long flags;
14
 
15
        addr += nr >> 5;
16
        mask = 1 << (nr & 0x1f);
17
        save_and_cli(flags);
18
        retval = (mask & *addr) != 0;
19
        *addr |= mask;
20
        restore_flags(flags);
21
        return retval;
22
}
23
 
24
extern __inline__ int clear_bit(int nr, void * a)
25
{
26
        int     * addr = a;
27
        int     mask, retval;
28
        unsigned long flags;
29
 
30
        addr += nr >> 5;
31
        mask = 1 << (nr & 0x1f);
32
        save_and_cli(flags);
33
        retval = (mask & *addr) != 0;
34
        *addr &= ~mask;
35
        restore_flags(flags);
36
        return retval;
37
}
38
 
39
extern __inline__ unsigned long change_bit(unsigned long nr,  void *addr)
40
{
41
        int mask;
42
  unsigned long flags;
43
        unsigned long *ADDR = (unsigned long *) addr;
44
        unsigned long oldbit;
45
 
46
        ADDR += nr >> 5;
47
        mask = 1 << (nr & 31);
48
        save_and_cli(flags);
49
        oldbit = (mask & *ADDR);
50
        *ADDR ^= mask;
51
        restore_flags(flags);
52
        return oldbit != 0;
53
}
54
 
55
extern __inline__ int test_bit(int nr, void * a)
56
{
57
        int     * addr = a;
58
        int     mask;
59
 
60
        addr += nr >> 5;
61
        mask = 1 << (nr & 0x1f);
62
        return ((mask & *addr) != 0);
63
}
64
 
65
static __inline__ int test_and_set_bit(int nr, void *addr)
66
{
67
        unsigned int mask, retval;
68
        unsigned long flags;
69
        unsigned int *adr = (unsigned int *)addr;
70
 
71
        adr += nr >> 5;
72
        mask = 1 << (nr & 0x1f);
73
        save_and_cli(flags);
74
        retval = (mask & *adr) != 0;
75
        *adr |= mask;
76
        restore_flags(flags);
77
        return retval;
78
}
79
 
80
static __inline__ int test_and_clear_bit(int nr, void *addr)
81
{
82
        unsigned int mask, retval;
83
        unsigned long flags;
84
        unsigned int *adr = (unsigned int *)addr;
85
 
86
        adr += nr >> 5;
87
        mask = 1 << (nr & 0x1f);
88
        save_and_cli(flags);
89
        retval = (mask & *adr) != 0;
90
        *adr &= ~mask;
91
        restore_flags(flags);
92
        return retval;
93
}
94
 
95
static __inline__ int test_and_change_bit(int nr, void *addr)
96
{
97
        unsigned int mask, retval;
98
        unsigned long flags;
99
        unsigned int *adr = (unsigned int *)addr;
100
        adr += nr >> 5;
101
        mask = 1 << (nr & 0x1f);
102
        save_and_cli(flags);
103
        retval = (mask & *adr) != 0;
104
        *adr ^= mask;
105
        restore_flags(flags);
106
        return retval;
107
}
108
 
109
#define __change_bit(nr, addr) (void)__test_and_change_bit(nr, addr)
110
 
111
static __inline__ int __test_and_change_bit(int nr, void *addr)
112
{
113
        unsigned int mask, retval;
114
        unsigned int *adr = (unsigned int *)addr;
115
 
116
        adr += nr >> 5;
117
        mask = 1 << (nr & 0x1f);
118
        retval = (mask & *adr) != 0;
119
        *adr ^= mask;
120
 
121
        return retval;
122
}
123
 
124
/* The easy/cheese version for now. */
125
extern __inline__ unsigned long ffz(unsigned long word)
126
{
127
        unsigned long result = 0;
128
 
129
        while(word & 1) {
130
                result++;
131
                word >>= 1;
132
        }
133
        return result;
134
}
135
 
136
/* find_next_zero_bit() finds the first zero bit in a bit string of length
137
 * 'size' bits, starting the search at bit 'offset'. This is largely based
138
 * on Linus's ALPHA routines, which are pretty portable BTW.
139
 */
140
 
141
extern __inline__ unsigned long find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
142
{
143
        unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
144
        unsigned long result = offset & ~31UL;
145
        unsigned long tmp;
146
 
147
        if (offset >= size)
148
                return size;
149
        size -= result;
150
        offset &= 31UL;
151
        if (offset) {
152
                tmp = *(p++);
153
                tmp |= ~0UL >> (32-offset);
154
                if (size < 32)
155
                        goto found_first;
156
                if (~tmp)
157
                        goto found_middle;
158
                size -= 32;
159
                result += 32;
160
        }
161
        while (size & ~31UL) {
162
                if (~(tmp = *(p++)))
163
                        goto found_middle;
164
                result += 32;
165
                size -= 32;
166
        }
167
        if (!size)
168
                return result;
169
        tmp = *p;
170
 
171
found_first:
172
        tmp |= ~0UL >> size;
173
found_middle:
174
        return result + ffz(tmp);
175
}
176
 
177
/* Linus sez that gcc can optimize the following correctly, we'll see if this
178
 * holds on the Sparc as it does for the ALPHA.
179
 */
180
 
181
#define find_first_zero_bit(addr, size) \
182
        find_next_zero_bit((addr), (size), 0)
183
 
184
/* Now for the ext2 filesystem bit operations and helper routines. */
185
 
186
extern __inline__ int ext2_set_bit(int nr,void * addr)
187
{
188
        int             mask, retval;
189
  unsigned long flags;
190
        unsigned char   *ADDR = (unsigned char *) addr;
191
 
192
        ADDR += nr >> 3;
193
        mask = 1 << (nr & 0x07);
194
        save_and_cli(flags);
195
        retval = (mask & *ADDR) != 0;
196
        *ADDR |= mask;
197
        restore_flags(flags);
198
        return retval;
199
}
200
 
201
extern __inline__ int ext2_clear_bit(int nr, void * addr)
202
{
203
        int             mask, retval;
204
  unsigned long flags;
205
        unsigned char   *ADDR = (unsigned char *) addr;
206
 
207
        ADDR += nr >> 3;
208
        mask = 1 << (nr & 0x07);
209
        save_and_cli(flags);
210
        retval = (mask & *ADDR) != 0;
211
        *ADDR &= ~mask;
212
        restore_flags(flags);
213
        return retval;
214
}
215
 
216
extern __inline__ int ext2_test_bit(int nr, const void * addr)
217
{
218
        int                     mask;
219
        const unsigned char     *ADDR = (const unsigned char *) addr;
220
 
221
        ADDR += nr >> 3;
222
        mask = 1 << (nr & 0x07);
223
        return ((mask & *ADDR) != 0);
224
}
225
 
226
#define ext2_find_first_zero_bit(addr, size) \
227
        ext2_find_next_zero_bit((addr), (size), 0)
228
 
229
extern __inline__ unsigned long ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
230
{
231
        unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
232
        unsigned long result = offset & ~31UL;
233
        unsigned long tmp;
234
 
235
        if (offset >= size)
236
                return size;
237
        size -= result;
238
        offset &= 31UL;
239
        if(offset) {
240
                tmp = *(p++);
241
                tmp |= ~0UL << (32-offset);
242
                if(size < 32)
243
                        goto found_first;
244
                if(~tmp)
245
                        goto found_middle;
246
                size -= 32;
247
                result += 32;
248
        }
249
        while(size & ~31UL) {
250
                if(~(tmp = *(p++)))
251
                        goto found_middle;
252
                result += 32;
253
                size -= 32;
254
        }
255
        if(!size)
256
                return result;
257
        tmp = *p;
258
 
259
found_first:
260
        tmp |= ~0UL << size;
261
found_middle:
262
        tmp = ((tmp>>24) | ((tmp>>8)&0xff00) | ((tmp<<8)&0xff0000) | (tmp<<24));
263
        return result + ffz(tmp);
264
}
265
 
266
#define __ext2_set_bit ext2_set_bit
267
#define __ext2_clear_bit ext2_clear_bit
268
 
269
extern __inline__ int __ext2_test_bit(int nr, __const__ void * addr)
270
{
271
        int                     mask;
272
        __const__ unsigned char *ADDR = (__const__ unsigned char *) addr;
273
 
274
        ADDR += nr >> 3;
275
        mask = 1 << (nr & 0x07);
276
        return ((mask & *ADDR) != 0);
277
}
278
 
279
#define __ext2_find_first_zero_bit(addr, size) \
280
        __ext2_find_next_zero_bit((addr), (size), 0)
281
 
282
extern __inline__ unsigned long __ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
283
{
284
        unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
285
        unsigned long result = offset & ~31UL;
286
        unsigned long tmp;
287
 
288
        if (offset >= size)
289
                return size;
290
        size -= result;
291
        offset &= 31UL;
292
        if(offset) {
293
                tmp = *(p++);
294
                tmp |= __swab32(~0UL >> (32-offset));
295
                if(size < 32)
296
                        goto found_first;
297
                if(~tmp)
298
                        goto found_middle;
299
                size -= 32;
300
                result += 32;
301
        }
302
        while(size & ~31UL) {
303
                if(~(tmp = *(p++)))
304
                        goto found_middle;
305
                result += 32;
306
                size -= 32;
307
        }
308
        if(!size)
309
                return result;
310
        tmp = *p;
311
 
312
found_first:
313
        return result + ffz(__swab32(tmp) | (~0UL << size));
314
found_middle:
315
        return result + ffz(__swab32(tmp));
316
}
317
 
318
/*
319
 * clear_bit() doesn't provide any barrier for the compiler.
320
 */
321
 
322
/* __PHX__ :: enable for SMP */
323
//#define smp_mb__before_clear_bit()      barrier()
324
//#define smp_mb__after_clear_bit()       barrier()
325
 
326
#define smp_mb__before_clear_bit()
327
#define smp_mb__after_clear_bit()
328
 
329
 
330
#endif /* _OR32_BITOPS_H */
331
#endif /* __KERNEL__ */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.