1/* $Id: bitops.S,v 1.1.1.1 2007-08-03 18:52:18 $
2 * bitops.S: Sparc64 atomic bit operations.
3 *
4 * Copyright (C) 2000 David S. Miller (davem@redhat.com)
5 */
6
7#include <asm/asi.h>
8
9	.text
10
11	/* On SMP we need to use memory barriers to ensure
12	 * correct memory operation ordering, nop these out
13	 * for uniprocessor.
14	 */
15
16#ifdef CONFIG_SMP
17#define BITOP_PRE_BARRIER	membar #StoreLoad | #LoadLoad
18#define BITOP_POST_BARRIER	\
19	ba,pt	%xcc, 80b;	\
20	membar #StoreLoad | #StoreStore
21
2280:	retl
23	 nop
24#else
25#define BITOP_PRE_BARRIER
26#define BITOP_POST_BARRIER
27#endif
28
29	.globl	test_and_set_bit
30	.type	test_and_set_bit,#function
31test_and_set_bit:	/* %o0=nr, %o1=addr */
32	BITOP_PRE_BARRIER
33	srlx	%o0, 6, %g1
34	mov	1, %o2
35	sllx	%g1, 3, %g3
36	and	%o0, 63, %g2
37	sllx	%o2, %g2, %o2
38	add	%o1, %g3, %o1
391:	ldx	[%o1], %g7
40	or	%g7, %o2, %g1
41	casx	[%o1], %g7, %g1
42	cmp	%g7, %g1
43	bne,pn	%xcc, 1b
44	 and	%g7, %o2, %g2
45	clr	%o0
46	movrne	%g2, 1, %o0
47	BITOP_POST_BARRIER
48	retl
49	 nop
50	.size	test_and_set_bit, .-test_and_set_bit
51
52	.globl	test_and_clear_bit
53	.type	test_and_clear_bit,#function
54test_and_clear_bit:	/* %o0=nr, %o1=addr */
55	BITOP_PRE_BARRIER
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	andn	%g7, %o2, %g1
64	casx	[%o1], %g7, %g1
65	cmp	%g7, %g1
66	bne,pn	%xcc, 1b
67	 and	%g7, %o2, %g2
68	clr	%o0
69	movrne	%g2, 1, %o0
70	BITOP_POST_BARRIER
71	retl
72	 nop
73	.size	test_and_clear_bit, .-test_and_clear_bit
74
75	.globl	test_and_change_bit
76	.type	test_and_change_bit,#function
77test_and_change_bit:	/* %o0=nr, %o1=addr */
78	BITOP_PRE_BARRIER
79	srlx	%o0, 6, %g1
80	mov	1, %o2
81	sllx	%g1, 3, %g3
82	and	%o0, 63, %g2
83	sllx	%o2, %g2, %o2
84	add	%o1, %g3, %o1
851:	ldx	[%o1], %g7
86	xor	%g7, %o2, %g1
87	casx	[%o1], %g7, %g1
88	cmp	%g7, %g1
89	bne,pn	%xcc, 1b
90	 and	%g7, %o2, %g2
91	clr	%o0
92	movrne	%g2, 1, %o0
93	BITOP_POST_BARRIER
94	retl
95	 nop
96	.size	test_and_change_bit, .-test_and_change_bit
97
98	.globl	set_bit
99	.type	set_bit,#function
100set_bit:		/* %o0=nr, %o1=addr */
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	or	%g7, %o2, %g1
109	casx	[%o1], %g7, %g1
110	cmp	%g7, %g1
111	bne,pn	%xcc, 1b
112	 nop
113	retl
114	 nop
115	.size	set_bit, .-set_bit
116
117	.globl	clear_bit
118	.type	clear_bit,#function
119clear_bit:		/* %o0=nr, %o1=addr */
120	srlx	%o0, 6, %g1
121	mov	1, %o2
122	sllx	%g1, 3, %g3
123	and	%o0, 63, %g2
124	sllx	%o2, %g2, %o2
125	add	%o1, %g3, %o1
1261:	ldx	[%o1], %g7
127	andn	%g7, %o2, %g1
128	casx	[%o1], %g7, %g1
129	cmp	%g7, %g1
130	bne,pn	%xcc, 1b
131	 nop
132	retl
133	 nop
134	.size	clear_bit, .-clear_bit
135
136	.globl	change_bit
137	.type	change_bit,#function
138change_bit:		/* %o0=nr, %o1=addr */
139	srlx	%o0, 6, %g1
140	mov	1, %o2
141	sllx	%g1, 3, %g3
142	and	%o0, 63, %g2
143	sllx	%o2, %g2, %o2
144	add	%o1, %g3, %o1
1451:	ldx	[%o1], %g7
146	xor	%g7, %o2, %g1
147	casx	[%o1], %g7, %g1
148	cmp	%g7, %g1
149	bne,pn	%xcc, 1b
150	 nop
151	retl
152	 nop
153	.size	change_bit, .-change_bit
154