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// +build ppc64 ppc64le
6
7#include "textflag.h"
8
9// bool cas(uint32 *ptr, uint32 old, uint32 new)
10// Atomically:
11//	if(*val == old){
12//		*val = new;
13//		return 1;
14//	} else
15//		return 0;
16TEXT runtimeinternalatomic·Cas(SB), NOSPLIT, $0-17
17	MOVD	ptr+0(FP), R3
18	MOVWZ	old+8(FP), R4
19	MOVWZ	new+12(FP), R5
20	LWSYNC
21cas_again:
22	LWAR	(R3), R6
23	CMPW	R6, R4
24	BNE	cas_fail
25	STWCCC	R5, (R3)
26	BNE	cas_again
27	MOVD	$1, R3
28	LWSYNC
29	MOVB	R3, ret+16(FP)
30	RET
31cas_fail:
32	MOVB	R0, ret+16(FP)
33	RET
34
35// bool	runtime∕internal∕atomic·Cas64(uint64 *ptr, uint64 old, uint64 new)
36// Atomically:
37//	if(*val == *old){
38//		*val = new;
39//		return 1;
40//	} else {
41//		return 0;
42//	}
43TEXT runtimeinternalatomic·Cas64(SB), NOSPLIT, $0-25
44	MOVD	ptr+0(FP), R3
45	MOVD	old+8(FP), R4
46	MOVD	new+16(FP), R5
47	LWSYNC
48cas64_again:
49	LDAR	(R3), R6
50	CMP	R6, R4
51	BNE	cas64_fail
52	STDCCC	R5, (R3)
53	BNE	cas64_again
54	MOVD	$1, R3
55	LWSYNC
56	MOVB	R3, ret+24(FP)
57	RET
58cas64_fail:
59	MOVB	R0, ret+24(FP)
60	RET
61
62TEXT runtimeinternalatomic·CasRel(SB), NOSPLIT, $0-17
63	MOVD    ptr+0(FP), R3
64	MOVWZ   old+8(FP), R4
65	MOVWZ   new+12(FP), R5
66	LWSYNC
67cas_again:
68	LWAR    (R3), $0, R6        // 0 = Mutex release hint
69	CMPW    R6, R4
70	BNE     cas_fail
71	STWCCC  R5, (R3)
72	BNE     cas_again
73	MOVD    $1, R3
74	MOVB    R3, ret+16(FP)
75	RET
76cas_fail:
77	MOVB    R0, ret+16(FP)
78	RET
79
80TEXT runtimeinternalatomic·Casuintptr(SB), NOSPLIT, $0-25
81	BR	runtimeinternalatomic·Cas64(SB)
82
83TEXT runtimeinternalatomic·Loaduintptr(SB),  NOSPLIT|NOFRAME, $0-16
84	BR	runtimeinternalatomic·Load64(SB)
85
86TEXT runtimeinternalatomic·Loaduint(SB), NOSPLIT|NOFRAME, $0-16
87	BR	runtimeinternalatomic·Load64(SB)
88
89TEXT runtimeinternalatomic·Storeuintptr(SB), NOSPLIT, $0-16
90	BR	runtimeinternalatomic·Store64(SB)
91
92TEXT runtimeinternalatomic·Xadduintptr(SB), NOSPLIT, $0-24
93	BR	runtimeinternalatomic·Xadd64(SB)
94
95TEXT runtimeinternalatomic·Loadint64(SB), NOSPLIT, $0-16
96	BR	runtimeinternalatomic·Load64(SB)
97
98TEXT runtimeinternalatomic·Xaddint64(SB), NOSPLIT, $0-24
99	BR	runtimeinternalatomic·Xadd64(SB)
100
101// bool casp(void **val, void *old, void *new)
102// Atomically:
103//	if(*val == old){
104//		*val = new;
105//		return 1;
106//	} else
107//		return 0;
108TEXT runtimeinternalatomic·Casp1(SB), NOSPLIT, $0-25
109	BR runtimeinternalatomic·Cas64(SB)
110
111// uint32 xadd(uint32 volatile *ptr, int32 delta)
112// Atomically:
113//	*val += delta;
114//	return *val;
115TEXT runtimeinternalatomic·Xadd(SB), NOSPLIT, $0-20
116	MOVD	ptr+0(FP), R4
117	MOVW	delta+8(FP), R5
118	LWSYNC
119	LWAR	(R4), R3
120	ADD	R5, R3
121	STWCCC	R3, (R4)
122	BNE	-3(PC)
123	MOVW	R3, ret+16(FP)
124	RET
125
126TEXT runtimeinternalatomic·Xadd64(SB), NOSPLIT, $0-24
127	MOVD	ptr+0(FP), R4
128	MOVD	delta+8(FP), R5
129	LWSYNC
130	LDAR	(R4), R3
131	ADD	R5, R3
132	STDCCC	R3, (R4)
133	BNE	-3(PC)
134	MOVD	R3, ret+16(FP)
135	RET
136
137TEXT runtimeinternalatomic·Xchg(SB), NOSPLIT, $0-20
138	MOVD	ptr+0(FP), R4
139	MOVW	new+8(FP), R5
140	LWSYNC
141	LWAR	(R4), R3
142	STWCCC	R5, (R4)
143	BNE	-2(PC)
144	ISYNC
145	MOVW	R3, ret+16(FP)
146	RET
147
148TEXT runtimeinternalatomic·Xchg64(SB), NOSPLIT, $0-24
149	MOVD	ptr+0(FP), R4
150	MOVD	new+8(FP), R5
151	LWSYNC
152	LDAR	(R4), R3
153	STDCCC	R5, (R4)
154	BNE	-2(PC)
155	ISYNC
156	MOVD	R3, ret+16(FP)
157	RET
158
159TEXT runtimeinternalatomic·Xchguintptr(SB), NOSPLIT, $0-24
160	BR	runtimeinternalatomic·Xchg64(SB)
161
162
163TEXT runtimeinternalatomic·StorepNoWB(SB), NOSPLIT, $0-16
164	BR	runtimeinternalatomic·Store64(SB)
165
166TEXT runtimeinternalatomic·Store(SB), NOSPLIT, $0-12
167	MOVD	ptr+0(FP), R3
168	MOVW	val+8(FP), R4
169	SYNC
170	MOVW	R4, 0(R3)
171	RET
172
173TEXT runtimeinternalatomic·Store8(SB), NOSPLIT, $0-9
174	MOVD	ptr+0(FP), R3
175	MOVB	val+8(FP), R4
176	SYNC
177	MOVB	R4, 0(R3)
178	RET
179
180TEXT runtimeinternalatomic·Store64(SB), NOSPLIT, $0-16
181	MOVD	ptr+0(FP), R3
182	MOVD	val+8(FP), R4
183	SYNC
184	MOVD	R4, 0(R3)
185	RET
186
187TEXT runtimeinternalatomic·StoreRel(SB), NOSPLIT, $0-12
188	MOVD	ptr+0(FP), R3
189	MOVW	val+8(FP), R4
190	LWSYNC
191	MOVW	R4, 0(R3)
192	RET
193
194// void runtime∕internal∕atomic·Or8(byte volatile*, byte);
195TEXT runtimeinternalatomic·Or8(SB), NOSPLIT, $0-9
196	MOVD	ptr+0(FP), R3
197	MOVBZ	val+8(FP), R4
198	LWSYNC
199again:
200	LBAR	(R3), R6
201	OR	R4, R6
202	STBCCC	R6, (R3)
203	BNE	again
204	RET
205
206// void runtime∕internal∕atomic·And8(byte volatile*, byte);
207TEXT runtimeinternalatomic·And8(SB), NOSPLIT, $0-9
208	MOVD	ptr+0(FP), R3
209	MOVBZ	val+8(FP), R4
210	LWSYNC
211again:
212	LBAR	(R3),R6
213	AND	R4,R6
214	STBCCC	R6,(R3)
215	BNE	again
216	RET
217