blob: 6b015a6eefb50017e7d22b2d1edc0637408a1fef [file] [log] [blame]
David S. Miller24f287e2007-10-15 16:41:44 -07001/* bitops.S: Sparc64 atomic bit operations.
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 *
David S. Miller24f287e2007-10-15 16:41:44 -07003 * Copyright (C) 2000, 2007 David S. Miller (davem@davemloft.net)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004 */
5
Linus Torvalds1da177e2005-04-16 15:20:36 -07006#include <asm/asi.h>
David S. Miller24f287e2007-10-15 16:41:44 -07007#include <asm/backoff.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -07008
David S. Millerb445e262005-06-27 15:42:04 -07009 .text
10
Linus Torvalds1da177e2005-04-16 15:20:36 -070011 /* On SMP we need to use memory barriers to ensure
12 * correct memory operation ordering, nop these out
13 * for uniprocessor.
14 */
David S. Millerb445e262005-06-27 15:42:04 -070015
Linus Torvalds1da177e2005-04-16 15:20:36 -070016#ifdef CONFIG_SMP
17#define BITOP_PRE_BARRIER membar #StoreLoad | #LoadLoad
David S. Millerb445e262005-06-27 15:42:04 -070018#define BITOP_POST_BARRIER \
19 ba,pt %xcc, 80b; \
20 membar #StoreLoad | #StoreStore
Linus Torvalds1da177e2005-04-16 15:20:36 -070021
David S. Millerb445e262005-06-27 15:42:04 -07002280: retl
23 nop
24#else
25#define BITOP_PRE_BARRIER
26#define BITOP_POST_BARRIER
27#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -070028
29 .globl test_and_set_bit
30 .type test_and_set_bit,#function
31test_and_set_bit: /* %o0=nr, %o1=addr */
David S. Miller24f287e2007-10-15 16:41:44 -070032 BACKOFF_SETUP(%o3)
Linus Torvalds1da177e2005-04-16 15:20:36 -070033 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
David S. Miller24f287e2007-10-15 16:41:44 -070044 bne,pn %xcc, 2f
Linus Torvalds1da177e2005-04-16 15:20:36 -070045 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
David S. Miller24f287e2007-10-15 16:41:44 -0700512: BACKOFF_SPIN(%o3, %o4, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -070052 .size test_and_set_bit, .-test_and_set_bit
53
54 .globl test_and_clear_bit
55 .type test_and_clear_bit,#function
56test_and_clear_bit: /* %o0=nr, %o1=addr */
David S. Miller24f287e2007-10-15 16:41:44 -070057 BACKOFF_SETUP(%o3)
Linus Torvalds1da177e2005-04-16 15:20:36 -070058 BITOP_PRE_BARRIER
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
651: ldx [%o1], %g7
66 andn %g7, %o2, %g1
67 casx [%o1], %g7, %g1
68 cmp %g7, %g1
David S. Miller24f287e2007-10-15 16:41:44 -070069 bne,pn %xcc, 2f
Linus Torvalds1da177e2005-04-16 15:20:36 -070070 and %g7, %o2, %g2
Linus Torvalds1da177e2005-04-16 15:20:36 -070071 clr %o0
David S. Millerb445e262005-06-27 15:42:04 -070072 movrne %g2, 1, %o0
73 BITOP_POST_BARRIER
Linus Torvalds1da177e2005-04-16 15:20:36 -070074 retl
David S. Millerb445e262005-06-27 15:42:04 -070075 nop
David S. Miller24f287e2007-10-15 16:41:44 -0700762: BACKOFF_SPIN(%o3, %o4, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -070077 .size test_and_clear_bit, .-test_and_clear_bit
78
79 .globl test_and_change_bit
80 .type test_and_change_bit,#function
81test_and_change_bit: /* %o0=nr, %o1=addr */
David S. Miller24f287e2007-10-15 16:41:44 -070082 BACKOFF_SETUP(%o3)
Linus Torvalds1da177e2005-04-16 15:20:36 -070083 BITOP_PRE_BARRIER
84 srlx %o0, 6, %g1
85 mov 1, %o2
86 sllx %g1, 3, %g3
87 and %o0, 63, %g2
88 sllx %o2, %g2, %o2
89 add %o1, %g3, %o1
901: ldx [%o1], %g7
91 xor %g7, %o2, %g1
92 casx [%o1], %g7, %g1
93 cmp %g7, %g1
David S. Miller24f287e2007-10-15 16:41:44 -070094 bne,pn %xcc, 2f
Linus Torvalds1da177e2005-04-16 15:20:36 -070095 and %g7, %o2, %g2
Linus Torvalds1da177e2005-04-16 15:20:36 -070096 clr %o0
David S. Millerb445e262005-06-27 15:42:04 -070097 movrne %g2, 1, %o0
98 BITOP_POST_BARRIER
Linus Torvalds1da177e2005-04-16 15:20:36 -070099 retl
David S. Millerb445e262005-06-27 15:42:04 -0700100 nop
David S. Miller24f287e2007-10-15 16:41:44 -07001012: BACKOFF_SPIN(%o3, %o4, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102 .size test_and_change_bit, .-test_and_change_bit
103
104 .globl set_bit
105 .type set_bit,#function
106set_bit: /* %o0=nr, %o1=addr */
David S. Miller24f287e2007-10-15 16:41:44 -0700107 BACKOFF_SETUP(%o3)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108 srlx %o0, 6, %g1
109 mov 1, %o2
110 sllx %g1, 3, %g3
111 and %o0, 63, %g2
112 sllx %o2, %g2, %o2
113 add %o1, %g3, %o1
1141: ldx [%o1], %g7
115 or %g7, %o2, %g1
116 casx [%o1], %g7, %g1
117 cmp %g7, %g1
David S. Miller24f287e2007-10-15 16:41:44 -0700118 bne,pn %xcc, 2f
Linus Torvalds1da177e2005-04-16 15:20:36 -0700119 nop
120 retl
121 nop
David S. Miller24f287e2007-10-15 16:41:44 -07001222: BACKOFF_SPIN(%o3, %o4, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700123 .size set_bit, .-set_bit
124
125 .globl clear_bit
126 .type clear_bit,#function
127clear_bit: /* %o0=nr, %o1=addr */
David S. Miller24f287e2007-10-15 16:41:44 -0700128 BACKOFF_SETUP(%o3)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129 srlx %o0, 6, %g1
130 mov 1, %o2
131 sllx %g1, 3, %g3
132 and %o0, 63, %g2
133 sllx %o2, %g2, %o2
134 add %o1, %g3, %o1
1351: ldx [%o1], %g7
136 andn %g7, %o2, %g1
137 casx [%o1], %g7, %g1
138 cmp %g7, %g1
David S. Miller24f287e2007-10-15 16:41:44 -0700139 bne,pn %xcc, 2f
Linus Torvalds1da177e2005-04-16 15:20:36 -0700140 nop
141 retl
142 nop
David S. Miller24f287e2007-10-15 16:41:44 -07001432: BACKOFF_SPIN(%o3, %o4, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700144 .size clear_bit, .-clear_bit
145
146 .globl change_bit
147 .type change_bit,#function
148change_bit: /* %o0=nr, %o1=addr */
David S. Miller24f287e2007-10-15 16:41:44 -0700149 BACKOFF_SETUP(%o3)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700150 srlx %o0, 6, %g1
151 mov 1, %o2
152 sllx %g1, 3, %g3
153 and %o0, 63, %g2
154 sllx %o2, %g2, %o2
155 add %o1, %g3, %o1
1561: ldx [%o1], %g7
157 xor %g7, %o2, %g1
158 casx [%o1], %g7, %g1
159 cmp %g7, %g1
David S. Miller24f287e2007-10-15 16:41:44 -0700160 bne,pn %xcc, 2f
Linus Torvalds1da177e2005-04-16 15:20:36 -0700161 nop
162 retl
163 nop
David S. Miller24f287e2007-10-15 16:41:44 -07001642: BACKOFF_SPIN(%o3, %o4, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700165 .size change_bit, .-change_bit