blob: 892431a821311f639e9a18aec4a70c702bd4c726 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/* $Id: bitops.S,v 1.3 2001/11/18 00:12:56 davem Exp $
2 * bitops.S: Sparc64 atomic bit operations.
3 *
4 * Copyright (C) 2000 David S. Miller (davem@redhat.com)
5 */
6
Linus Torvalds1da177e2005-04-16 15:20:36 -07007#include <asm/asi.h>
8
David S. Millerb445e262005-06-27 15:42:04 -07009 .text
10
Linus Torvalds1da177e2005-04-16 15:20:36 -070011 /* On SMP we need to use memory barriers to ensure
12 * correct memory operation ordering, nop these out
13 * for uniprocessor.
14 */
David S. Millerb445e262005-06-27 15:42:04 -070015
Linus Torvalds1da177e2005-04-16 15:20:36 -070016#ifdef CONFIG_SMP
17#define BITOP_PRE_BARRIER membar #StoreLoad | #LoadLoad
David S. Millerb445e262005-06-27 15:42:04 -070018#define BITOP_POST_BARRIER \
19 ba,pt %xcc, 80b; \
20 membar #StoreLoad | #StoreStore
Linus Torvalds1da177e2005-04-16 15:20:36 -070021
David S. Millerb445e262005-06-27 15:42:04 -07002280: retl
23 nop
24#else
25#define BITOP_PRE_BARRIER
26#define BITOP_POST_BARRIER
27#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -070028
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
Linus Torvalds1da177e2005-04-16 15:20:36 -070045 clr %o0
David S. Millerb445e262005-06-27 15:42:04 -070046 movrne %g2, 1, %o0
47 BITOP_POST_BARRIER
Linus Torvalds1da177e2005-04-16 15:20:36 -070048 retl
David S. Millerb445e262005-06-27 15:42:04 -070049 nop
Linus Torvalds1da177e2005-04-16 15:20:36 -070050 .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
Linus Torvalds1da177e2005-04-16 15:20:36 -070068 clr %o0
David S. Millerb445e262005-06-27 15:42:04 -070069 movrne %g2, 1, %o0
70 BITOP_POST_BARRIER
Linus Torvalds1da177e2005-04-16 15:20:36 -070071 retl
David S. Millerb445e262005-06-27 15:42:04 -070072 nop
Linus Torvalds1da177e2005-04-16 15:20:36 -070073 .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
Linus Torvalds1da177e2005-04-16 15:20:36 -070091 clr %o0
David S. Millerb445e262005-06-27 15:42:04 -070092 movrne %g2, 1, %o0
93 BITOP_POST_BARRIER
Linus Torvalds1da177e2005-04-16 15:20:36 -070094 retl
David S. Millerb445e262005-06-27 15:42:04 -070095 nop
Linus Torvalds1da177e2005-04-16 15:20:36 -070096 .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