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
10	.text
11
12ENTRY(test_and_set_bit)	/* %o0=nr, %o1=addr */
13	BACKOFF_SETUP(%o3)
14	srlx	%o0, 6, %g1
15	mov	1, %o2
16	sllx	%g1, 3, %g3
17	and	%o0, 63, %g2
18	sllx	%o2, %g2, %o2
19	add	%o1, %g3, %o1
201:	ldx	[%o1], %g7
21	or	%g7, %o2, %g1
22	casx	[%o1], %g7, %g1
23	cmp	%g7, %g1
24	bne,pn	%xcc, BACKOFF_LABEL(2f, 1b)
25	 and	%g7, %o2, %g2
26	clr	%o0
27	movrne	%g2, 1, %o0
28	retl
29	 nop
302:	BACKOFF_SPIN(%o3, %o4, 1b)
31ENDPROC(test_and_set_bit)
32
33ENTRY(test_and_clear_bit) /* %o0=nr, %o1=addr */
34	BACKOFF_SETUP(%o3)
35	srlx	%o0, 6, %g1
36	mov	1, %o2
37	sllx	%g1, 3, %g3
38	and	%o0, 63, %g2
39	sllx	%o2, %g2, %o2
40	add	%o1, %g3, %o1
411:	ldx	[%o1], %g7
42	andn	%g7, %o2, %g1
43	casx	[%o1], %g7, %g1
44	cmp	%g7, %g1
45	bne,pn	%xcc, BACKOFF_LABEL(2f, 1b)
46	 and	%g7, %o2, %g2
47	clr	%o0
48	movrne	%g2, 1, %o0
49	retl
50	 nop
512:	BACKOFF_SPIN(%o3, %o4, 1b)
52ENDPROC(test_and_clear_bit)
53
54ENTRY(test_and_change_bit) /* %o0=nr, %o1=addr */
55	BACKOFF_SETUP(%o3)
56	srlx	%o0, 6, %g1
57	mov	1, %o2
58	sllx	%g1, 3, %g3
59	and	%o0, 63, %g2
60	sllx	%o2, %g2, %o2
61	add	%o1, %g3, %o1
621:	ldx	[%o1], %g7
63	xor	%g7, %o2, %g1
64	casx	[%o1], %g7, %g1
65	cmp	%g7, %g1
66	bne,pn	%xcc, BACKOFF_LABEL(2f, 1b)
67	 and	%g7, %o2, %g2
68	clr	%o0
69	movrne	%g2, 1, %o0
70	retl
71	 nop
722:	BACKOFF_SPIN(%o3, %o4, 1b)
73ENDPROC(test_and_change_bit)
74
75ENTRY(set_bit) /* %o0=nr, %o1=addr */
76	BACKOFF_SETUP(%o3)
77	srlx	%o0, 6, %g1
78	mov	1, %o2
79	sllx	%g1, 3, %g3
80	and	%o0, 63, %g2
81	sllx	%o2, %g2, %o2
82	add	%o1, %g3, %o1
831:	ldx	[%o1], %g7
84	or	%g7, %o2, %g1
85	casx	[%o1], %g7, %g1
86	cmp	%g7, %g1
87	bne,pn	%xcc, BACKOFF_LABEL(2f, 1b)
88	 nop
89	retl
90	 nop
912:	BACKOFF_SPIN(%o3, %o4, 1b)
92ENDPROC(set_bit)
93
94ENTRY(clear_bit) /* %o0=nr, %o1=addr */
95	BACKOFF_SETUP(%o3)
96	srlx	%o0, 6, %g1
97	mov	1, %o2
98	sllx	%g1, 3, %g3
99	and	%o0, 63, %g2
100	sllx	%o2, %g2, %o2
101	add	%o1, %g3, %o1
1021:	ldx	[%o1], %g7
103	andn	%g7, %o2, %g1
104	casx	[%o1], %g7, %g1
105	cmp	%g7, %g1
106	bne,pn	%xcc, BACKOFF_LABEL(2f, 1b)
107	 nop
108	retl
109	 nop
1102:	BACKOFF_SPIN(%o3, %o4, 1b)
111ENDPROC(clear_bit)
112
113ENTRY(change_bit) /* %o0=nr, %o1=addr */
114	BACKOFF_SETUP(%o3)
115	srlx	%o0, 6, %g1
116	mov	1, %o2
117	sllx	%g1, 3, %g3
118	and	%o0, 63, %g2
119	sllx	%o2, %g2, %o2
120	add	%o1, %g3, %o1
1211:	ldx	[%o1], %g7
122	xor	%g7, %o2, %g1
123	casx	[%o1], %g7, %g1
124	cmp	%g7, %g1
125	bne,pn	%xcc, BACKOFF_LABEL(2f, 1b)
126	 nop
127	retl
128	 nop
1292:	BACKOFF_SPIN(%o3, %o4, 1b)
130ENDPROC(change_bit)
131