1 // Copyright 2016 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 //go:build mips || mipsle
6
7 #include "textflag.h"
8
9 // func Cas(ptr *int32, old, new int32) bool
10 // Atomically:
11 // if *ptr == old {
12 // *ptr = new
13 // return true
14 // } else {
15 // return false
16 // }
17 TEXT ·Cas(SB),NOSPLIT,$0-13
18 MOVW ptr+0(FP), R1
19 MOVW old+4(FP), R2
20 MOVW new+8(FP), R5
21 SYNC
22 try_cas:
23 MOVW R5, R3
24 LL (R1), R4 // R4 = *R1
25 BNE R2, R4, cas_fail
26 SC R3, (R1) // *R1 = R3
27 BEQ R3, try_cas
28 SYNC
29 MOVB R3, ret+12(FP)
30 RET
31 cas_fail:
32 SYNC
33 MOVB R0, ret+12(FP)
34 RET
35
36 TEXT ·Store(SB),NOSPLIT,$0-8
37 MOVW ptr+0(FP), R1
38 MOVW val+4(FP), R2
39 SYNC
40 MOVW R2, 0(R1)
41 SYNC
42 RET
43
44 TEXT ·Store8(SB),NOSPLIT,$0-5
45 MOVW ptr+0(FP), R1
46 MOVB val+4(FP), R2
47 SYNC
48 MOVB R2, 0(R1)
49 SYNC
50 RET
51
52 TEXT ·Load(SB),NOSPLIT,$0-8
53 MOVW ptr+0(FP), R1
54 SYNC
55 MOVW 0(R1), R1
56 SYNC
57 MOVW R1, ret+4(FP)
58 RET
59
60 TEXT ·Load8(SB),NOSPLIT,$0-5
61 MOVW ptr+0(FP), R1
62 SYNC
63 MOVB 0(R1), R1
64 SYNC
65 MOVB R1, ret+4(FP)
66 RET
67
68 // uint32 Xadd(uint32 volatile *val, int32 delta)
69 // Atomically:
70 // *val += delta;
71 // return *val;
72 TEXT ·Xadd(SB),NOSPLIT,$0-12
73 MOVW ptr+0(FP), R2
74 MOVW delta+4(FP), R3
75 SYNC
76 try_xadd:
77 LL (R2), R1 // R1 = *R2
78 ADDU R1, R3, R4
79 MOVW R4, R1
80 SC R4, (R2) // *R2 = R4
81 BEQ R4, try_xadd
82 SYNC
83 MOVW R1, ret+8(FP)
84 RET
85
86 // uint32 Xchg(ptr *uint32, new uint32)
87 // Atomically:
88 // old := *ptr;
89 // *ptr = new;
90 // return old;
91 TEXT ·Xchg(SB),NOSPLIT,$0-12
92 MOVW ptr+0(FP), R2
93 MOVW new+4(FP), R5
94 SYNC
95 try_xchg:
96 MOVW R5, R3
97 LL (R2), R1 // R1 = *R2
98 SC R3, (R2) // *R2 = R3
99 BEQ R3, try_xchg
100 SYNC
101 MOVW R1, ret+8(FP)
102 RET
103
104 // uint8 Xchg(ptr *uint8, new uint8)
105 // Atomically:
106 // old := *ptr;
107 // *ptr = new;
108 // return old;
109 TEXT ·Xchg8(SB), NOSPLIT, $0-9
110 MOVW ptr+0(FP), R2
111 MOVBU new+4(FP), R5
112 #ifdef GOARCH_mips
113 // Big endian. ptr = ptr ^ 3
114 XOR $3, R2
115 #endif
116 // R4 = ((ptr & 3) * 8)
117 AND $3, R2, R4
118 SLL $3, R4
119 // Shift val for aligned ptr. R7 = (0xFF << R4) ^ (-1)
120 MOVW $0xFF, R7
121 SLL R4, R7
122 XOR $-1, R7
123 AND $~3, R2
124 SLL R4, R5
125
126 SYNC
127 LL (R2), R9
128 AND R7, R9, R8
129 OR R5, R8
130 SC R8, (R2)
131 BEQ R8, -5(PC)
132 SYNC
133 SRL R4, R9
134 MOVBU R9, ret+8(FP)
135 RET
136
137 TEXT ·Casint32(SB),NOSPLIT,$0-13
138 JMP ·Cas(SB)
139
140 TEXT ·Casint64(SB),NOSPLIT,$0-21
141 JMP ·Cas64(SB)
142
143 TEXT ·Casuintptr(SB),NOSPLIT,$0-13
144 JMP ·Cas(SB)
145
146 TEXT ·CasRel(SB),NOSPLIT,$0-13
147 JMP ·Cas(SB)
148
149 TEXT ·Loaduintptr(SB),NOSPLIT,$0-8
150 JMP ·Load(SB)
151
152 TEXT ·Loaduint(SB),NOSPLIT,$0-8
153 JMP ·Load(SB)
154
155 TEXT ·Loadp(SB),NOSPLIT,$-0-8
156 JMP ·Load(SB)
157
158 TEXT ·Storeint32(SB),NOSPLIT,$0-8
159 JMP ·Store(SB)
160
161 TEXT ·Storeint64(SB),NOSPLIT,$0-12
162 JMP ·Store64(SB)
163
164 TEXT ·Storeuintptr(SB),NOSPLIT,$0-8
165 JMP ·Store(SB)
166
167 TEXT ·Xadduintptr(SB),NOSPLIT,$0-12
168 JMP ·Xadd(SB)
169
170 TEXT ·Loadint32(SB),NOSPLIT,$0-8
171 JMP ·Load(SB)
172
173 TEXT ·Loadint64(SB),NOSPLIT,$0-12
174 JMP ·Load64(SB)
175
176 TEXT ·Xaddint32(SB),NOSPLIT,$0-12
177 JMP ·Xadd(SB)
178
179 TEXT ·Xaddint64(SB),NOSPLIT,$0-20
180 JMP ·Xadd64(SB)
181
182 TEXT ·Casp1(SB),NOSPLIT,$0-13
183 JMP ·Cas(SB)
184
185 TEXT ·Xchgint32(SB),NOSPLIT,$0-12
186 JMP ·Xchg(SB)
187
188 TEXT ·Xchgint64(SB),NOSPLIT,$0-20
189 JMP ·Xchg64(SB)
190
191 TEXT ·Xchguintptr(SB),NOSPLIT,$0-12
192 JMP ·Xchg(SB)
193
194 TEXT ·StorepNoWB(SB),NOSPLIT,$0-8
195 JMP ·Store(SB)
196
197 TEXT ·StoreRel(SB),NOSPLIT,$0-8
198 JMP ·Store(SB)
199
200 TEXT ·StoreReluintptr(SB),NOSPLIT,$0-8
201 JMP ·Store(SB)
202
203 // void Or8(byte volatile*, byte);
204 TEXT ·Or8(SB),NOSPLIT,$0-5
205 MOVW ptr+0(FP), R1
206 MOVBU val+4(FP), R2
207 MOVW $~3, R3 // Align ptr down to 4 bytes so we can use 32-bit load/store.
208 AND R1, R3
209 #ifdef GOARCH_mips
210 // Big endian. ptr = ptr ^ 3
211 XOR $3, R1
212 #endif
213 AND $3, R1, R4 // R4 = ((ptr & 3) * 8)
214 SLL $3, R4
215 SLL R4, R2, R2 // Shift val for aligned ptr. R2 = val << R4
216 SYNC
217 try_or8:
218 LL (R3), R4 // R4 = *R3
219 OR R2, R4
220 SC R4, (R3) // *R3 = R4
221 BEQ R4, try_or8
222 SYNC
223 RET
224
225 // void And8(byte volatile*, byte);
226 TEXT ·And8(SB),NOSPLIT,$0-5
227 MOVW ptr+0(FP), R1
228 MOVBU val+4(FP), R2
229 MOVW $~3, R3
230 AND R1, R3
231 #ifdef GOARCH_mips
232 // Big endian. ptr = ptr ^ 3
233 XOR $3, R1
234 #endif
235 AND $3, R1, R4 // R4 = ((ptr & 3) * 8)
236 SLL $3, R4
237 MOVW $0xFF, R5
238 SLL R4, R2
239 SLL R4, R5
240 NOR R0, R5
241 OR R5, R2 // Shift val for aligned ptr. R2 = val << R4 | ^(0xFF << R4)
242 SYNC
243 try_and8:
244 LL (R3), R4 // R4 = *R3
245 AND R2, R4
246 SC R4, (R3) // *R3 = R4
247 BEQ R4, try_and8
248 SYNC
249 RET
250
251 // func Or(addr *uint32, v uint32)
252 TEXT ·Or(SB), NOSPLIT, $0-8
253 MOVW ptr+0(FP), R1
254 MOVW val+4(FP), R2
255
256 SYNC
257 LL (R1), R3
258 OR R2, R3
259 SC R3, (R1)
260 BEQ R3, -4(PC)
261 SYNC
262 RET
263
264 // func And(addr *uint32, v uint32)
265 TEXT ·And(SB), NOSPLIT, $0-8
266 MOVW ptr+0(FP), R1
267 MOVW val+4(FP), R2
268
269 SYNC
270 LL (R1), R3
271 AND R2, R3
272 SC R3, (R1)
273 BEQ R3, -4(PC)
274 SYNC
275 RET
276
277 // func Or32(addr *uint32, v uint32) old uint32
278 TEXT ·Or32(SB), NOSPLIT, $0-12
279 MOVW ptr+0(FP), R1
280 MOVW val+4(FP), R2
281
282 SYNC
283 LL (R1), R3
284 OR R2, R3, R4
285 SC R4, (R1)
286 BEQ R4, -4(PC)
287 SYNC
288 MOVW R3, ret+8(FP)
289 RET
290
291 // func And32(addr *uint32, v uint32) old uint32
292 TEXT ·And32(SB), NOSPLIT, $0-12
293 MOVW ptr+0(FP), R1
294 MOVW val+4(FP), R2
295
296 SYNC
297 LL (R1), R3
298 AND R2, R3, R4
299 SC R4, (R1)
300 BEQ R4, -4(PC)
301 SYNC
302 MOVW R3, ret+8(FP)
303 RET
304
305 // func Anduintptr(addr *uintptr, v uintptr) old uintptr
306 TEXT ·Anduintptr(SB), NOSPLIT, $0-12
307 JMP ·And32(SB)
308
309 // func Oruintptr(addr *uintptr, v uintptr) old uintptr
310 TEXT ·Oruintptr(SB), NOSPLIT, $0-12
311 JMP ·Or32(SB)
312
313 TEXT ·spinLock(SB),NOSPLIT,$0-4
314 MOVW state+0(FP), R1
315 MOVW $1, R2
316 SYNC
317 try_lock:
318 MOVW R2, R3
319 check_again:
320 LL (R1), R4
321 BNE R4, check_again
322 SC R3, (R1)
323 BEQ R3, try_lock
324 SYNC
325 RET
326
327 TEXT ·spinUnlock(SB),NOSPLIT,$0-4
328 MOVW state+0(FP), R1
329 SYNC
330 MOVW R0, (R1)
331 SYNC
332 RET
333
View as plain text