blob: 36f72cc0e67e682dc347d7efe66ae7c7c2eb5658 [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
David S. Miller8695c372012-05-11 20:33:22 -07006#include <linux/linkage.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -07007#include <asm/asi.h>
David S. Miller24f287e2007-10-15 16:41:44 -07008#include <asm/backoff.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -07009
David S. Millerb445e262005-06-27 15:42:04 -070010 .text
11
David S. Miller8695c372012-05-11 20:33:22 -070012ENTRY(test_and_set_bit) /* %o0=nr, %o1=addr */
David S. Miller24f287e2007-10-15 16:41:44 -070013 BACKOFF_SETUP(%o3)
Linus Torvalds1da177e2005-04-16 15:20:36 -070014 srlx %o0, 6, %g1
15 mov 1, %o2
16 sllx %g1, 3, %g3
17 and %o0, 63, %g2
18 sllx %o2, %g2, %o2
19 add %o1, %g3, %o1
201: ldx [%o1], %g7
21 or %g7, %o2, %g1
22 casx [%o1], %g7, %g1
23 cmp %g7, %g1
David S. Miller0f581892010-08-18 22:53:26 -070024 bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -070025 and %g7, %o2, %g2
Linus Torvalds1da177e2005-04-16 15:20:36 -070026 clr %o0
David S. Millerb445e262005-06-27 15:42:04 -070027 movrne %g2, 1, %o0
Linus Torvalds1da177e2005-04-16 15:20:36 -070028 retl
David S. Millerb445e262005-06-27 15:42:04 -070029 nop
David S. Miller24f287e2007-10-15 16:41:44 -0700302: BACKOFF_SPIN(%o3, %o4, 1b)
David S. Miller8695c372012-05-11 20:33:22 -070031ENDPROC(test_and_set_bit)
Linus Torvalds1da177e2005-04-16 15:20:36 -070032
David S. Miller8695c372012-05-11 20:33:22 -070033ENTRY(test_and_clear_bit) /* %o0=nr, %o1=addr */
David S. Miller24f287e2007-10-15 16:41:44 -070034 BACKOFF_SETUP(%o3)
Linus Torvalds1da177e2005-04-16 15:20:36 -070035 srlx %o0, 6, %g1
36 mov 1, %o2
37 sllx %g1, 3, %g3
38 and %o0, 63, %g2
39 sllx %o2, %g2, %o2
40 add %o1, %g3, %o1
411: ldx [%o1], %g7
42 andn %g7, %o2, %g1
43 casx [%o1], %g7, %g1
44 cmp %g7, %g1
David S. Miller0f581892010-08-18 22:53:26 -070045 bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -070046 and %g7, %o2, %g2
Linus Torvalds1da177e2005-04-16 15:20:36 -070047 clr %o0
David S. Millerb445e262005-06-27 15:42:04 -070048 movrne %g2, 1, %o0
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)
David S. Miller8695c372012-05-11 20:33:22 -070052ENDPROC(test_and_clear_bit)
Linus Torvalds1da177e2005-04-16 15:20:36 -070053
David S. Miller8695c372012-05-11 20:33:22 -070054ENTRY(test_and_change_bit) /* %o0=nr, %o1=addr */
David S. Miller24f287e2007-10-15 16:41:44 -070055 BACKOFF_SETUP(%o3)
Linus Torvalds1da177e2005-04-16 15:20:36 -070056 srlx %o0, 6, %g1
57 mov 1, %o2
58 sllx %g1, 3, %g3
59 and %o0, 63, %g2
60 sllx %o2, %g2, %o2
61 add %o1, %g3, %o1
621: ldx [%o1], %g7
63 xor %g7, %o2, %g1
64 casx [%o1], %g7, %g1
65 cmp %g7, %g1
David S. Miller0f581892010-08-18 22:53:26 -070066 bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -070067 and %g7, %o2, %g2
Linus Torvalds1da177e2005-04-16 15:20:36 -070068 clr %o0
David S. Millerb445e262005-06-27 15:42:04 -070069 movrne %g2, 1, %o0
Linus Torvalds1da177e2005-04-16 15:20:36 -070070 retl
David S. Millerb445e262005-06-27 15:42:04 -070071 nop
David S. Miller24f287e2007-10-15 16:41:44 -0700722: BACKOFF_SPIN(%o3, %o4, 1b)
David S. Miller8695c372012-05-11 20:33:22 -070073ENDPROC(test_and_change_bit)
Linus Torvalds1da177e2005-04-16 15:20:36 -070074
David S. Miller8695c372012-05-11 20:33:22 -070075ENTRY(set_bit) /* %o0=nr, %o1=addr */
David S. Miller24f287e2007-10-15 16:41:44 -070076 BACKOFF_SETUP(%o3)
Linus Torvalds1da177e2005-04-16 15:20:36 -070077 srlx %o0, 6, %g1
78 mov 1, %o2
79 sllx %g1, 3, %g3
80 and %o0, 63, %g2
81 sllx %o2, %g2, %o2
82 add %o1, %g3, %o1
831: ldx [%o1], %g7
84 or %g7, %o2, %g1
85 casx [%o1], %g7, %g1
86 cmp %g7, %g1
David S. Miller0f581892010-08-18 22:53:26 -070087 bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -070088 nop
89 retl
90 nop
David S. Miller24f287e2007-10-15 16:41:44 -0700912: BACKOFF_SPIN(%o3, %o4, 1b)
David S. Miller8695c372012-05-11 20:33:22 -070092ENDPROC(set_bit)
Linus Torvalds1da177e2005-04-16 15:20:36 -070093
David S. Miller8695c372012-05-11 20:33:22 -070094ENTRY(clear_bit) /* %o0=nr, %o1=addr */
David S. Miller24f287e2007-10-15 16:41:44 -070095 BACKOFF_SETUP(%o3)
Linus Torvalds1da177e2005-04-16 15:20:36 -070096 srlx %o0, 6, %g1
97 mov 1, %o2
98 sllx %g1, 3, %g3
99 and %o0, 63, %g2
100 sllx %o2, %g2, %o2
101 add %o1, %g3, %o1
1021: ldx [%o1], %g7
103 andn %g7, %o2, %g1
104 casx [%o1], %g7, %g1
105 cmp %g7, %g1
David S. Miller0f581892010-08-18 22:53:26 -0700106 bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700107 nop
108 retl
109 nop
David S. Miller24f287e2007-10-15 16:41:44 -07001102: BACKOFF_SPIN(%o3, %o4, 1b)
David S. Miller8695c372012-05-11 20:33:22 -0700111ENDPROC(clear_bit)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700112
David S. Miller8695c372012-05-11 20:33:22 -0700113ENTRY(change_bit) /* %o0=nr, %o1=addr */
David S. Miller24f287e2007-10-15 16:41:44 -0700114 BACKOFF_SETUP(%o3)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115 srlx %o0, 6, %g1
116 mov 1, %o2
117 sllx %g1, 3, %g3
118 and %o0, 63, %g2
119 sllx %o2, %g2, %o2
120 add %o1, %g3, %o1
1211: ldx [%o1], %g7
122 xor %g7, %o2, %g1
123 casx [%o1], %g7, %g1
124 cmp %g7, %g1
David S. Miller0f581892010-08-18 22:53:26 -0700125 bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700126 nop
127 retl
128 nop
David S. Miller24f287e2007-10-15 16:41:44 -07001292: BACKOFF_SPIN(%o3, %o4, 1b)
David S. Miller8695c372012-05-11 20:33:22 -0700130ENDPROC(change_bit)