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