~ubuntu-branches/ubuntu/trusty/musl/trusty-proposed

« back to all changes in this revision

Viewing changes to arch/mips/atomic.h

  • Committer: Package Import Robot
  • Author(s): Kevin Bortis
  • Date: 2013-09-20 20:54:14 UTC
  • Revision ID: package-import@ubuntu.com-20130920205414-5b61trtmma18w58o
Tags: upstream-0.9.13
ImportĀ upstreamĀ versionĀ 0.9.13

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#ifndef _INTERNAL_ATOMIC_H
 
2
#define _INTERNAL_ATOMIC_H
 
3
 
 
4
#include <stdint.h>
 
5
 
 
6
static inline int a_ctz_l(unsigned long x)
 
7
{
 
8
        static const char debruijn32[32] = {
 
9
                0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,
 
10
                31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14
 
11
        };
 
12
        return debruijn32[(x&-x)*0x076be629 >> 27];
 
13
}
 
14
 
 
15
static inline int a_ctz_64(uint64_t x)
 
16
{
 
17
        uint32_t y = x;
 
18
        if (!y) {
 
19
                y = x>>32;
 
20
                return 32 + a_ctz_l(y);
 
21
        }
 
22
        return a_ctz_l(y);
 
23
}
 
24
 
 
25
static inline int a_cas(volatile int *p, int t, int s)
 
26
{
 
27
        int dummy;
 
28
        __asm__ __volatile__(
 
29
                ".set push\n"
 
30
                ".set mips2\n"
 
31
                ".set noreorder\n"
 
32
                "1:     ll %0, 0(%2)\n"
 
33
                "       bne %0, %3, 1f\n"
 
34
                "       addu %1, %4, $0\n"
 
35
                "       sc %1, 0(%2)\n"
 
36
                "       beq %1, $0, 1b\n"
 
37
                "       nop\n"
 
38
                "1:     \n"
 
39
                ".set pop\n"
 
40
                : "=&r"(t), "=&r"(dummy) : "r"(p), "r"(t), "r"(s) : "memory" );
 
41
        return t;
 
42
}
 
43
 
 
44
static inline void *a_cas_p(volatile void *p, void *t, void *s)
 
45
{
 
46
        return (void *)a_cas(p, (int)t, (int)s);
 
47
}
 
48
 
 
49
static inline long a_cas_l(volatile void *p, long t, long s)
 
50
{
 
51
        return a_cas(p, t, s);
 
52
}
 
53
 
 
54
 
 
55
static inline int a_swap(volatile int *x, int v)
 
56
{
 
57
        int old, dummy;
 
58
        __asm__ __volatile__(
 
59
                ".set push\n"
 
60
                ".set mips2\n"
 
61
                ".set noreorder\n"
 
62
                "1:     ll %0, 0(%2)\n"
 
63
                "       addu %1, %3, $0\n"
 
64
                "       sc %1, 0(%2)\n"
 
65
                "       beq %1, $0, 1b\n"
 
66
                "       nop\n"
 
67
                "1:     \n"
 
68
                ".set pop\n"
 
69
                : "=&r"(old), "=&r"(dummy) : "r"(x), "r"(v) : "memory" );
 
70
        return old;
 
71
}
 
72
 
 
73
static inline int a_fetch_add(volatile int *x, int v)
 
74
{
 
75
        int old, dummy;
 
76
        __asm__ __volatile__(
 
77
                ".set push\n"
 
78
                ".set mips2\n"
 
79
                ".set noreorder\n"
 
80
                "1:     ll %0, 0(%2)\n"
 
81
                "       addu %1, %0, %3\n"
 
82
                "       sc %1, 0(%2)\n"
 
83
                "       beq %1, $0, 1b\n"
 
84
                "       nop\n"
 
85
                "1:     \n"
 
86
                ".set pop\n"
 
87
                : "=&r"(old), "=&r"(dummy) : "r"(x), "r"(v) : "memory" );
 
88
        return old;
 
89
}
 
90
 
 
91
static inline void a_inc(volatile int *x)
 
92
{
 
93
        int dummy;
 
94
        __asm__ __volatile__(
 
95
                ".set push\n"
 
96
                ".set mips2\n"
 
97
                ".set noreorder\n"
 
98
                "1:     ll %0, 0(%1)\n"
 
99
                "       addu %0, %0, 1\n"
 
100
                "       sc %0, 0(%1)\n"
 
101
                "       beq %0, $0, 1b\n"
 
102
                "       nop\n"
 
103
                "1:     \n"
 
104
                ".set pop\n"
 
105
                : "=&r"(dummy) : "r"(x) : "memory" );
 
106
}
 
107
 
 
108
static inline void a_dec(volatile int *x)
 
109
{
 
110
        int dummy;
 
111
        __asm__ __volatile__(
 
112
                ".set push\n"
 
113
                ".set mips2\n"
 
114
                ".set noreorder\n"
 
115
                "1:     ll %0, 0(%1)\n"
 
116
                "       subu %0, %0, 1\n"
 
117
                "       sc %0, 0(%1)\n"
 
118
                "       beq %0, $0, 1b\n"
 
119
                "       nop\n"
 
120
                "1:     \n"
 
121
                ".set pop\n"
 
122
                : "=&r"(dummy) : "r"(x) : "memory" );
 
123
}
 
124
 
 
125
static inline void a_store(volatile int *p, int x)
 
126
{
 
127
        int dummy;
 
128
        __asm__ __volatile__(
 
129
                ".set push\n"
 
130
                ".set mips2\n"
 
131
                ".set noreorder\n"
 
132
                "1:     ll %0, 0(%1)\n"
 
133
                "       addu %0, %2, $0\n"
 
134
                "       sc %0, 0(%1)\n"
 
135
                "       beq %0, $0, 1b\n"
 
136
                "       nop\n"
 
137
                "1:     \n"
 
138
                ".set pop\n"
 
139
                : "=&r"(dummy) : "r"(p), "r"(x) : "memory" );
 
140
}
 
141
 
 
142
static inline void a_spin()
 
143
{
 
144
}
 
145
 
 
146
static inline void a_crash()
 
147
{
 
148
        *(volatile char *)0=0;
 
149
}
 
150
 
 
151
static inline void a_and(volatile int *p, int v)
 
152
{
 
153
        int dummy;
 
154
        __asm__ __volatile__(
 
155
                ".set push\n"
 
156
                ".set mips2\n"
 
157
                ".set noreorder\n"
 
158
                "1:     ll %0, 0(%1)\n"
 
159
                "       and %0, %0, %2\n"
 
160
                "       sc %0, 0(%1)\n"
 
161
                "       beq %0, $0, 1b\n"
 
162
                "       nop\n"
 
163
                "1:     \n"
 
164
                ".set pop\n"
 
165
                : "=&r"(dummy) : "r"(p), "r"(v) : "memory" );
 
166
}
 
167
 
 
168
static inline void a_or(volatile int *p, int v)
 
169
{
 
170
        int dummy;
 
171
        __asm__ __volatile__(
 
172
                ".set push\n"
 
173
                ".set mips2\n"
 
174
                ".set noreorder\n"
 
175
                "1:     ll %0, 0(%1)\n"
 
176
                "       or %0, %0, %2\n"
 
177
                "       sc %0, 0(%1)\n"
 
178
                "       beq %0, $0, 1b\n"
 
179
                "       nop\n"
 
180
                "1:     \n"
 
181
                ".set pop\n"
 
182
                : "=&r"(dummy) : "r"(p), "r"(v) : "memory" );
 
183
}
 
184
 
 
185
static inline void a_or_l(volatile void *p, long v)
 
186
{
 
187
        a_or(p, v);
 
188
}
 
189
 
 
190
static inline void a_and_64(volatile uint64_t *p, uint64_t v)
 
191
{
 
192
        union { uint64_t v; uint32_t r[2]; } u = { v };
 
193
        a_and((int *)p, u.r[0]);
 
194
        a_and((int *)p+1, u.r[1]);
 
195
}
 
196
 
 
197
static inline void a_or_64(volatile uint64_t *p, uint64_t v)
 
198
{
 
199
        union { uint64_t v; uint32_t r[2]; } u = { v };
 
200
        a_or((int *)p, u.r[0]);
 
201
        a_or((int *)p+1, u.r[1]);
 
202
}
 
203
 
 
204
#endif