Commit | Line | Data |
---|---|---|
1da177e4 LT |
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 |