blob: 31afbfe6c1e86864242f7e5bc75f5902a4da4387 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/* $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
David S. Millerb445e262005-06-27 15:42:04 -070010 .text
11
Linus Torvalds1da177e2005-04-16 15:20:36 -070012 /* On SMP we need to use memory barriers to ensure
13 * correct memory operation ordering, nop these out
14 * for uniprocessor.
15 */
David S. Millerb445e262005-06-27 15:42:04 -070016
Linus Torvalds1da177e2005-04-16 15:20:36 -070017#ifdef CONFIG_SMP
18#define BITOP_PRE_BARRIER membar #StoreLoad | #LoadLoad
David S. Millerb445e262005-06-27 15:42:04 -070019#define BITOP_POST_BARRIER \
20 ba,pt %xcc, 80b; \
21 membar #StoreLoad | #StoreStore
Linus Torvalds1da177e2005-04-16 15:20:36 -070022
David S. Millerb445e262005-06-27 15:42:04 -07002380: retl
24 nop
25#else
26#define BITOP_PRE_BARRIER
27#define BITOP_POST_BARRIER
28#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -070029
30 .globl test_and_set_bit
31 .type test_and_set_bit,#function
32test_and_set_bit: /* %o0=nr, %o1=addr */
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
401: ldx [%o1], %g7
41 or %g7, %o2, %g1
42 casx [%o1], %g7, %g1
43 cmp %g7, %g1
44 bne,pn %xcc, 1b
45 and %g7, %o2, %g2
Linus Torvalds1da177e2005-04-16 15:20:36 -070046 clr %o0
David S. Millerb445e262005-06-27 15:42:04 -070047 movrne %g2, 1, %o0
48 BITOP_POST_BARRIER
Linus Torvalds1da177e2005-04-16 15:20:36 -070049 retl
David S. Millerb445e262005-06-27 15:42:04 -070050 nop
Linus Torvalds1da177e2005-04-16 15:20:36 -070051 .size test_and_set_bit, .-test_and_set_bit
52
53 .globl test_and_clear_bit
54 .type test_and_clear_bit,#function
55test_and_clear_bit: /* %o0=nr, %o1=addr */
56 BITOP_PRE_BARRIER
57 srlx %o0, 6, %g1
58 mov 1, %o2
59 sllx %g1, 3, %g3
60 and %o0, 63, %g2
61 sllx %o2, %g2, %o2
62 add %o1, %g3, %o1
631: ldx [%o1], %g7
64 andn %g7, %o2, %g1
65 casx [%o1], %g7, %g1
66 cmp %g7, %g1
67 bne,pn %xcc, 1b
68 and %g7, %o2, %g2
Linus Torvalds1da177e2005-04-16 15:20:36 -070069 clr %o0
David S. Millerb445e262005-06-27 15:42:04 -070070 movrne %g2, 1, %o0
71 BITOP_POST_BARRIER
Linus Torvalds1da177e2005-04-16 15:20:36 -070072 retl
David S. Millerb445e262005-06-27 15:42:04 -070073 nop
Linus Torvalds1da177e2005-04-16 15:20:36 -070074 .size test_and_clear_bit, .-test_and_clear_bit
75
76 .globl test_and_change_bit
77 .type test_and_change_bit,#function
78test_and_change_bit: /* %o0=nr, %o1=addr */
79 BITOP_PRE_BARRIER
80 srlx %o0, 6, %g1
81 mov 1, %o2
82 sllx %g1, 3, %g3
83 and %o0, 63, %g2
84 sllx %o2, %g2, %o2
85 add %o1, %g3, %o1
861: ldx [%o1], %g7
87 xor %g7, %o2, %g1
88 casx [%o1], %g7, %g1
89 cmp %g7, %g1
90 bne,pn %xcc, 1b
91 and %g7, %o2, %g2
Linus Torvalds1da177e2005-04-16 15:20:36 -070092 clr %o0
David S. Millerb445e262005-06-27 15:42:04 -070093 movrne %g2, 1, %o0
94 BITOP_POST_BARRIER
Linus Torvalds1da177e2005-04-16 15:20:36 -070095 retl
David S. Millerb445e262005-06-27 15:42:04 -070096 nop
Linus Torvalds1da177e2005-04-16 15:20:36 -070097 .size test_and_change_bit, .-test_and_change_bit
98
99 .globl set_bit
100 .type set_bit,#function
101set_bit: /* %o0=nr, %o1=addr */
102 srlx %o0, 6, %g1
103 mov 1, %o2
104 sllx %g1, 3, %g3
105 and %o0, 63, %g2
106 sllx %o2, %g2, %o2
107 add %o1, %g3, %o1
1081: ldx [%o1], %g7
109 or %g7, %o2, %g1
110 casx [%o1], %g7, %g1
111 cmp %g7, %g1
112 bne,pn %xcc, 1b
113 nop
114 retl
115 nop
116 .size set_bit, .-set_bit
117
118 .globl clear_bit
119 .type clear_bit,#function
120clear_bit: /* %o0=nr, %o1=addr */
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
1271: ldx [%o1], %g7
128 andn %g7, %o2, %g1
129 casx [%o1], %g7, %g1
130 cmp %g7, %g1
131 bne,pn %xcc, 1b
132 nop
133 retl
134 nop
135 .size clear_bit, .-clear_bit
136
137 .globl change_bit
138 .type change_bit,#function
139change_bit: /* %o0=nr, %o1=addr */
140 srlx %o0, 6, %g1
141 mov 1, %o2
142 sllx %g1, 3, %g3
143 and %o0, 63, %g2
144 sllx %o2, %g2, %o2
145 add %o1, %g3, %o1
1461: ldx [%o1], %g7
147 xor %g7, %o2, %g1
148 casx [%o1], %g7, %g1
149 cmp %g7, %g1
150 bne,pn %xcc, 1b
151 nop
152 retl
153 nop
154 .size change_bit, .-change_bit