1 // Copyright 2015 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 mips64 || mips64le
6
7 #include "textflag.h"
8
9 #define SYNC WORD $0xf
10
11 // func cas(ptr *uint32, old, new uint32) bool
12 // Atomically:
13 // if *ptr == old {
14 // *ptr = new
15 // return true
16 // } else {
17 // return false
18 // }
19 TEXT ·Cas(SB), NOSPLIT, $0-17
20 MOVV ptr+0(FP), R1
21 MOVW old+8(FP), R2
22 MOVW new+12(FP), R5
23 SYNC
24 cas_again:
25 MOVV R5, R3
26 LL (R1), R4
27 BNE R2, R4, cas_fail
28 SC R3, (R1)
29 BEQ R3, cas_again
30 MOVV $1, R1
31 MOVB R1, ret+16(FP)
32 SYNC
33 RET
34 cas_fail:
35 MOVV $0, R1
36 JMP -4(PC)
37
38 // func Cas64(ptr *uint64, old, new uint64) bool
39 // Atomically:
40 // if *ptr == old {
41 // *ptr = new
42 // return true
43 // } else {
44 // return false
45 // }
46 TEXT ·Cas64(SB), NOSPLIT, $0-25
47 MOVV ptr+0(FP), R1
48 MOVV old+8(FP), R2
49 MOVV new+16(FP), R5
50 SYNC
51 cas64_again:
52 MOVV R5, R3
53 LLV (R1), R4
54 BNE R2, R4, cas64_fail
55 SCV R3, (R1)
56 BEQ R3, cas64_again
57 MOVV $1, R1
58 MOVB R1, ret+24(FP)
59 SYNC
60 RET
61 cas64_fail:
62 MOVV $0, R1
63 JMP -4(PC)
64
65 TEXT ·Casint32(SB), NOSPLIT, $0-17
66 JMP ·Cas(SB)
67
68 TEXT ·Casint64(SB), NOSPLIT, $0-25
69 JMP ·Cas64(SB)
70
71 TEXT ·Casuintptr(SB), NOSPLIT, $0-25
72 JMP ·Cas64(SB)
73
74 TEXT ·CasRel(SB), NOSPLIT, $0-17
75 JMP ·Cas(SB)
76
77 TEXT ·Loaduintptr(SB), NOSPLIT|NOFRAME, $0-16
78 JMP ·Load64(SB)
79
80 TEXT ·Loaduint(SB), NOSPLIT|NOFRAME, $0-16
81 JMP ·Load64(SB)
82
83 TEXT ·Storeint32(SB), NOSPLIT, $0-12
84 JMP ·Store(SB)
85
86 TEXT ·Storeint64(SB), NOSPLIT, $0-16
87 JMP ·Store64(SB)
88
89 TEXT ·Storeuintptr(SB), NOSPLIT, $0-16
90 JMP ·Store64(SB)
91
92 TEXT ·Xadduintptr(SB), NOSPLIT, $0-24
93 JMP ·Xadd64(SB)
94
95 TEXT ·Loadint32(SB), NOSPLIT, $0-12
96 JMP ·Load(SB)
97
98 TEXT ·Loadint64(SB), NOSPLIT, $0-16
99 JMP ·Load64(SB)
100
101 TEXT ·Xaddint32(SB), NOSPLIT, $0-20
102 JMP ·Xadd(SB)
103
104 TEXT ·Xaddint64(SB), NOSPLIT, $0-24
105 JMP ·Xadd64(SB)
106
107 // func Casp1(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool
108 // Atomically:
109 // if *ptr == old {
110 // *ptr = new
111 // return true
112 // } else {
113 // return false
114 // }
115 TEXT ·Casp1(SB), NOSPLIT, $0-25
116 JMP ·Cas64(SB)
117
118 // uint32 xadd(uint32 volatile *ptr, int32 delta)
119 // Atomically:
120 // *val += delta;
121 // return *val;
122 TEXT ·Xadd(SB), NOSPLIT, $0-20
123 MOVV ptr+0(FP), R2
124 MOVW delta+8(FP), R3
125 SYNC
126 LL (R2), R1
127 ADDU R1, R3, R4
128 MOVV R4, R1
129 SC R4, (R2)
130 BEQ R4, -4(PC)
131 MOVW R1, ret+16(FP)
132 SYNC
133 RET
134
135 // uint64 Xadd64(uint64 volatile *ptr, int64 delta)
136 // Atomically:
137 // *val += delta;
138 // return *val;
139 TEXT ·Xadd64(SB), NOSPLIT, $0-24
140 MOVV ptr+0(FP), R2
141 MOVV delta+8(FP), R3
142 SYNC
143 LLV (R2), R1
144 ADDVU R1, R3, R4
145 MOVV R4, R1
146 SCV R4, (R2)
147 BEQ R4, -4(PC)
148 MOVV R1, ret+16(FP)
149 SYNC
150 RET
151
152 // uint8 Xchg(ptr *uint8, new uint8)
153 // Atomically:
154 // old := *ptr;
155 // *ptr = new;
156 // return old;
157 TEXT ·Xchg8(SB), NOSPLIT, $0-17
158 MOVV ptr+0(FP), R2
159 MOVBU new+8(FP), R5
160 #ifdef GOARCH_mips64
161 // Big endian. ptr = ptr ^ 3
162 XOR $3, R2
163 #endif
164 // R4 = ((ptr & 3) * 8)
165 AND $3, R2, R4
166 SLLV $3, R4
167 // Shift val for aligned ptr. R7 = (0xFF << R4) ^ (-1)
168 MOVV $0xFF, R7
169 SLLV R4, R7
170 XOR $-1, R7
171 AND $~3, R2
172 SLLV R4, R5
173
174 SYNC
175 LL (R2), R9
176 AND R7, R9, R8
177 OR R5, R8
178 SC R8, (R2)
179 BEQ R8, -5(PC)
180 SYNC
181 SRLV R4, R9
182 MOVBU R9, ret+16(FP)
183 RET
184
185 // uint32 Xchg(ptr *uint32, new uint32)
186 // Atomically:
187 // old := *ptr;
188 // *ptr = new;
189 // return old;
190 TEXT ·Xchg(SB), NOSPLIT, $0-20
191 MOVV ptr+0(FP), R2
192 MOVW new+8(FP), R5
193
194 SYNC
195 MOVV R5, R3
196 LL (R2), R1
197 SC R3, (R2)
198 BEQ R3, -3(PC)
199 MOVW R1, ret+16(FP)
200 SYNC
201 RET
202
203 // uint64 Xchg64(ptr *uint64, new uint64)
204 // Atomically:
205 // old := *ptr;
206 // *ptr = new;
207 // return old;
208 TEXT ·Xchg64(SB), NOSPLIT, $0-24
209 MOVV ptr+0(FP), R2
210 MOVV new+8(FP), R5
211
212 SYNC
213 MOVV R5, R3
214 LLV (R2), R1
215 SCV R3, (R2)
216 BEQ R3, -3(PC)
217 MOVV R1, ret+16(FP)
218 SYNC
219 RET
220
221 TEXT ·Xchgint32(SB), NOSPLIT, $0-20
222 JMP ·Xchg(SB)
223
224 TEXT ·Xchgint64(SB), NOSPLIT, $0-24
225 JMP ·Xchg64(SB)
226
227 TEXT ·Xchguintptr(SB), NOSPLIT, $0-24
228 JMP ·Xchg64(SB)
229
230 TEXT ·StorepNoWB(SB), NOSPLIT, $0-16
231 JMP ·Store64(SB)
232
233 TEXT ·StoreRel(SB), NOSPLIT, $0-12
234 JMP ·Store(SB)
235
236 TEXT ·StoreRel64(SB), NOSPLIT, $0-16
237 JMP ·Store64(SB)
238
239 TEXT ·StoreReluintptr(SB), NOSPLIT, $0-16
240 JMP ·Store64(SB)
241
242 TEXT ·Store(SB), NOSPLIT, $0-12
243 MOVV ptr+0(FP), R1
244 MOVW val+8(FP), R2
245 SYNC
246 MOVW R2, 0(R1)
247 SYNC
248 RET
249
250 TEXT ·Store8(SB), NOSPLIT, $0-9
251 MOVV ptr+0(FP), R1
252 MOVB val+8(FP), R2
253 SYNC
254 MOVB R2, 0(R1)
255 SYNC
256 RET
257
258 TEXT ·Store64(SB), NOSPLIT, $0-16
259 MOVV ptr+0(FP), R1
260 MOVV val+8(FP), R2
261 SYNC
262 MOVV R2, 0(R1)
263 SYNC
264 RET
265
266 // void Or8(byte volatile*, byte);
267 TEXT ·Or8(SB), NOSPLIT, $0-9
268 MOVV ptr+0(FP), R1
269 MOVBU val+8(FP), R2
270 // Align ptr down to 4 bytes so we can use 32-bit load/store.
271 MOVV $~3, R3
272 AND R1, R3
273 // Compute val shift.
274 #ifdef GOARCH_mips64
275 // Big endian. ptr = ptr ^ 3
276 XOR $3, R1
277 #endif
278 // R4 = ((ptr & 3) * 8)
279 AND $3, R1, R4
280 SLLV $3, R4
281 // Shift val for aligned ptr. R2 = val << R4
282 SLLV R4, R2
283
284 SYNC
285 LL (R3), R4
286 OR R2, R4
287 SC R4, (R3)
288 BEQ R4, -4(PC)
289 SYNC
290 RET
291
292 // void And8(byte volatile*, byte);
293 TEXT ·And8(SB), NOSPLIT, $0-9
294 MOVV ptr+0(FP), R1
295 MOVBU val+8(FP), R2
296 // Align ptr down to 4 bytes so we can use 32-bit load/store.
297 MOVV $~3, R3
298 AND R1, R3
299 // Compute val shift.
300 #ifdef GOARCH_mips64
301 // Big endian. ptr = ptr ^ 3
302 XOR $3, R1
303 #endif
304 // R4 = ((ptr & 3) * 8)
305 AND $3, R1, R4
306 SLLV $3, R4
307 // Shift val for aligned ptr. R2 = val << R4 | ^(0xFF << R4)
308 MOVV $0xFF, R5
309 SLLV R4, R2
310 SLLV R4, R5
311 NOR R0, R5
312 OR R5, R2
313
314 SYNC
315 LL (R3), R4
316 AND R2, R4
317 SC R4, (R3)
318 BEQ R4, -4(PC)
319 SYNC
320 RET
321
322 // func Or(addr *uint32, v uint32)
323 TEXT ·Or(SB), NOSPLIT, $0-12
324 MOVV ptr+0(FP), R1
325 MOVW val+8(FP), R2
326
327 SYNC
328 LL (R1), R3
329 OR R2, R3
330 SC R3, (R1)
331 BEQ R3, -4(PC)
332 SYNC
333 RET
334
335 // func And(addr *uint32, v uint32)
336 TEXT ·And(SB), NOSPLIT, $0-12
337 MOVV ptr+0(FP), R1
338 MOVW val+8(FP), R2
339
340 SYNC
341 LL (R1), R3
342 AND R2, R3
343 SC R3, (R1)
344 BEQ R3, -4(PC)
345 SYNC
346 RET
347
348 // func Or32(addr *uint32, v uint32) old uint32
349 TEXT ·Or32(SB), NOSPLIT, $0-20
350 MOVV ptr+0(FP), R1
351 MOVW val+8(FP), R2
352
353 SYNC
354 LL (R1), R3
355 OR R2, R3, R4
356 SC R4, (R1)
357 BEQ R4, -3(PC)
358 SYNC
359 MOVW R3, ret+16(FP)
360 RET
361
362 // func And32(addr *uint32, v uint32) old uint32
363 TEXT ·And32(SB), NOSPLIT, $0-20
364 MOVV ptr+0(FP), R1
365 MOVW val+8(FP), R2
366
367 SYNC
368 LL (R1), R3
369 AND R2, R3, R4
370 SC R4, (R1)
371 BEQ R4, -3(PC)
372 SYNC
373 MOVW R3, ret+16(FP)
374 RET
375
376 // func Or64(addr *uint64, v uint64) old uint64
377 TEXT ·Or64(SB), NOSPLIT, $0-24
378 MOVV ptr+0(FP), R1
379 MOVV val+8(FP), R2
380
381 SYNC
382 LLV (R1), R3
383 OR R2, R3, R4
384 SCV R4, (R1)
385 BEQ R4, -3(PC)
386 SYNC
387 MOVV R3, ret+16(FP)
388 RET
389
390 // func And64(addr *uint64, v uint64) old uint64
391 TEXT ·And64(SB), NOSPLIT, $0-24
392 MOVV ptr+0(FP), R1
393 MOVV val+8(FP), R2
394
395 SYNC
396 LLV (R1), R3
397 AND R2, R3, R4
398 SCV R4, (R1)
399 BEQ R4, -3(PC)
400 SYNC
401 MOVV R3, ret+16(FP)
402 RET
403
404 // func Anduintptr(addr *uintptr, v uintptr) old uintptr
405 TEXT ·Anduintptr(SB), NOSPLIT, $0-24
406 JMP ·And64(SB)
407
408 // func Oruintptr(addr *uintptr, v uintptr) old uintptr
409 TEXT ·Oruintptr(SB), NOSPLIT, $0-24
410 JMP ·Or64(SB)
411
412 // uint32 ·Load(uint32 volatile* ptr)
413 TEXT ·Load(SB),NOSPLIT|NOFRAME,$0-12
414 MOVV ptr+0(FP), R1
415 SYNC
416 MOVWU 0(R1), R1
417 SYNC
418 MOVW R1, ret+8(FP)
419 RET
420
421 // uint8 ·Load8(uint8 volatile* ptr)
422 TEXT ·Load8(SB),NOSPLIT|NOFRAME,$0-9
423 MOVV ptr+0(FP), R1
424 SYNC
425 MOVBU 0(R1), R1
426 SYNC
427 MOVB R1, ret+8(FP)
428 RET
429
430 // uint64 ·Load64(uint64 volatile* ptr)
431 TEXT ·Load64(SB),NOSPLIT|NOFRAME,$0-16
432 MOVV ptr+0(FP), R1
433 SYNC
434 MOVV 0(R1), R1
435 SYNC
436 MOVV R1, ret+8(FP)
437 RET
438
439 // void *·Loadp(void *volatile *ptr)
440 TEXT ·Loadp(SB),NOSPLIT|NOFRAME,$0-16
441 MOVV ptr+0(FP), R1
442 SYNC
443 MOVV 0(R1), R1
444 SYNC
445 MOVV R1, ret+8(FP)
446 RET
447
448 // uint32 ·LoadAcq(uint32 volatile* ptr)
449 TEXT ·LoadAcq(SB),NOSPLIT|NOFRAME,$0-12
450 JMP atomic·Load(SB)
451
452 // uint64 ·LoadAcq64(uint64 volatile* ptr)
453 TEXT ·LoadAcq64(SB),NOSPLIT|NOFRAME,$0-16
454 JMP atomic·Load64(SB)
455
456 // uintptr ·LoadAcquintptr(uintptr volatile* ptr)
457 TEXT ·LoadAcquintptr(SB),NOSPLIT|NOFRAME,$0-16
458 JMP atomic·Load64(SB)
459
View as plain text