Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/penberg...
[deliverable/linux.git] / arch / sparc64 / lib / bitops.S
1 /* bitops.S: Sparc64 atomic bit operations.
2 *
3 * Copyright (C) 2000, 2007 David S. Miller (davem@davemloft.net)
4 */
5
6 #include <asm/asi.h>
7 #include <asm/backoff.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
22 80: 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
31 test_and_set_bit: /* %o0=nr, %o1=addr */
32 BACKOFF_SETUP(%o3)
33 BITOP_PRE_BARRIER
34 srlx %o0, 6, %g1
35 mov 1, %o2
36 sllx %g1, 3, %g3
37 and %o0, 63, %g2
38 sllx %o2, %g2, %o2
39 add %o1, %g3, %o1
40 1: ldx [%o1], %g7
41 or %g7, %o2, %g1
42 casx [%o1], %g7, %g1
43 cmp %g7, %g1
44 bne,pn %xcc, 2f
45 and %g7, %o2, %g2
46 clr %o0
47 movrne %g2, 1, %o0
48 BITOP_POST_BARRIER
49 retl
50 nop
51 2: BACKOFF_SPIN(%o3, %o4, 1b)
52 .size test_and_set_bit, .-test_and_set_bit
53
54 .globl test_and_clear_bit
55 .type test_and_clear_bit,#function
56 test_and_clear_bit: /* %o0=nr, %o1=addr */
57 BACKOFF_SETUP(%o3)
58 BITOP_PRE_BARRIER
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
65 1: ldx [%o1], %g7
66 andn %g7, %o2, %g1
67 casx [%o1], %g7, %g1
68 cmp %g7, %g1
69 bne,pn %xcc, 2f
70 and %g7, %o2, %g2
71 clr %o0
72 movrne %g2, 1, %o0
73 BITOP_POST_BARRIER
74 retl
75 nop
76 2: BACKOFF_SPIN(%o3, %o4, 1b)
77 .size test_and_clear_bit, .-test_and_clear_bit
78
79 .globl test_and_change_bit
80 .type test_and_change_bit,#function
81 test_and_change_bit: /* %o0=nr, %o1=addr */
82 BACKOFF_SETUP(%o3)
83 BITOP_PRE_BARRIER
84 srlx %o0, 6, %g1
85 mov 1, %o2
86 sllx %g1, 3, %g3
87 and %o0, 63, %g2
88 sllx %o2, %g2, %o2
89 add %o1, %g3, %o1
90 1: ldx [%o1], %g7
91 xor %g7, %o2, %g1
92 casx [%o1], %g7, %g1
93 cmp %g7, %g1
94 bne,pn %xcc, 2f
95 and %g7, %o2, %g2
96 clr %o0
97 movrne %g2, 1, %o0
98 BITOP_POST_BARRIER
99 retl
100 nop
101 2: BACKOFF_SPIN(%o3, %o4, 1b)
102 .size test_and_change_bit, .-test_and_change_bit
103
104 .globl set_bit
105 .type set_bit,#function
106 set_bit: /* %o0=nr, %o1=addr */
107 BACKOFF_SETUP(%o3)
108 srlx %o0, 6, %g1
109 mov 1, %o2
110 sllx %g1, 3, %g3
111 and %o0, 63, %g2
112 sllx %o2, %g2, %o2
113 add %o1, %g3, %o1
114 1: ldx [%o1], %g7
115 or %g7, %o2, %g1
116 casx [%o1], %g7, %g1
117 cmp %g7, %g1
118 bne,pn %xcc, 2f
119 nop
120 retl
121 nop
122 2: BACKOFF_SPIN(%o3, %o4, 1b)
123 .size set_bit, .-set_bit
124
125 .globl clear_bit
126 .type clear_bit,#function
127 clear_bit: /* %o0=nr, %o1=addr */
128 BACKOFF_SETUP(%o3)
129 srlx %o0, 6, %g1
130 mov 1, %o2
131 sllx %g1, 3, %g3
132 and %o0, 63, %g2
133 sllx %o2, %g2, %o2
134 add %o1, %g3, %o1
135 1: ldx [%o1], %g7
136 andn %g7, %o2, %g1
137 casx [%o1], %g7, %g1
138 cmp %g7, %g1
139 bne,pn %xcc, 2f
140 nop
141 retl
142 nop
143 2: BACKOFF_SPIN(%o3, %o4, 1b)
144 .size clear_bit, .-clear_bit
145
146 .globl change_bit
147 .type change_bit,#function
148 change_bit: /* %o0=nr, %o1=addr */
149 BACKOFF_SETUP(%o3)
150 srlx %o0, 6, %g1
151 mov 1, %o2
152 sllx %g1, 3, %g3
153 and %o0, 63, %g2
154 sllx %o2, %g2, %o2
155 add %o1, %g3, %o1
156 1: ldx [%o1], %g7
157 xor %g7, %o2, %g1
158 casx [%o1], %g7, %g1
159 cmp %g7, %g1
160 bne,pn %xcc, 2f
161 nop
162 retl
163 nop
164 2: BACKOFF_SPIN(%o3, %o4, 1b)
165 .size change_bit, .-change_bit
This page took 0.10152 seconds and 5 git commands to generate.