886dcd2b376a0e9d1359b35b04da1124db7746b8
[linux-3.10.git] / arch / sparc64 / lib / bitops.S
1 /* $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
7 #include <linux/config.h>
8 #include <asm/asi.h>
9
10         /* On SMP we need to use memory barriers to ensure
11          * correct memory operation ordering, nop these out
12          * for uniprocessor.
13          */
14 #ifdef CONFIG_SMP
15 #define BITOP_PRE_BARRIER       membar #StoreLoad | #LoadLoad
16 #define BITOP_POST_BARRIER      membar #StoreLoad | #StoreStore
17 #else
18 #define BITOP_PRE_BARRIER       nop
19 #define BITOP_POST_BARRIER      nop
20 #endif
21
22         .text
23
24         .globl  test_and_set_bit
25         .type   test_and_set_bit,#function
26 test_and_set_bit:       /* %o0=nr, %o1=addr */
27         BITOP_PRE_BARRIER
28         srlx    %o0, 6, %g1
29         mov     1, %o2
30         sllx    %g1, 3, %g3
31         and     %o0, 63, %g2
32         sllx    %o2, %g2, %o2
33         add     %o1, %g3, %o1
34 1:      ldx     [%o1], %g7
35         or      %g7, %o2, %g1
36         casx    [%o1], %g7, %g1
37         cmp     %g7, %g1
38         bne,pn  %xcc, 1b
39          and    %g7, %o2, %g2
40         BITOP_POST_BARRIER
41         clr     %o0
42         retl
43          movrne %g2, 1, %o0
44         .size   test_and_set_bit, .-test_and_set_bit
45
46         .globl  test_and_clear_bit
47         .type   test_and_clear_bit,#function
48 test_and_clear_bit:     /* %o0=nr, %o1=addr */
49         BITOP_PRE_BARRIER
50         srlx    %o0, 6, %g1
51         mov     1, %o2
52         sllx    %g1, 3, %g3
53         and     %o0, 63, %g2
54         sllx    %o2, %g2, %o2
55         add     %o1, %g3, %o1
56 1:      ldx     [%o1], %g7
57         andn    %g7, %o2, %g1
58         casx    [%o1], %g7, %g1
59         cmp     %g7, %g1
60         bne,pn  %xcc, 1b
61          and    %g7, %o2, %g2
62         BITOP_POST_BARRIER
63         clr     %o0
64         retl
65          movrne %g2, 1, %o0
66         .size   test_and_clear_bit, .-test_and_clear_bit
67
68         .globl  test_and_change_bit
69         .type   test_and_change_bit,#function
70 test_and_change_bit:    /* %o0=nr, %o1=addr */
71         BITOP_PRE_BARRIER
72         srlx    %o0, 6, %g1
73         mov     1, %o2
74         sllx    %g1, 3, %g3
75         and     %o0, 63, %g2
76         sllx    %o2, %g2, %o2
77         add     %o1, %g3, %o1
78 1:      ldx     [%o1], %g7
79         xor     %g7, %o2, %g1
80         casx    [%o1], %g7, %g1
81         cmp     %g7, %g1
82         bne,pn  %xcc, 1b
83          and    %g7, %o2, %g2
84         BITOP_POST_BARRIER
85         clr     %o0
86         retl
87          movrne %g2, 1, %o0
88         .size   test_and_change_bit, .-test_and_change_bit
89
90         .globl  set_bit
91         .type   set_bit,#function
92 set_bit:                /* %o0=nr, %o1=addr */
93         srlx    %o0, 6, %g1
94         mov     1, %o2
95         sllx    %g1, 3, %g3
96         and     %o0, 63, %g2
97         sllx    %o2, %g2, %o2
98         add     %o1, %g3, %o1
99 1:      ldx     [%o1], %g7
100         or      %g7, %o2, %g1
101         casx    [%o1], %g7, %g1
102         cmp     %g7, %g1
103         bne,pn  %xcc, 1b
104          nop
105         retl
106          nop
107         .size   set_bit, .-set_bit
108
109         .globl  clear_bit
110         .type   clear_bit,#function
111 clear_bit:              /* %o0=nr, %o1=addr */
112         srlx    %o0, 6, %g1
113         mov     1, %o2
114         sllx    %g1, 3, %g3
115         and     %o0, 63, %g2
116         sllx    %o2, %g2, %o2
117         add     %o1, %g3, %o1
118 1:      ldx     [%o1], %g7
119         andn    %g7, %o2, %g1
120         casx    [%o1], %g7, %g1
121         cmp     %g7, %g1
122         bne,pn  %xcc, 1b
123          nop
124         retl
125          nop
126         .size   clear_bit, .-clear_bit
127
128         .globl  change_bit
129         .type   change_bit,#function
130 change_bit:             /* %o0=nr, %o1=addr */
131         srlx    %o0, 6, %g1
132         mov     1, %o2
133         sllx    %g1, 3, %g3
134         and     %o0, 63, %g2
135         sllx    %o2, %g2, %o2
136         add     %o1, %g3, %o1
137 1:      ldx     [%o1], %g7
138         xor     %g7, %o2, %g1
139         casx    [%o1], %g7, %g1
140         cmp     %g7, %g1
141         bne,pn  %xcc, 1b
142          nop
143         retl
144          nop
145         .size   change_bit, .-change_bit