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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
#ifndef _ASM_GENERIC_BITOPS_H_
2
#define _ASM_GENERIC_BITOPS_H_
3
 
4
#include <asm/system.h>
5
 
6
/*
7
 * N.B.: we shouldn't assume addresses are long*'s; nr can be > 31.
8
 */
9
static __inline__ long set_bit(long nr, void *a)
10
{
11
        long*   addr = a;
12
        int     mask, oldval;
13
 
14
        addr += nr >> 5;
15
        mask = 1 << (nr & 0x1f);
16
        __asm__ __volatile__
17
                ("atmod %3, %2, %2"
18
                 : "=m" (*addr), "=r" (oldval)
19
                 : "1" (mask), "r" (addr), "m"(*addr));
20
        return (oldval & mask) != 0;
21
}
22
 
23
static __inline__ long clear_bit(long nr, void *a)
24
{
25
        long*   addr = a;
26
        int     mask, oldval;
27
 
28
        addr += nr >> 5;
29
        mask = 1 << (nr & 0x1f);
30
        __asm__ __volatile__
31
                ("atmod %4, %3, %2"
32
                 : "=m" (*addr), "=r"(oldval)
33
                 : "1" (0), "r" (mask), "r"(addr), "m"(*addr));
34
        return (oldval & mask) != 0;
35
}
36
 
37
 
38
static __inline__ long change_bit(long nr, void *a)
39
{
40
        long*   addr = a;
41
        long    flags;
42
        int     bitpos, retval;
43
 
44
        addr += nr >> 5;
45
        bitpos = (nr & 0x1f);
46
        save_flags(flags);
47
        cli();
48
 
49
#if 1
50
        retval = (*addr & (1 << bitpos));
51
        *addr ^= (1 << bitpos);
52
#else
53
        __asm__
54
                ("ld            (%2), r3\n\t"
55
                 "notbit        %1, r3, r4\n\t"
56
                 "st            r4, (%2)\n\t"
57
                 "ldconst       1, r4\n\t"
58
                 "shlo          %1, r4, r4\n\t"
59
                 "and           r4, r3, %0\n\t"
60
                 : "=&r" (retval)
61
                 : "r" (bitpos), "r" (addr)
62
                 : "r3", "r4", "memory");
63
#endif
64
        restore_flags(flags);
65
        return retval != 0;
66
}
67
 
68
static __inline__ long test_bit(long nr, void *a)
69
{
70
        int     * addr = a;
71
        int     mask;
72
 
73
        addr += nr >> 5;
74
        mask = 1 << (nr & 0x1f);
75
        return ((mask & *addr) != 0);
76
}
77
 
78
/* The easy/cheese version for now. */
79
extern __inline__ unsigned long ffz(unsigned long word)
80
{
81
        unsigned long result = 0;
82
 
83
        while(word & 1) {
84
                result++;
85
                word >>= 1;
86
        }
87
        return result;
88
}
89
 
90
/* find_next_zero_bit() finds the first zero bit in a bit string of length
91
 * 'size' bits, starting the search at bit 'offset'. This is largely based
92
 * on Linus's ALPHA routines, which are pretty portable BTW.
93
 */
94
 
95
extern __inline__ unsigned long find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
96
{
97
        unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
98
        unsigned long result = offset & ~31UL;
99
        unsigned long tmp;
100
 
101
        if (offset >= size)
102
                return size;
103
        size -= result;
104
        offset &= 31UL;
105
        if (offset) {
106
                tmp = *(p++);
107
                tmp |= ~0UL >> (32-offset);
108
                if (size < 32)
109
                        goto found_first;
110
                if (~tmp)
111
                        goto found_middle;
112
                size -= 32;
113
                result += 32;
114
        }
115
        while (size & ~31UL) {
116
                if (~(tmp = *(p++)))
117
                        goto found_middle;
118
                result += 32;
119
                size -= 32;
120
        }
121
        if (!size)
122
                return result;
123
        tmp = *p;
124
 
125
found_first:
126
        tmp |= ~0UL >> size;
127
found_middle:
128
        return result + ffz(tmp);
129
}
130
 
131
/* Linus sez that gcc can optimize the following correctly, we'll see if this
132
 * holds on the Sparc as it does for the ALPHA.
133
 */
134
 
135
#define find_first_zero_bit(addr, size) \
136
        find_next_zero_bit((addr), (size), 0)
137
 
138
 
139
#endif /* _ASM_I960_BITOPS_H */

powered by: WebSVN 2.1.0

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