GNU Linux-libre 4.9.284-gnu1
[releases.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 #include <asm/export.h>
10
11         .text
12
13 ENTRY(test_and_set_bit) /* %o0=nr, %o1=addr */
14         BACKOFF_SETUP(%o3)
15         srlx    %o0, 6, %g1
16         mov     1, %o2
17         sllx    %g1, 3, %g3
18         and     %o0, 63, %g2
19         sllx    %o2, %g2, %o2
20         add     %o1, %g3, %o1
21 1:      ldx     [%o1], %g7
22         or      %g7, %o2, %g1
23         casx    [%o1], %g7, %g1
24         cmp     %g7, %g1
25         bne,pn  %xcc, BACKOFF_LABEL(2f, 1b)
26          and    %g7, %o2, %g2
27         clr     %o0
28         movrne  %g2, 1, %o0
29         retl
30          nop
31 2:      BACKOFF_SPIN(%o3, %o4, 1b)
32 ENDPROC(test_and_set_bit)
33 EXPORT_SYMBOL(test_and_set_bit)
34
35 ENTRY(test_and_clear_bit) /* %o0=nr, %o1=addr */
36         BACKOFF_SETUP(%o3)
37         srlx    %o0, 6, %g1
38         mov     1, %o2
39         sllx    %g1, 3, %g3
40         and     %o0, 63, %g2
41         sllx    %o2, %g2, %o2
42         add     %o1, %g3, %o1
43 1:      ldx     [%o1], %g7
44         andn    %g7, %o2, %g1
45         casx    [%o1], %g7, %g1
46         cmp     %g7, %g1
47         bne,pn  %xcc, BACKOFF_LABEL(2f, 1b)
48          and    %g7, %o2, %g2
49         clr     %o0
50         movrne  %g2, 1, %o0
51         retl
52          nop
53 2:      BACKOFF_SPIN(%o3, %o4, 1b)
54 ENDPROC(test_and_clear_bit)
55 EXPORT_SYMBOL(test_and_clear_bit)
56
57 ENTRY(test_and_change_bit) /* %o0=nr, %o1=addr */
58         BACKOFF_SETUP(%o3)
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         xor     %g7, %o2, %g1
67         casx    [%o1], %g7, %g1
68         cmp     %g7, %g1
69         bne,pn  %xcc, BACKOFF_LABEL(2f, 1b)
70          and    %g7, %o2, %g2
71         clr     %o0
72         movrne  %g2, 1, %o0
73         retl
74          nop
75 2:      BACKOFF_SPIN(%o3, %o4, 1b)
76 ENDPROC(test_and_change_bit)
77 EXPORT_SYMBOL(test_and_change_bit)
78
79 ENTRY(set_bit) /* %o0=nr, %o1=addr */
80         BACKOFF_SETUP(%o3)
81         srlx    %o0, 6, %g1
82         mov     1, %o2
83         sllx    %g1, 3, %g3
84         and     %o0, 63, %g2
85         sllx    %o2, %g2, %o2
86         add     %o1, %g3, %o1
87 1:      ldx     [%o1], %g7
88         or      %g7, %o2, %g1
89         casx    [%o1], %g7, %g1
90         cmp     %g7, %g1
91         bne,pn  %xcc, BACKOFF_LABEL(2f, 1b)
92          nop
93         retl
94          nop
95 2:      BACKOFF_SPIN(%o3, %o4, 1b)
96 ENDPROC(set_bit)
97 EXPORT_SYMBOL(set_bit)
98
99 ENTRY(clear_bit) /* %o0=nr, %o1=addr */
100         BACKOFF_SETUP(%o3)
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
107 1:      ldx     [%o1], %g7
108         andn    %g7, %o2, %g1
109         casx    [%o1], %g7, %g1
110         cmp     %g7, %g1
111         bne,pn  %xcc, BACKOFF_LABEL(2f, 1b)
112          nop
113         retl
114          nop
115 2:      BACKOFF_SPIN(%o3, %o4, 1b)
116 ENDPROC(clear_bit)
117 EXPORT_SYMBOL(clear_bit)
118
119 ENTRY(change_bit) /* %o0=nr, %o1=addr */
120         BACKOFF_SETUP(%o3)
121         srlx    %o0, 6, %g1
122         mov     1, %o2
123         sllx    %g1, 3, %g3
124         and     %o0, 63, %g2
125         sllx    %o2, %g2, %o2
126         add     %o1, %g3, %o1
127 1:      ldx     [%o1], %g7
128         xor     %g7, %o2, %g1
129         casx    [%o1], %g7, %g1
130         cmp     %g7, %g1
131         bne,pn  %xcc, BACKOFF_LABEL(2f, 1b)
132          nop
133         retl
134          nop
135 2:      BACKOFF_SPIN(%o3, %o4, 1b)
136 ENDPROC(change_bit)
137 EXPORT_SYMBOL(change_bit)