Merge branch 'for-4.0' of git://linux-nfs.org/~bfields/linux
[sfrench/cifs-2.6.git] / arch / sparc / 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 <linux/linkage.h>
7 #include <asm/asi.h>
8 #include <asm/backoff.h>
9
10         .text
11
12 ENTRY(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
20 1:      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
30 2:      BACKOFF_SPIN(%o3, %o4, 1b)
31 ENDPROC(test_and_set_bit)
32
33 ENTRY(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
41 1:      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
51 2:      BACKOFF_SPIN(%o3, %o4, 1b)
52 ENDPROC(test_and_clear_bit)
53
54 ENTRY(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
62 1:      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
72 2:      BACKOFF_SPIN(%o3, %o4, 1b)
73 ENDPROC(test_and_change_bit)
74
75 ENTRY(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
83 1:      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
91 2:      BACKOFF_SPIN(%o3, %o4, 1b)
92 ENDPROC(set_bit)
93
94 ENTRY(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
102 1:      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
110 2:      BACKOFF_SPIN(%o3, %o4, 1b)
111 ENDPROC(clear_bit)
112
113 ENTRY(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
121 1:      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
129 2:      BACKOFF_SPIN(%o3, %o4, 1b)
130 ENDPROC(change_bit)