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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [include/] [asm-sh64/] [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
#ifndef __ASM_SH64_BITOPS_H
2
#define __ASM_SH64_BITOPS_H
3
 
4
#ifdef __KERNEL__
5
#include <asm/system.h>
6
/* For __swab32 */
7
#include <asm/byteorder.h>
8
 
9
static __inline__ void set_bit(int nr, volatile void * addr)
10
{
11
        int     mask;
12
        volatile unsigned int *a = addr;
13
        unsigned long flags;
14
 
15
        a += nr >> 5;
16
        mask = 1 << (nr & 0x1f);
17
        save_and_cli(flags);
18
        *a |= mask;
19
        restore_flags(flags);
20
}
21
 
22
static __inline__ void __set_bit(int nr, volatile void * addr)
23
{
24
        int     mask;
25
        volatile unsigned int *a = addr;
26
 
27
        a += nr >> 5;
28
        mask = 1 << (nr & 0x1f);
29
        *a |= mask;
30
}
31
 
32
/*
33
 * clear_bit() doesn't provide any barrier for the compiler.
34
 */
35
#define smp_mb__before_clear_bit()      barrier()
36
#define smp_mb__after_clear_bit()       barrier()
37
static __inline__ void clear_bit(int nr, volatile void * addr)
38
{
39
        int     mask;
40
        volatile unsigned int *a = addr;
41
        unsigned long flags;
42
 
43
        a += nr >> 5;
44
        mask = 1 << (nr & 0x1f);
45
        save_and_cli(flags);
46
        *a &= ~mask;
47
        restore_flags(flags);
48
}
49
 
50
static __inline__ void __clear_bit(int nr, volatile void * addr)
51
{
52
        int     mask;
53
        volatile unsigned int *a = addr;
54
 
55
        a += nr >> 5;
56
        mask = 1 << (nr & 0x1f);
57
        *a &= ~mask;
58
}
59
 
60
static __inline__ void change_bit(int nr, volatile void * addr)
61
{
62
        int     mask;
63
        volatile unsigned int *a = addr;
64
        unsigned long flags;
65
 
66
        a += nr >> 5;
67
        mask = 1 << (nr & 0x1f);
68
        save_and_cli(flags);
69
        *a ^= mask;
70
        restore_flags(flags);
71
}
72
 
73
static __inline__ void __change_bit(int nr, volatile void * addr)
74
{
75
        int     mask;
76
        volatile unsigned int *a = addr;
77
 
78
        a += nr >> 5;
79
        mask = 1 << (nr & 0x1f);
80
        *a ^= mask;
81
}
82
 
83
static __inline__ int test_and_set_bit(int nr, volatile void * addr)
84
{
85
        int     mask, retval;
86
        volatile unsigned int *a = addr;
87
        unsigned long flags;
88
 
89
        a += nr >> 5;
90
        mask = 1 << (nr & 0x1f);
91
        save_and_cli(flags);
92
        retval = (mask & *a) != 0;
93
        *a |= mask;
94
        restore_flags(flags);
95
 
96
        return retval;
97
}
98
 
99
static __inline__ int __test_and_set_bit(int nr, volatile void * addr)
100
{
101
        int     mask, retval;
102
        volatile unsigned int *a = addr;
103
 
104
        a += nr >> 5;
105
        mask = 1 << (nr & 0x1f);
106
        retval = (mask & *a) != 0;
107
        *a |= mask;
108
 
109
        return retval;
110
}
111
 
112
static __inline__ int test_and_clear_bit(int nr, volatile void * addr)
113
{
114
        int     mask, retval;
115
        volatile unsigned int *a = addr;
116
        unsigned long flags;
117
 
118
        a += nr >> 5;
119
        mask = 1 << (nr & 0x1f);
120
        save_and_cli(flags);
121
        retval = (mask & *a) != 0;
122
        *a &= ~mask;
123
        restore_flags(flags);
124
 
125
        return retval;
126
}
127
 
128
static __inline__ int __test_and_clear_bit(int nr, volatile void * addr)
129
{
130
        int     mask, retval;
131
        volatile unsigned int *a = addr;
132
 
133
        a += nr >> 5;
134
        mask = 1 << (nr & 0x1f);
135
        retval = (mask & *a) != 0;
136
        *a &= ~mask;
137
 
138
        return retval;
139
}
140
 
141
static __inline__ int test_and_change_bit(int nr, volatile void * addr)
142
{
143
        int     mask, retval;
144
        volatile unsigned int *a = addr;
145
        unsigned long flags;
146
 
147
        a += nr >> 5;
148
        mask = 1 << (nr & 0x1f);
149
        save_and_cli(flags);
150
        retval = (mask & *a) != 0;
151
        *a ^= mask;
152
        restore_flags(flags);
153
 
154
        return retval;
155
}
156
 
157
static __inline__ int __test_and_change_bit(int nr, volatile void * addr)
158
{
159
        int     mask, retval;
160
        volatile unsigned int *a = addr;
161
 
162
        a += nr >> 5;
163
        mask = 1 << (nr & 0x1f);
164
        retval = (mask & *a) != 0;
165
        *a ^= mask;
166
 
167
        return retval;
168
}
169
 
170
static __inline__ int test_bit(int nr, const volatile void *addr)
171
{
172
        return 1UL & (((const volatile unsigned int *) addr)[nr >> 5] >> (nr & 31));
173
}
174
 
175
static __inline__ unsigned long ffz(unsigned long word)
176
{
177
        unsigned long result, __d2, __d3;
178
 
179
        __asm__("gettr  " __t0 ", %2\n\t"
180
                "_pta   32, " __t0 "\n\t"
181
                "andi   %1, 1, %3\n\t"
182
                "beq    %3, r63, " __t0 "\n\t"
183
                "_pta   4, " __t0 "\n"
184
                "0:\n\t"
185
                "shlri.l        %1, 1, %1\n\t"
186
                "addi   %0, 1, %0\n\t"
187
                "andi   %1, 1, %3\n\t"
188
                "beqi   %3, 1, " __t0 "\n"
189
                "1:\n\t"
190
                "ptabs  %2, " __t0 "\n\t"
191
                : "=r" (result), "=r" (word), "=r" (__d2), "=r" (__d3)
192
                : "0" (0L), "1" (word));
193
 
194
        return result;
195
}
196
 
197
static __inline__ int find_next_zero_bit(void *addr, int size, int offset)
198
{
199
        unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
200
        unsigned long result = offset & ~31UL;
201
        unsigned long tmp;
202
 
203
        if (offset >= size)
204
                return size;
205
        size -= result;
206
        offset &= 31UL;
207
        if (offset) {
208
                tmp = *(p++);
209
                tmp |= ~0UL >> (32-offset);
210
                if (size < 32)
211
                        goto found_first;
212
                if (~tmp)
213
                        goto found_middle;
214
                size -= 32;
215
                result += 32;
216
        }
217
        while (size & ~31UL) {
218
                if (~(tmp = *(p++)))
219
                        goto found_middle;
220
                result += 32;
221
                size -= 32;
222
        }
223
        if (!size)
224
                return result;
225
        tmp = *p;
226
 
227
found_first:
228
        tmp |= ~0UL << size;
229
found_middle:
230
        return result + ffz(tmp);
231
}
232
 
233
#define find_first_zero_bit(addr, size) \
234
        find_next_zero_bit((addr), (size), 0)
235
 
236
/*
237
 * ffs: find first bit set. This is defined the same way as
238
 * the libc and compiler builtin ffs routines, therefore
239
 * differs in spirit from the above ffz (man ffs).
240
 */
241
 
242
#define ffs(x) generic_ffs(x)
243
 
244
/*
245
 * hweightN: returns the hamming weight (i.e. the number
246
 * of bits set) of a N-bit word
247
 */
248
 
249
#define hweight32(x) generic_hweight32(x)
250
#define hweight16(x) generic_hweight16(x)
251
#define hweight8(x) generic_hweight8(x)
252
 
253
#ifdef __LITTLE_ENDIAN__
254
#define ext2_set_bit(nr, addr) test_and_set_bit((nr), (addr))
255
#define ext2_clear_bit(nr, addr) test_and_clear_bit((nr), (addr))
256
#define ext2_test_bit(nr, addr) test_bit((nr), (addr))
257
#define ext2_find_first_zero_bit(addr, size) find_first_zero_bit((addr), (size))
258
#define ext2_find_next_zero_bit(addr, size, offset) \
259
                find_next_zero_bit((addr), (size), (offset))
260
#else
261
static __inline__ int ext2_set_bit(int nr, volatile void * addr)
262
{
263
        int             mask, retval;
264
        unsigned long   flags;
265
        volatile unsigned char  *ADDR = (unsigned char *) addr;
266
 
267
        ADDR += nr >> 3;
268
        mask = 1 << (nr & 0x07);
269
        save_and_cli(flags);
270
        retval = (mask & *ADDR) != 0;
271
        *ADDR |= mask;
272
        restore_flags(flags);
273
        return retval;
274
}
275
 
276
static __inline__ int ext2_clear_bit(int nr, volatile void * addr)
277
{
278
        int             mask, retval;
279
        unsigned long   flags;
280
        volatile unsigned char  *ADDR = (unsigned char *) addr;
281
 
282
        ADDR += nr >> 3;
283
        mask = 1 << (nr & 0x07);
284
        save_and_cli(flags);
285
        retval = (mask & *ADDR) != 0;
286
        *ADDR &= ~mask;
287
        restore_flags(flags);
288
        return retval;
289
}
290
 
291
static __inline__ int ext2_test_bit(int nr, const volatile void * addr)
292
{
293
        int                     mask;
294
        const volatile unsigned char    *ADDR = (const unsigned char *) addr;
295
 
296
        ADDR += nr >> 3;
297
        mask = 1 << (nr & 0x07);
298
        return ((mask & *ADDR) != 0);
299
}
300
 
301
#define ext2_find_first_zero_bit(addr, size) \
302
        ext2_find_next_zero_bit((addr), (size), 0)
303
 
304
static __inline__ unsigned long ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
305
{
306
        unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
307
        unsigned long result = offset & ~31UL;
308
        unsigned long tmp;
309
 
310
        if (offset >= size)
311
                return size;
312
        size -= result;
313
        offset &= 31UL;
314
        if(offset) {
315
                /* We hold the little endian value in tmp, but then the
316
                 * shift is illegal. So we could keep a big endian value
317
                 * in tmp, like this:
318
                 *
319
                 * tmp = __swab32(*(p++));
320
                 * tmp |= ~0UL >> (32-offset);
321
                 *
322
                 * but this would decrease preformance, so we change the
323
                 * shift:
324
                 */
325
                tmp = *(p++);
326
                tmp |= __swab32(~0UL >> (32-offset));
327
                if(size < 32)
328
                        goto found_first;
329
                if(~tmp)
330
                        goto found_middle;
331
                size -= 32;
332
                result += 32;
333
        }
334
        while(size & ~31UL) {
335
                if(~(tmp = *(p++)))
336
                        goto found_middle;
337
                result += 32;
338
                size -= 32;
339
        }
340
        if(!size)
341
                return result;
342
        tmp = *p;
343
 
344
found_first:
345
        /* tmp is little endian, so we would have to swab the shift,
346
         * see above. But then we have to swab tmp below for ffz, so
347
         * we might as well do this here.
348
         */
349
        return result + ffz(__swab32(tmp) | (~0UL << size));
350
found_middle:
351
        return result + ffz(__swab32(tmp));
352
}
353
#endif
354
 
355
/* Bitmap functions for the minix filesystem.  */
356
#define minix_test_and_set_bit(nr,addr) test_and_set_bit(nr,addr)
357
#define minix_set_bit(nr,addr) set_bit(nr,addr)
358
#define minix_test_and_clear_bit(nr,addr) test_and_clear_bit(nr,addr)
359
#define minix_test_bit(nr,addr) test_bit(nr,addr)
360
#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
361
 
362
#endif /* __KERNEL__ */
363
 
364
#endif /* __ASM_SH64_BITOPS_H */

powered by: WebSVN 2.1.0

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