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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [include/] [asm-mips/] [bitops.h] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/*
2
 * include/asm-mips/bitops.h
3
 *
4
 * This file is subject to the terms and conditions of the GNU General Public
5
 * License.  See the file "COPYING" in the main directory of this archive
6
 * for more details.
7
 *
8
 * Copyright (c) 1994, 1995  Ralf Baechle
9
 */
10
#ifndef __ASM_MIPS_BITOPS_H
11
#define __ASM_MIPS_BITOPS_H
12
 
13
#if __mips > 1
14
 
15
/*
16
 * These functions for MIPS ISA >= 2 are interrupt and SMP proof and
17
 * interrupt friendly
18
 */
19
#include <asm/mipsregs.h>
20
 
21
/*
22
 * The following functions will only work for the R4000!
23
 */
24
extern __inline__ int set_bit(int nr, void *addr)
25
{
26
        int     mask, retval, mw;
27
 
28
        addr += ((nr >> 3) & ~3);
29
        mask = 1 << (nr & 0x1f);
30
        do {
31
                mw = load_linked(addr);
32
                retval = (mask & mw) != 0;
33
                }
34
        while (!store_conditional(addr, mw|mask));
35
 
36
        return retval;
37
}
38
 
39
extern __inline__ int clear_bit(int nr, void *addr)
40
{
41
        int     mask, retval, mw;
42
 
43
        addr += ((nr >> 3) & ~3);
44
        mask = 1 << (nr & 0x1f);
45
        do {
46
                mw = load_linked(addr);
47
                retval = (mask & mw) != 0;
48
                }
49
        while (!store_conditional(addr, mw & ~mask));
50
 
51
        return retval;
52
}
53
 
54
extern __inline__ int change_bit(int nr, void *addr)
55
{
56
        int     mask, retval, mw;
57
 
58
        addr += ((nr >> 3) & ~3);
59
        mask = 1 << (nr & 0x1f);
60
        do {
61
                mw = load_linked(addr);
62
                retval = (mask & mw) != 0;
63
                }
64
        while (!store_conditional(addr, mw ^ mask));
65
 
66
        return retval;
67
}
68
 
69
#else /* __mips <= 1 */
70
 
71
/*
72
 * These functions are only used for MIPS ISA 1 CPUs.  Since I don't
73
 * believe that someone ever will run Linux/SMP on such a beast I don't
74
 * worry about making them SMP proof.
75
 */
76
#include <asm/system.h>
77
 
78
#ifdef __KERNEL__
79
/*
80
 * Only disable interrupt for kernel mode stuff to keep usermode stuff
81
 * that dares to use kernel include files alive.
82
 */
83
#define __flags unsigned long flags
84
#define __cli() cli()
85
#define __save_flags(x) save_flags(x)
86
#define __restore_flags(x) restore_flags(x)
87
#endif /* __KERNEL__ */
88
 
89
extern __inline__ int set_bit(int nr, void * addr)
90
{
91
        int     mask, retval;
92
        int     *a = addr;
93
        __flags;
94
 
95
        a += nr >> 5;
96
        mask = 1 << (nr & 0x1f);
97
        __save_flags(flags);
98
        __cli();
99
        retval = (mask & *a) != 0;
100
        *a |= mask;
101
        __restore_flags(flags);
102
 
103
        return retval;
104
}
105
 
106
extern __inline__ int clear_bit(int nr, void * addr)
107
{
108
        int     mask, retval;
109
        int     *a = addr;
110
        __flags;
111
 
112
        a += nr >> 5;
113
        mask = 1 << (nr & 0x1f);
114
        __save_flags(flags);
115
        __cli();
116
        retval = (mask & *a) != 0;
117
        *a &= ~mask;
118
        __restore_flags(flags);
119
 
120
        return retval;
121
}
122
 
123
extern __inline__ int change_bit(int nr, void * addr)
124
{
125
        int     mask, retval;
126
        int     *a = addr;
127
        __flags;
128
 
129
        a += nr >> 5;
130
        mask = 1 << (nr & 0x1f);
131
        __save_flags(flags);
132
        __cli();
133
        retval = (mask & *a) != 0;
134
        *a ^= mask;
135
        __restore_flags(flags);
136
 
137
        return retval;
138
}
139
 
140
#undef __flags
141
#undef __cli()
142
#undef __save_flags(x)
143
#undef __restore_flags(x)
144
 
145
#endif /* __mips <= 1 */
146
 
147
extern __inline__ int test_bit(int nr, const void *addr)
148
{
149
        return 1UL & (((const unsigned int *) addr)[nr >> 5] >> (nr & 31));
150
}
151
 
152
extern __inline__ int find_first_zero_bit (void *addr, unsigned size)
153
{
154
        int res;
155
 
156
        if (!size)
157
                return 0;
158
 
159
        __asm__(".set\tnoreorder\n\t"
160
                ".set\tnoat\n"
161
                "1:\tsubu\t$1,%2,%0\n\t"
162
                "blez\t$1,2f\n\t"
163
                "lw\t$1,(%4)\n\t"
164
                "addiu\t%4,%4,4\n\t"
165
                "beql\t%1,$1,1b\n\t"
166
                "addiu\t%0,%0,32\n\t"
167
                "li\t%1,1\n"
168
                "1:\tand\t%4,$1,%1\n\t"
169
                "beq\t$0,%4,2f\n\t"
170
                "sll\t%1,%1,1\n\t"
171
                "bne\t$0,%1,1b\n\t"
172
                "add\t%0,%0,1\n\t"
173
                ".set\tat\n\t"
174
                ".set\treorder\n"
175
                "2:"
176
                : "=r" (res)
177
                : "r" ((unsigned int) 0xffffffff),
178
                  "r" (size),
179
                  "0" ((signed int) 0),
180
                  "r" (addr)
181
                : "$1");
182
 
183
        return res;
184
}
185
 
186
extern __inline__ int find_next_zero_bit (void * addr, int size, int offset)
187
{
188
        unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
189
        int set = 0, bit = offset & 31, res;
190
 
191
        if (bit) {
192
                /*
193
                 * Look for zero in first byte
194
                 */
195
                __asm__(".set\tnoreorder\n\t"
196
                        ".set\tnoat\n"
197
                        "1:\tand\t$1,%2,%1\n\t"
198
                        "beq\t$0,$1,2f\n\t"
199
                        "sll\t%2,%2,1\n\t"
200
                        "bne\t$0,%2,1b\n\t"
201
                        "addiu\t%0,%0,1\n\t"
202
                        ".set\tat\n\t"
203
                        ".set\treorder\n"
204
                        : "=r" (set)
205
                        : "r" (*p >> bit),
206
                          "r" (1),
207
                          "0" (0)
208
                        : "$1");
209
                if (set < (32 - bit))
210
                        return set + offset;
211
                set = 32 - bit;
212
                p++;
213
        }
214
        /*
215
         * No zero yet, search remaining full bytes for a zero
216
         */
217
        res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr));
218
        return (offset + set + res);
219
}
220
 
221
/*
222
 * ffz = Find First Zero in word. Undefined if no zero exists,
223
 * so code should check against ~0UL first..
224
 */
225
extern __inline__ unsigned long ffz(unsigned long word)
226
{
227
        unsigned int    __res;
228
        unsigned int    mask = 1;
229
 
230
        __asm__ __volatile__ (
231
                ".set\tnoreorder\n\t"
232
                ".set\tnoat\n\t"
233
                "move\t%0,$0\n"
234
                "1:\tand\t$1,%2,%1\n\t"
235
                "beqz\t$1,2f\n\t"
236
                "sll\t%1,1\n\t"
237
                "bnez\t%1,1b\n\t"
238
                "addiu\t%0,1\n\t"
239
                ".set\tat\n\t"
240
                ".set\treorder\n"
241
                "2:\n\t"
242
                : "=r" (__res), "=r" (mask)
243
                : "r" (word), "1" (mask)
244
                : "$1");
245
 
246
        return __res;
247
}
248
 
249
#endif /* __ASM_MIPS_BITOPS_H */

powered by: WebSVN 2.1.0

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