Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[wrt350n-kernel.git] / arch / sparc64 / lib / bitops.S
blob6b015a6eefb50017e7d22b2d1edc0637408a1fef
1 /* bitops.S: Sparc64 atomic bit operations.
2  *
3  * Copyright (C) 2000, 2007 David S. Miller (davem@davemloft.net)
4  */
6 #include <asm/asi.h>
7 #include <asm/backoff.h>
9         .text
11         /* On SMP we need to use memory barriers to ensure
12          * correct memory operation ordering, nop these out
13          * for uniprocessor.
14          */
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
22 80:     retl
23          nop
24 #else
25 #define BITOP_PRE_BARRIER
26 #define BITOP_POST_BARRIER
27 #endif
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
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
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
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
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
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