xref: /linux/arch/sparc/lib/bitops.S (revision f3a8b6645dc2e60d11f20c1c23afd964ff4e55ae)
1/* bitops.S: Sparc64 atomic bit operations.
2 *
3 * Copyright (C) 2000, 2007 David S. Miller (davem@davemloft.net)
4 */
5
6#include <linux/linkage.h>
7#include <asm/asi.h>
8#include <asm/backoff.h>
9#include <asm/export.h>
10
11	.text
12
13ENTRY(test_and_set_bit)	/* %o0=nr, %o1=addr */
14	BACKOFF_SETUP(%o3)
15	srlx	%o0, 6, %g1
16	mov	1, %o2
17	sllx	%g1, 3, %g3
18	and	%o0, 63, %g2
19	sllx	%o2, %g2, %o2
20	add	%o1, %g3, %o1
211:	ldx	[%o1], %g7
22	or	%g7, %o2, %g1
23	casx	[%o1], %g7, %g1
24	cmp	%g7, %g1
25	bne,pn	%xcc, BACKOFF_LABEL(2f, 1b)
26	 and	%g7, %o2, %g2
27	clr	%o0
28	movrne	%g2, 1, %o0
29	retl
30	 nop
312:	BACKOFF_SPIN(%o3, %o4, 1b)
32ENDPROC(test_and_set_bit)
33EXPORT_SYMBOL(test_and_set_bit)
34
35ENTRY(test_and_clear_bit) /* %o0=nr, %o1=addr */
36	BACKOFF_SETUP(%o3)
37	srlx	%o0, 6, %g1
38	mov	1, %o2
39	sllx	%g1, 3, %g3
40	and	%o0, 63, %g2
41	sllx	%o2, %g2, %o2
42	add	%o1, %g3, %o1
431:	ldx	[%o1], %g7
44	andn	%g7, %o2, %g1
45	casx	[%o1], %g7, %g1
46	cmp	%g7, %g1
47	bne,pn	%xcc, BACKOFF_LABEL(2f, 1b)
48	 and	%g7, %o2, %g2
49	clr	%o0
50	movrne	%g2, 1, %o0
51	retl
52	 nop
532:	BACKOFF_SPIN(%o3, %o4, 1b)
54ENDPROC(test_and_clear_bit)
55EXPORT_SYMBOL(test_and_clear_bit)
56
57ENTRY(test_and_change_bit) /* %o0=nr, %o1=addr */
58	BACKOFF_SETUP(%o3)
59	srlx	%o0, 6, %g1
60	mov	1, %o2
61	sllx	%g1, 3, %g3
62	and	%o0, 63, %g2
63	sllx	%o2, %g2, %o2
64	add	%o1, %g3, %o1
651:	ldx	[%o1], %g7
66	xor	%g7, %o2, %g1
67	casx	[%o1], %g7, %g1
68	cmp	%g7, %g1
69	bne,pn	%xcc, BACKOFF_LABEL(2f, 1b)
70	 and	%g7, %o2, %g2
71	clr	%o0
72	movrne	%g2, 1, %o0
73	retl
74	 nop
752:	BACKOFF_SPIN(%o3, %o4, 1b)
76ENDPROC(test_and_change_bit)
77EXPORT_SYMBOL(test_and_change_bit)
78
79ENTRY(set_bit) /* %o0=nr, %o1=addr */
80	BACKOFF_SETUP(%o3)
81	srlx	%o0, 6, %g1
82	mov	1, %o2
83	sllx	%g1, 3, %g3
84	and	%o0, 63, %g2
85	sllx	%o2, %g2, %o2
86	add	%o1, %g3, %o1
871:	ldx	[%o1], %g7
88	or	%g7, %o2, %g1
89	casx	[%o1], %g7, %g1
90	cmp	%g7, %g1
91	bne,pn	%xcc, BACKOFF_LABEL(2f, 1b)
92	 nop
93	retl
94	 nop
952:	BACKOFF_SPIN(%o3, %o4, 1b)
96ENDPROC(set_bit)
97EXPORT_SYMBOL(set_bit)
98
99ENTRY(clear_bit) /* %o0=nr, %o1=addr */
100	BACKOFF_SETUP(%o3)
101	srlx	%o0, 6, %g1
102	mov	1, %o2
103	sllx	%g1, 3, %g3
104	and	%o0, 63, %g2
105	sllx	%o2, %g2, %o2
106	add	%o1, %g3, %o1
1071:	ldx	[%o1], %g7
108	andn	%g7, %o2, %g1
109	casx	[%o1], %g7, %g1
110	cmp	%g7, %g1
111	bne,pn	%xcc, BACKOFF_LABEL(2f, 1b)
112	 nop
113	retl
114	 nop
1152:	BACKOFF_SPIN(%o3, %o4, 1b)
116ENDPROC(clear_bit)
117EXPORT_SYMBOL(clear_bit)
118
119ENTRY(change_bit) /* %o0=nr, %o1=addr */
120	BACKOFF_SETUP(%o3)
121	srlx	%o0, 6, %g1
122	mov	1, %o2
123	sllx	%g1, 3, %g3
124	and	%o0, 63, %g2
125	sllx	%o2, %g2, %o2
126	add	%o1, %g3, %o1
1271:	ldx	[%o1], %g7
128	xor	%g7, %o2, %g1
129	casx	[%o1], %g7, %g1
130	cmp	%g7, %g1
131	bne,pn	%xcc, BACKOFF_LABEL(2f, 1b)
132	 nop
133	retl
134	 nop
1352:	BACKOFF_SPIN(%o3, %o4, 1b)
136ENDPROC(change_bit)
137EXPORT_SYMBOL(change_bit)
138