1/* SPDX-License-Identifier: GPL-2.0 */
2/* bitops.S: Sparc64 atomic bit operations.
3 *
4 * Copyright (C) 2000, 2007 David S. Miller (davem@davemloft.net)
5 */
6
7#include <linux/export.h>
8#include <linux/linkage.h>
9#include <asm/asi.h>
10#include <asm/backoff.h>
11
12	.text
13
14ENTRY(test_and_set_bit)	/* %o0=nr, %o1=addr */
15	BACKOFF_SETUP(%o3)
16	srlx	%o0, 6, %g1
17	mov	1, %o2
18	sllx	%g1, 3, %g3
19	and	%o0, 63, %g2
20	sllx	%o2, %g2, %o2
21	add	%o1, %g3, %o1
221:	ldx	[%o1], %g7
23	or	%g7, %o2, %g1
24	casx	[%o1], %g7, %g1
25	cmp	%g7, %g1
26	bne,pn	%xcc, BACKOFF_LABEL(2f, 1b)
27	 and	%g7, %o2, %g2
28	clr	%o0
29	movrne	%g2, 1, %o0
30	retl
31	 nop
322:	BACKOFF_SPIN(%o3, %o4, 1b)
33ENDPROC(test_and_set_bit)
34EXPORT_SYMBOL(test_and_set_bit)
35
36ENTRY(test_and_clear_bit) /* %o0=nr, %o1=addr */
37	BACKOFF_SETUP(%o3)
38	srlx	%o0, 6, %g1
39	mov	1, %o2
40	sllx	%g1, 3, %g3
41	and	%o0, 63, %g2
42	sllx	%o2, %g2, %o2
43	add	%o1, %g3, %o1
441:	ldx	[%o1], %g7
45	andn	%g7, %o2, %g1
46	casx	[%o1], %g7, %g1
47	cmp	%g7, %g1
48	bne,pn	%xcc, BACKOFF_LABEL(2f, 1b)
49	 and	%g7, %o2, %g2
50	clr	%o0
51	movrne	%g2, 1, %o0
52	retl
53	 nop
542:	BACKOFF_SPIN(%o3, %o4, 1b)
55ENDPROC(test_and_clear_bit)
56EXPORT_SYMBOL(test_and_clear_bit)
57
58ENTRY(test_and_change_bit) /* %o0=nr, %o1=addr */
59	BACKOFF_SETUP(%o3)
60	srlx	%o0, 6, %g1
61	mov	1, %o2
62	sllx	%g1, 3, %g3
63	and	%o0, 63, %g2
64	sllx	%o2, %g2, %o2
65	add	%o1, %g3, %o1
661:	ldx	[%o1], %g7
67	xor	%g7, %o2, %g1
68	casx	[%o1], %g7, %g1
69	cmp	%g7, %g1
70	bne,pn	%xcc, BACKOFF_LABEL(2f, 1b)
71	 and	%g7, %o2, %g2
72	clr	%o0
73	movrne	%g2, 1, %o0
74	retl
75	 nop
762:	BACKOFF_SPIN(%o3, %o4, 1b)
77ENDPROC(test_and_change_bit)
78EXPORT_SYMBOL(test_and_change_bit)
79
80ENTRY(set_bit) /* %o0=nr, %o1=addr */
81	BACKOFF_SETUP(%o3)
82	srlx	%o0, 6, %g1
83	mov	1, %o2
84	sllx	%g1, 3, %g3
85	and	%o0, 63, %g2
86	sllx	%o2, %g2, %o2
87	add	%o1, %g3, %o1
881:	ldx	[%o1], %g7
89	or	%g7, %o2, %g1
90	casx	[%o1], %g7, %g1
91	cmp	%g7, %g1
92	bne,pn	%xcc, BACKOFF_LABEL(2f, 1b)
93	 nop
94	retl
95	 nop
962:	BACKOFF_SPIN(%o3, %o4, 1b)
97ENDPROC(set_bit)
98EXPORT_SYMBOL(set_bit)
99
100ENTRY(clear_bit) /* %o0=nr, %o1=addr */
101	BACKOFF_SETUP(%o3)
102	srlx	%o0, 6, %g1
103	mov	1, %o2
104	sllx	%g1, 3, %g3
105	and	%o0, 63, %g2
106	sllx	%o2, %g2, %o2
107	add	%o1, %g3, %o1
1081:	ldx	[%o1], %g7
109	andn	%g7, %o2, %g1
110	casx	[%o1], %g7, %g1
111	cmp	%g7, %g1
112	bne,pn	%xcc, BACKOFF_LABEL(2f, 1b)
113	 nop
114	retl
115	 nop
1162:	BACKOFF_SPIN(%o3, %o4, 1b)
117ENDPROC(clear_bit)
118EXPORT_SYMBOL(clear_bit)
119
120ENTRY(change_bit) /* %o0=nr, %o1=addr */
121	BACKOFF_SETUP(%o3)
122	srlx	%o0, 6, %g1
123	mov	1, %o2
124	sllx	%g1, 3, %g3
125	and	%o0, 63, %g2
126	sllx	%o2, %g2, %o2
127	add	%o1, %g3, %o1
1281:	ldx	[%o1], %g7
129	xor	%g7, %o2, %g1
130	casx	[%o1], %g7, %g1
131	cmp	%g7, %g1
132	bne,pn	%xcc, BACKOFF_LABEL(2f, 1b)
133	 nop
134	retl
135	 nop
1362:	BACKOFF_SPIN(%o3, %o4, 1b)
137ENDPROC(change_bit)
138EXPORT_SYMBOL(change_bit)
139