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 #include "textflag.h"
6
7 // func Store(ptr *uint32, val uint32)
8 TEXT ·Store(SB), NOSPLIT, $0
9 MOVD ptr+0(FP), R2
10 MOVWZ val+8(FP), R3
11 MOVW R3, 0(R2)
12 SYNC
13 RET
14
15 // func Store8(ptr *uint8, val uint8)
16 TEXT ·Store8(SB), NOSPLIT, $0
17 MOVD ptr+0(FP), R2
18 MOVB val+8(FP), R3
19 MOVB R3, 0(R2)
20 SYNC
21 RET
22
23 // func Store64(ptr *uint64, val uint64)
24 TEXT ·Store64(SB), NOSPLIT, $0
25 MOVD ptr+0(FP), R2
26 MOVD val+8(FP), R3
27 MOVD R3, 0(R2)
28 SYNC
29 RET
30
31 // func StorepNoWB(ptr unsafe.Pointer, val unsafe.Pointer)
32 TEXT ·StorepNoWB(SB), NOSPLIT, $0
33 MOVD ptr+0(FP), R2
34 MOVD val+8(FP), R3
35 MOVD R3, 0(R2)
36 SYNC
37 RET
38
39 // func Cas(ptr *uint32, old, new uint32) bool
40 // Atomically:
41 // if *ptr == old {
42 // *val = new
43 // return 1
44 // } else {
45 // return 0
46 // }
47 TEXT ·Cas(SB), NOSPLIT, $0-17
48 MOVD ptr+0(FP), R3
49 MOVWZ old+8(FP), R4
50 MOVWZ new+12(FP), R5
51 CS R4, R5, 0(R3) // if (R4 == 0(R3)) then 0(R3)= R5
52 BNE cas_fail
53 MOVB $1, ret+16(FP)
54 RET
55 cas_fail:
56 MOVB $0, ret+16(FP)
57 RET
58
59 // func Cas64(ptr *uint64, old, new uint64) bool
60 // Atomically:
61 // if *ptr == old {
62 // *ptr = new
63 // return 1
64 // } else {
65 // return 0
66 // }
67 TEXT ·Cas64(SB), NOSPLIT, $0-25
68 MOVD ptr+0(FP), R3
69 MOVD old+8(FP), R4
70 MOVD new+16(FP), R5
71 CSG R4, R5, 0(R3) // if (R4 == 0(R3)) then 0(R3)= R5
72 BNE cas64_fail
73 MOVB $1, ret+24(FP)
74 RET
75 cas64_fail:
76 MOVB $0, ret+24(FP)
77 RET
78
79 // func Casint32(ptr *int32, old, new int32) bool
80 TEXT ·Casint32(SB), NOSPLIT, $0-17
81 BR ·Cas(SB)
82
83 // func Casint64(ptr *int64, old, new int64) bool
84 TEXT ·Casint64(SB), NOSPLIT, $0-25
85 BR ·Cas64(SB)
86
87 // func Casuintptr(ptr *uintptr, old, new uintptr) bool
88 TEXT ·Casuintptr(SB), NOSPLIT, $0-25
89 BR ·Cas64(SB)
90
91 // func CasRel(ptr *uint32, old, new uint32) bool
92 TEXT ·CasRel(SB), NOSPLIT, $0-17
93 BR ·Cas(SB)
94
95 // func Loaduintptr(ptr *uintptr) uintptr
96 TEXT ·Loaduintptr(SB), NOSPLIT, $0-16
97 BR ·Load64(SB)
98
99 // func Loaduint(ptr *uint) uint
100 TEXT ·Loaduint(SB), NOSPLIT, $0-16
101 BR ·Load64(SB)
102
103 // func Storeint32(ptr *int32, new int32)
104 TEXT ·Storeint32(SB), NOSPLIT, $0-12
105 BR ·Store(SB)
106
107 // func Storeint64(ptr *int64, new int64)
108 TEXT ·Storeint64(SB), NOSPLIT, $0-16
109 BR ·Store64(SB)
110
111 // func Storeuintptr(ptr *uintptr, new uintptr)
112 TEXT ·Storeuintptr(SB), NOSPLIT, $0-16
113 BR ·Store64(SB)
114
115 // func Loadint32(ptr *int32) int32
116 TEXT ·Loadint32(SB), NOSPLIT, $0-12
117 BR ·Load(SB)
118
119 // func Loadint64(ptr *int64) int64
120 TEXT ·Loadint64(SB), NOSPLIT, $0-16
121 BR ·Load64(SB)
122
123 // func Xadduintptr(ptr *uintptr, delta uintptr) uintptr
124 TEXT ·Xadduintptr(SB), NOSPLIT, $0-24
125 BR ·Xadd64(SB)
126
127 // func Xaddint32(ptr *int32, delta int32) int32
128 TEXT ·Xaddint32(SB), NOSPLIT, $0-20
129 BR ·Xadd(SB)
130
131 // func Xaddint64(ptr *int64, delta int64) int64
132 TEXT ·Xaddint64(SB), NOSPLIT, $0-24
133 BR ·Xadd64(SB)
134
135 // func Casp1(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool
136 // Atomically:
137 // if *ptr == old {
138 // *ptr = new
139 // return 1
140 // } else {
141 // return 0
142 // }
143 TEXT ·Casp1(SB), NOSPLIT, $0-25
144 BR ·Cas64(SB)
145
146 // func Xadd(ptr *uint32, delta int32) uint32
147 // Atomically:
148 // *ptr += delta
149 // return *ptr
150 TEXT ·Xadd(SB), NOSPLIT, $0-20
151 MOVD ptr+0(FP), R4
152 MOVW delta+8(FP), R5
153 MOVW (R4), R3
154 repeat:
155 ADD R5, R3, R6
156 CS R3, R6, (R4) // if R3==(R4) then (R4)=R6 else R3=(R4)
157 BNE repeat
158 MOVW R6, ret+16(FP)
159 RET
160
161 // func Xadd64(ptr *uint64, delta int64) uint64
162 TEXT ·Xadd64(SB), NOSPLIT, $0-24
163 MOVD ptr+0(FP), R4
164 MOVD delta+8(FP), R5
165 MOVD (R4), R3
166 repeat:
167 ADD R5, R3, R6
168 CSG R3, R6, (R4) // if R3==(R4) then (R4)=R6 else R3=(R4)
169 BNE repeat
170 MOVD R6, ret+16(FP)
171 RET
172
173 // func Xchg(ptr *uint32, new uint32) uint32
174 TEXT ·Xchg(SB), NOSPLIT, $0-20
175 MOVD ptr+0(FP), R4
176 MOVW new+8(FP), R3
177 MOVW (R4), R6
178 repeat:
179 CS R6, R3, (R4) // if R6==(R4) then (R4)=R3 else R6=(R4)
180 BNE repeat
181 MOVW R6, ret+16(FP)
182 RET
183
184 // func Xchg64(ptr *uint64, new uint64) uint64
185 TEXT ·Xchg64(SB), NOSPLIT, $0-24
186 MOVD ptr+0(FP), R4
187 MOVD new+8(FP), R3
188 MOVD (R4), R6
189 repeat:
190 CSG R6, R3, (R4) // if R6==(R4) then (R4)=R3 else R6=(R4)
191 BNE repeat
192 MOVD R6, ret+16(FP)
193 RET
194
195 // func Xchgint32(ptr *int32, new int32) int32
196 TEXT ·Xchgint32(SB), NOSPLIT, $0-20
197 BR ·Xchg(SB)
198
199 // func Xchgint64(ptr *int64, new int64) int64
200 TEXT ·Xchgint64(SB), NOSPLIT, $0-24
201 BR ·Xchg64(SB)
202
203 // func Xchguintptr(ptr *uintptr, new uintptr) uintptr
204 TEXT ·Xchguintptr(SB), NOSPLIT, $0-24
205 BR ·Xchg64(SB)
206
207 // func Or8(addr *uint8, v uint8)
208 TEXT ·Or8(SB), NOSPLIT, $0-9
209 MOVD ptr+0(FP), R3
210 MOVBZ val+8(FP), R4
211 // We don't have atomic operations that work on individual bytes so we
212 // need to align addr down to a word boundary and create a mask
213 // containing v to OR with the entire word atomically.
214 MOVD $(3<<3), R5
215 RXSBG $59, $60, $3, R3, R5 // R5 = 24 - ((addr % 4) * 8) = ((addr & 3) << 3) ^ (3 << 3)
216 ANDW $~3, R3 // R3 = floor(addr, 4) = addr &^ 3
217 SLW R5, R4 // R4 = uint32(v) << R5
218 LAO R4, R6, 0(R3) // R6 = *R3; *R3 |= R4; (atomic)
219 RET
220
221 // func And8(addr *uint8, v uint8)
222 TEXT ·And8(SB), NOSPLIT, $0-9
223 MOVD ptr+0(FP), R3
224 MOVBZ val+8(FP), R4
225 // We don't have atomic operations that work on individual bytes so we
226 // need to align addr down to a word boundary and create a mask
227 // containing v to AND with the entire word atomically.
228 ORW $~0xff, R4 // R4 = uint32(v) | 0xffffff00
229 MOVD $(3<<3), R5
230 RXSBG $59, $60, $3, R3, R5 // R5 = 24 - ((addr % 4) * 8) = ((addr & 3) << 3) ^ (3 << 3)
231 ANDW $~3, R3 // R3 = floor(addr, 4) = addr &^ 3
232 RLL R5, R4, R4 // R4 = rotl(R4, R5)
233 LAN R4, R6, 0(R3) // R6 = *R3; *R3 &= R4; (atomic)
234 RET
235
236 // func Or(addr *uint32, v uint32)
237 TEXT ·Or(SB), NOSPLIT, $0-12
238 MOVD ptr+0(FP), R3
239 MOVW val+8(FP), R4
240 LAO R4, R6, 0(R3) // R6 = *R3; *R3 |= R4; (atomic)
241 RET
242
243 // func And(addr *uint32, v uint32)
244 TEXT ·And(SB), NOSPLIT, $0-12
245 MOVD ptr+0(FP), R3
246 MOVW val+8(FP), R4
247 LAN R4, R6, 0(R3) // R6 = *R3; *R3 &= R4; (atomic)
248 RET
249
250 // func Or32(addr *uint32, v uint32) old uint32
251 TEXT ·Or32(SB), NOSPLIT, $0-20
252 MOVD ptr+0(FP), R4
253 MOVW val+8(FP), R5
254 MOVW (R4), R3
255 repeat:
256 OR R5, R3, R6
257 CS R3, R6, (R4) // if R3==(R4) then (R4)=R6 else R3=(R4)
258 BNE repeat
259 MOVW R3, ret+16(FP)
260 RET
261
262 // func And32(addr *uint32, v uint32) old uint32
263 TEXT ·And32(SB), NOSPLIT, $0-20
264 MOVD ptr+0(FP), R4
265 MOVW val+8(FP), R5
266 MOVW (R4), R3
267 repeat:
268 AND R5, R3, R6
269 CS R3, R6, (R4) // if R3==(R4) then (R4)=R6 else R3=(R4)
270 BNE repeat
271 MOVW R3, ret+16(FP)
272 RET
273
274 // func Or64(addr *uint64, v uint64) old uint64
275 TEXT ·Or64(SB), NOSPLIT, $0-24
276 MOVD ptr+0(FP), R4
277 MOVD val+8(FP), R5
278 MOVD (R4), R3
279 repeat:
280 OR R5, R3, R6
281 CSG R3, R6, (R4) // if R3==(R4) then (R4)=R6 else R3=(R4)
282 BNE repeat
283 MOVD R3, ret+16(FP)
284 RET
285
286 // func And64(addr *uint64, v uint64) old uint64
287 TEXT ·And64(SB), NOSPLIT, $0-24
288 MOVD ptr+0(FP), R4
289 MOVD val+8(FP), R5
290 MOVD (R4), R3
291 repeat:
292 AND R5, R3, R6
293 CSG R3, R6, (R4) // if R3==(R4) then (R4)=R6 else R3=(R4)
294 BNE repeat
295 MOVD R3, ret+16(FP)
296 RET
297
298 // func Anduintptr(addr *uintptr, v uintptr) old uintptr
299 TEXT ·Anduintptr(SB), NOSPLIT, $0-24
300 BR ·And64(SB)
301
302 // func Oruintptr(addr *uintptr, v uintptr) old uintptr
303 TEXT ·Oruintptr(SB), NOSPLIT, $0-24
304 BR ·Or64(SB)
305
View as plain text