blob: 3dc61d5537c08a6ad56f37b90df340a527298bb7 [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 .globl test_and_set_bit
12 .type test_and_set_bit,#function
13test_and_set_bit: /* %o0=nr, %o1=addr */
David S. Miller24f287e2007-10-15 16:41:44 -070014 BACKOFF_SETUP(%o3)
Linus Torvalds1da177e2005-04-16 15:20:36 -070015 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
211: ldx [%o1], %g7
22 or %g7, %o2, %g1
23 casx [%o1], %g7, %g1
24 cmp %g7, %g1
David S. Miller0f581892010-08-18 22:53:26 -070025 bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -070026 and %g7, %o2, %g2
Linus Torvalds1da177e2005-04-16 15:20:36 -070027 clr %o0
David S. Millerb445e262005-06-27 15:42:04 -070028 movrne %g2, 1, %o0
Linus Torvalds1da177e2005-04-16 15:20:36 -070029 retl
David S. Millerb445e262005-06-27 15:42:04 -070030 nop
David S. Miller24f287e2007-10-15 16:41:44 -0700312: BACKOFF_SPIN(%o3, %o4, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -070032 .size test_and_set_bit, .-test_and_set_bit
33
34 .globl test_and_clear_bit
35 .type test_and_clear_bit,#function
36test_and_clear_bit: /* %o0=nr, %o1=addr */
David S. Miller24f287e2007-10-15 16:41:44 -070037 BACKOFF_SETUP(%o3)
Linus Torvalds1da177e2005-04-16 15:20:36 -070038 srlx %o0, 6, %g1
39 mov 1, %o2
40 sllx %g1, 3, %g3
41 and %o0, 63, %g2
42 sllx %o2, %g2, %o2
43 add %o1, %g3, %o1
441: ldx [%o1], %g7
45 andn %g7, %o2, %g1
46 casx [%o1], %g7, %g1
47 cmp %g7, %g1
David S. Miller0f581892010-08-18 22:53:26 -070048 bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -070049 and %g7, %o2, %g2
Linus Torvalds1da177e2005-04-16 15:20:36 -070050 clr %o0
David S. Millerb445e262005-06-27 15:42:04 -070051 movrne %g2, 1, %o0
Linus Torvalds1da177e2005-04-16 15:20:36 -070052 retl
David S. Millerb445e262005-06-27 15:42:04 -070053 nop
David S. Miller24f287e2007-10-15 16:41:44 -0700542: BACKOFF_SPIN(%o3, %o4, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -070055 .size test_and_clear_bit, .-test_and_clear_bit
56
57 .globl test_and_change_bit
58 .type test_and_change_bit,#function
59test_and_change_bit: /* %o0=nr, %o1=addr */
David S. Miller24f287e2007-10-15 16:41:44 -070060 BACKOFF_SETUP(%o3)
Linus Torvalds1da177e2005-04-16 15:20:36 -070061 srlx %o0, 6, %g1
62 mov 1, %o2
63 sllx %g1, 3, %g3
64 and %o0, 63, %g2
65 sllx %o2, %g2, %o2
66 add %o1, %g3, %o1
671: ldx [%o1], %g7
68 xor %g7, %o2, %g1
69 casx [%o1], %g7, %g1
70 cmp %g7, %g1
David S. Miller0f581892010-08-18 22:53:26 -070071 bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -070072 and %g7, %o2, %g2
Linus Torvalds1da177e2005-04-16 15:20:36 -070073 clr %o0
David S. Millerb445e262005-06-27 15:42:04 -070074 movrne %g2, 1, %o0
Linus Torvalds1da177e2005-04-16 15:20:36 -070075 retl
David S. Millerb445e262005-06-27 15:42:04 -070076 nop
David S. Miller24f287e2007-10-15 16:41:44 -0700772: BACKOFF_SPIN(%o3, %o4, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -070078 .size test_and_change_bit, .-test_and_change_bit
79
80 .globl set_bit
81 .type set_bit,#function
82set_bit: /* %o0=nr, %o1=addr */
David S. Miller24f287e2007-10-15 16:41:44 -070083 BACKOFF_SETUP(%o3)
Linus Torvalds1da177e2005-04-16 15:20:36 -070084 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 or %g7, %o2, %g1
92 casx [%o1], %g7, %g1
93 cmp %g7, %g1
David S. Miller0f581892010-08-18 22:53:26 -070094 bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -070095 nop
96 retl
97 nop
David S. Miller24f287e2007-10-15 16:41:44 -0700982: BACKOFF_SPIN(%o3, %o4, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -070099 .size set_bit, .-set_bit
100
101 .globl clear_bit
102 .type clear_bit,#function
103clear_bit: /* %o0=nr, %o1=addr */
David S. Miller24f287e2007-10-15 16:41:44 -0700104 BACKOFF_SETUP(%o3)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700105 srlx %o0, 6, %g1
106 mov 1, %o2
107 sllx %g1, 3, %g3
108 and %o0, 63, %g2
109 sllx %o2, %g2, %o2
110 add %o1, %g3, %o1
1111: ldx [%o1], %g7
112 andn %g7, %o2, %g1
113 casx [%o1], %g7, %g1
114 cmp %g7, %g1
David S. Miller0f581892010-08-18 22:53:26 -0700115 bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116 nop
117 retl
118 nop
David S. Miller24f287e2007-10-15 16:41:44 -07001192: BACKOFF_SPIN(%o3, %o4, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700120 .size clear_bit, .-clear_bit
121
122 .globl change_bit
123 .type change_bit,#function
124change_bit: /* %o0=nr, %o1=addr */
David S. Miller24f287e2007-10-15 16:41:44 -0700125 BACKOFF_SETUP(%o3)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700126 srlx %o0, 6, %g1
127 mov 1, %o2
128 sllx %g1, 3, %g3
129 and %o0, 63, %g2
130 sllx %o2, %g2, %o2
131 add %o1, %g3, %o1
1321: ldx [%o1], %g7
133 xor %g7, %o2, %g1
134 casx [%o1], %g7, %g1
135 cmp %g7, %g1
David S. Miller0f581892010-08-18 22:53:26 -0700136 bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700137 nop
138 retl
139 nop
David S. Miller24f287e2007-10-15 16:41:44 -07001402: BACKOFF_SPIN(%o3, %o4, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700141 .size change_bit, .-change_bit