1 // Copyright 2014 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 #include "go_asm.h"
6 #include "textflag.h"
7
8 TEXT ·Casint32(SB), NOSPLIT, $0-17
9 B ·Cas(SB)
10
11 TEXT ·Casint64(SB), NOSPLIT, $0-25
12 B ·Cas64(SB)
13
14 TEXT ·Casuintptr(SB), NOSPLIT, $0-25
15 B ·Cas64(SB)
16
17 TEXT ·CasRel(SB), NOSPLIT, $0-17
18 B ·Cas(SB)
19
20 TEXT ·Loadint32(SB), NOSPLIT, $0-12
21 B ·Load(SB)
22
23 TEXT ·Loadint64(SB), NOSPLIT, $0-16
24 B ·Load64(SB)
25
26 TEXT ·Loaduintptr(SB), NOSPLIT, $0-16
27 B ·Load64(SB)
28
29 TEXT ·Loaduint(SB), NOSPLIT, $0-16
30 B ·Load64(SB)
31
32 TEXT ·Storeint32(SB), NOSPLIT, $0-12
33 B ·Store(SB)
34
35 TEXT ·Storeint64(SB), NOSPLIT, $0-16
36 B ·Store64(SB)
37
38 TEXT ·Storeuintptr(SB), NOSPLIT, $0-16
39 B ·Store64(SB)
40
41 TEXT ·Xaddint32(SB), NOSPLIT, $0-20
42 B ·Xadd(SB)
43
44 TEXT ·Xaddint64(SB), NOSPLIT, $0-24
45 B ·Xadd64(SB)
46
47 TEXT ·Xadduintptr(SB), NOSPLIT, $0-24
48 B ·Xadd64(SB)
49
50 TEXT ·Casp1(SB), NOSPLIT, $0-25
51 B ·Cas64(SB)
52
53 // uint32 ·Load(uint32 volatile* addr)
54 TEXT ·Load(SB),NOSPLIT,$0-12
55 MOVD ptr+0(FP), R0
56 LDARW (R0), R0
57 MOVW R0, ret+8(FP)
58 RET
59
60 // uint8 ·Load8(uint8 volatile* addr)
61 TEXT ·Load8(SB),NOSPLIT,$0-9
62 MOVD ptr+0(FP), R0
63 LDARB (R0), R0
64 MOVB R0, ret+8(FP)
65 RET
66
67 // uint64 ·Load64(uint64 volatile* addr)
68 TEXT ·Load64(SB),NOSPLIT,$0-16
69 MOVD ptr+0(FP), R0
70 LDAR (R0), R0
71 MOVD R0, ret+8(FP)
72 RET
73
74 // void *·Loadp(void *volatile *addr)
75 TEXT ·Loadp(SB),NOSPLIT,$0-16
76 MOVD ptr+0(FP), R0
77 LDAR (R0), R0
78 MOVD R0, ret+8(FP)
79 RET
80
81 // uint32 ·LoadAcq(uint32 volatile* addr)
82 TEXT ·LoadAcq(SB),NOSPLIT,$0-12
83 B ·Load(SB)
84
85 // uint64 ·LoadAcquintptr(uint64 volatile* addr)
86 TEXT ·LoadAcq64(SB),NOSPLIT,$0-16
87 B ·Load64(SB)
88
89 // uintptr ·LoadAcq64(uintptr volatile* addr)
90 TEXT ·LoadAcquintptr(SB),NOSPLIT,$0-16
91 B ·Load64(SB)
92
93 TEXT ·StorepNoWB(SB), NOSPLIT, $0-16
94 B ·Store64(SB)
95
96 TEXT ·StoreRel(SB), NOSPLIT, $0-12
97 B ·Store(SB)
98
99 TEXT ·StoreRel64(SB), NOSPLIT, $0-16
100 B ·Store64(SB)
101
102 TEXT ·StoreReluintptr(SB), NOSPLIT, $0-16
103 B ·Store64(SB)
104
105 TEXT ·Store(SB), NOSPLIT, $0-12
106 MOVD ptr+0(FP), R0
107 MOVW val+8(FP), R1
108 STLRW R1, (R0)
109 RET
110
111 TEXT ·Store8(SB), NOSPLIT, $0-9
112 MOVD ptr+0(FP), R0
113 MOVB val+8(FP), R1
114 STLRB R1, (R0)
115 RET
116
117 TEXT ·Store64(SB), NOSPLIT, $0-16
118 MOVD ptr+0(FP), R0
119 MOVD val+8(FP), R1
120 STLR R1, (R0)
121 RET
122
123 // uint8 Xchg(ptr *uint8, new uint8)
124 // Atomically:
125 // old := *ptr;
126 // *ptr = new;
127 // return old;
128 TEXT ·Xchg8(SB), NOSPLIT, $0-17
129 MOVD ptr+0(FP), R0
130 MOVB new+8(FP), R1
131 #ifndef GOARM64_LSE
132 MOVBU internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
133 CBZ R4, load_store_loop
134 #endif
135 SWPALB R1, (R0), R2
136 MOVB R2, ret+16(FP)
137 RET
138 #ifndef GOARM64_LSE
139 load_store_loop:
140 LDAXRB (R0), R2
141 STLXRB R1, (R0), R3
142 CBNZ R3, load_store_loop
143 MOVB R2, ret+16(FP)
144 RET
145 #endif
146
147 // uint32 Xchg(ptr *uint32, new uint32)
148 // Atomically:
149 // old := *ptr;
150 // *ptr = new;
151 // return old;
152 TEXT ·Xchg(SB), NOSPLIT, $0-20
153 MOVD ptr+0(FP), R0
154 MOVW new+8(FP), R1
155 #ifndef GOARM64_LSE
156 MOVBU internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
157 CBZ R4, load_store_loop
158 #endif
159 SWPALW R1, (R0), R2
160 MOVW R2, ret+16(FP)
161 RET
162 #ifndef GOARM64_LSE
163 load_store_loop:
164 LDAXRW (R0), R2
165 STLXRW R1, (R0), R3
166 CBNZ R3, load_store_loop
167 MOVW R2, ret+16(FP)
168 RET
169 #endif
170
171 // uint64 Xchg64(ptr *uint64, new uint64)
172 // Atomically:
173 // old := *ptr;
174 // *ptr = new;
175 // return old;
176 TEXT ·Xchg64(SB), NOSPLIT, $0-24
177 MOVD ptr+0(FP), R0
178 MOVD new+8(FP), R1
179 #ifndef GOARM64_LSE
180 MOVBU internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
181 CBZ R4, load_store_loop
182 #endif
183 SWPALD R1, (R0), R2
184 MOVD R2, ret+16(FP)
185 RET
186 #ifndef GOARM64_LSE
187 load_store_loop:
188 LDAXR (R0), R2
189 STLXR R1, (R0), R3
190 CBNZ R3, load_store_loop
191 MOVD R2, ret+16(FP)
192 RET
193 #endif
194
195 // func Cas(ptr *uint32, old, new uint32) bool
196 // Atomically:
197 // if *ptr == old {
198 // *ptr = new
199 // return true
200 // } else {
201 // return false
202 // }
203 TEXT ·Cas(SB), NOSPLIT, $0-17
204 MOVD ptr+0(FP), R0
205 MOVW old+8(FP), R1
206 MOVW new+12(FP), R2
207 #ifndef GOARM64_LSE
208 MOVBU internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
209 CBZ R4, load_store_loop
210 #endif
211 MOVD R1, R3
212 CASALW R3, (R0), R2
213 CMP R1, R3
214 CSET EQ, R0
215 MOVB R0, ret+16(FP)
216 RET
217 #ifndef GOARM64_LSE
218 load_store_loop:
219 LDAXRW (R0), R3
220 CMPW R1, R3
221 BNE ok
222 STLXRW R2, (R0), R3
223 CBNZ R3, load_store_loop
224 ok:
225 CSET EQ, R0
226 MOVB R0, ret+16(FP)
227 RET
228 #endif
229
230 // func Cas64(ptr *uint64, old, new uint64) bool
231 // Atomically:
232 // if *ptr == old {
233 // *ptr = new
234 // return true
235 // } else {
236 // return false
237 // }
238 TEXT ·Cas64(SB), NOSPLIT, $0-25
239 MOVD ptr+0(FP), R0
240 MOVD old+8(FP), R1
241 MOVD new+16(FP), R2
242 #ifndef GOARM64_LSE
243 MOVBU internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
244 CBZ R4, load_store_loop
245 #endif
246 MOVD R1, R3
247 CASALD R3, (R0), R2
248 CMP R1, R3
249 CSET EQ, R0
250 MOVB R0, ret+24(FP)
251 RET
252 #ifndef GOARM64_LSE
253 load_store_loop:
254 LDAXR (R0), R3
255 CMP R1, R3
256 BNE ok
257 STLXR R2, (R0), R3
258 CBNZ R3, load_store_loop
259 ok:
260 CSET EQ, R0
261 MOVB R0, ret+24(FP)
262 RET
263 #endif
264
265 // uint32 xadd(uint32 volatile *ptr, int32 delta)
266 // Atomically:
267 // *val += delta;
268 // return *val;
269 TEXT ·Xadd(SB), NOSPLIT, $0-20
270 MOVD ptr+0(FP), R0
271 MOVW delta+8(FP), R1
272 #ifndef GOARM64_LSE
273 MOVBU internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
274 CBZ R4, load_store_loop
275 #endif
276 LDADDALW R1, (R0), R2
277 ADD R1, R2
278 MOVW R2, ret+16(FP)
279 RET
280 #ifndef GOARM64_LSE
281 load_store_loop:
282 LDAXRW (R0), R2
283 ADDW R2, R1, R2
284 STLXRW R2, (R0), R3
285 CBNZ R3, load_store_loop
286 MOVW R2, ret+16(FP)
287 RET
288 #endif
289
290 // uint64 Xadd64(uint64 volatile *ptr, int64 delta)
291 // Atomically:
292 // *val += delta;
293 // return *val;
294 TEXT ·Xadd64(SB), NOSPLIT, $0-24
295 MOVD ptr+0(FP), R0
296 MOVD delta+8(FP), R1
297 #ifndef GOARM64_LSE
298 MOVBU internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
299 CBZ R4, load_store_loop
300 #endif
301 LDADDALD R1, (R0), R2
302 ADD R1, R2
303 MOVD R2, ret+16(FP)
304 RET
305 #ifndef GOARM64_LSE
306 load_store_loop:
307 LDAXR (R0), R2
308 ADD R2, R1, R2
309 STLXR R2, (R0), R3
310 CBNZ R3, load_store_loop
311 MOVD R2, ret+16(FP)
312 RET
313 #endif
314
315 TEXT ·Xchgint32(SB), NOSPLIT, $0-20
316 B ·Xchg(SB)
317
318 TEXT ·Xchgint64(SB), NOSPLIT, $0-24
319 B ·Xchg64(SB)
320
321 TEXT ·Xchguintptr(SB), NOSPLIT, $0-24
322 B ·Xchg64(SB)
323
324 TEXT ·And8(SB), NOSPLIT, $0-9
325 MOVD ptr+0(FP), R0
326 MOVB val+8(FP), R1
327 #ifndef GOARM64_LSE
328 MOVBU internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
329 CBZ R4, load_store_loop
330 #endif
331 MVN R1, R2
332 LDCLRALB R2, (R0), R3
333 RET
334 #ifndef GOARM64_LSE
335 load_store_loop:
336 LDAXRB (R0), R2
337 AND R1, R2
338 STLXRB R2, (R0), R3
339 CBNZ R3, load_store_loop
340 RET
341 #endif
342
343 TEXT ·Or8(SB), NOSPLIT, $0-9
344 MOVD ptr+0(FP), R0
345 MOVB val+8(FP), R1
346 #ifndef GOARM64_LSE
347 MOVBU internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
348 CBZ R4, load_store_loop
349 #endif
350 LDORALB R1, (R0), R2
351 RET
352 #ifndef GOARM64_LSE
353 load_store_loop:
354 LDAXRB (R0), R2
355 ORR R1, R2
356 STLXRB R2, (R0), R3
357 CBNZ R3, load_store_loop
358 RET
359 #endif
360
361 // func And(addr *uint32, v uint32)
362 TEXT ·And(SB), NOSPLIT, $0-12
363 MOVD ptr+0(FP), R0
364 MOVW val+8(FP), R1
365 #ifndef GOARM64_LSE
366 MOVBU internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
367 CBZ R4, load_store_loop
368 #endif
369 MVN R1, R2
370 LDCLRALW R2, (R0), R3
371 RET
372 #ifndef GOARM64_LSE
373 load_store_loop:
374 LDAXRW (R0), R2
375 AND R1, R2
376 STLXRW R2, (R0), R3
377 CBNZ R3, load_store_loop
378 RET
379 #endif
380
381 // func Or(addr *uint32, v uint32)
382 TEXT ·Or(SB), NOSPLIT, $0-12
383 MOVD ptr+0(FP), R0
384 MOVW val+8(FP), R1
385 #ifndef GOARM64_LSE
386 MOVBU internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
387 CBZ R4, load_store_loop
388 #endif
389 LDORALW R1, (R0), R2
390 RET
391 #ifndef GOARM64_LSE
392 load_store_loop:
393 LDAXRW (R0), R2
394 ORR R1, R2
395 STLXRW R2, (R0), R3
396 CBNZ R3, load_store_loop
397 RET
398 #endif
399
400 // func Or32(addr *uint32, v uint32) old uint32
401 TEXT ·Or32(SB), NOSPLIT, $0-20
402 MOVD ptr+0(FP), R0
403 MOVW val+8(FP), R1
404 #ifndef GOARM64_LSE
405 MOVBU internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
406 CBZ R4, load_store_loop
407 #endif
408 LDORALW R1, (R0), R2
409 MOVD R2, ret+16(FP)
410 RET
411 #ifndef GOARM64_LSE
412 load_store_loop:
413 LDAXRW (R0), R2
414 ORR R1, R2, R3
415 STLXRW R3, (R0), R4
416 CBNZ R4, load_store_loop
417 MOVD R2, ret+16(FP)
418 RET
419 #endif
420
421 // func And32(addr *uint32, v uint32) old uint32
422 TEXT ·And32(SB), NOSPLIT, $0-20
423 MOVD ptr+0(FP), R0
424 MOVW val+8(FP), R1
425 #ifndef GOARM64_LSE
426 MOVBU internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
427 CBZ R4, load_store_loop
428 #endif
429 MVN R1, R2
430 LDCLRALW R2, (R0), R3
431 MOVD R3, ret+16(FP)
432 RET
433 #ifndef GOARM64_LSE
434 load_store_loop:
435 LDAXRW (R0), R2
436 AND R1, R2, R3
437 STLXRW R3, (R0), R4
438 CBNZ R4, load_store_loop
439 MOVD R2, ret+16(FP)
440 RET
441 #endif
442
443 // func Or64(addr *uint64, v uint64) old uint64
444 TEXT ·Or64(SB), NOSPLIT, $0-24
445 MOVD ptr+0(FP), R0
446 MOVD val+8(FP), R1
447 #ifndef GOARM64_LSE
448 MOVBU internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
449 CBZ R4, load_store_loop
450 #endif
451 LDORALD R1, (R0), R2
452 MOVD R2, ret+16(FP)
453 RET
454 #ifndef GOARM64_LSE
455 load_store_loop:
456 LDAXR (R0), R2
457 ORR R1, R2, R3
458 STLXR R3, (R0), R4
459 CBNZ R4, load_store_loop
460 MOVD R2, ret+16(FP)
461 RET
462 #endif
463
464 // func And64(addr *uint64, v uint64) old uint64
465 TEXT ·And64(SB), NOSPLIT, $0-24
466 MOVD ptr+0(FP), R0
467 MOVD val+8(FP), R1
468 #ifndef GOARM64_LSE
469 MOVBU internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
470 CBZ R4, load_store_loop
471 #endif
472 MVN R1, R2
473 LDCLRALD R2, (R0), R3
474 MOVD R3, ret+16(FP)
475 RET
476 #ifndef GOARM64_LSE
477 load_store_loop:
478 LDAXR (R0), R2
479 AND R1, R2, R3
480 STLXR R3, (R0), R4
481 CBNZ R4, load_store_loop
482 MOVD R2, ret+16(FP)
483 RET
484 #endif
485
486 // func Anduintptr(addr *uintptr, v uintptr) old uintptr
487 TEXT ·Anduintptr(SB), NOSPLIT, $0-24
488 B ·And64(SB)
489
490 // func Oruintptr(addr *uintptr, v uintptr) old uintptr
491 TEXT ·Oruintptr(SB), NOSPLIT, $0-24
492 B ·Or64(SB)
493
View as plain text