blob: 59186e0fcf398feb5880b37fa28624230e0c756b [file] [log] [blame]
David S. Miller24f287e2007-10-15 16:41:44 -07001/* atomic.S: These things are too big to do inline.
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 *
David S. Miller24f287e2007-10-15 16:41:44 -07003 * Copyright (C) 1999, 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
Linus Torvalds1da177e2005-04-16 15:20:36 -07009 .text
10
11 /* Two versions of the atomic routines, one that
12 * does not return a value and does not perform
13 * memory barriers, and a second which returns
14 * a value and does the barriers.
15 */
16 .globl atomic_add
17 .type atomic_add,#function
18atomic_add: /* %o0 = increment, %o1 = atomic_ptr */
David S. Miller24f287e2007-10-15 16:41:44 -070019 BACKOFF_SETUP(%o2)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700201: lduw [%o1], %g1
21 add %g1, %o0, %g7
22 cas [%o1], %g1, %g7
23 cmp %g1, %g7
David S. Miller0f581892010-08-18 22:53:26 -070024 bne,pn %icc, BACKOFF_LABEL(2f, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -070025 nop
26 retl
27 nop
David S. Miller24f287e2007-10-15 16:41:44 -0700282: BACKOFF_SPIN(%o2, %o3, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -070029 .size atomic_add, .-atomic_add
30
31 .globl atomic_sub
32 .type atomic_sub,#function
33atomic_sub: /* %o0 = decrement, %o1 = atomic_ptr */
David S. Miller24f287e2007-10-15 16:41:44 -070034 BACKOFF_SETUP(%o2)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700351: lduw [%o1], %g1
36 sub %g1, %o0, %g7
37 cas [%o1], %g1, %g7
38 cmp %g1, %g7
David S. Miller0f581892010-08-18 22:53:26 -070039 bne,pn %icc, BACKOFF_LABEL(2f, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -070040 nop
41 retl
42 nop
David S. Miller24f287e2007-10-15 16:41:44 -0700432: BACKOFF_SPIN(%o2, %o3, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -070044 .size atomic_sub, .-atomic_sub
45
46 .globl atomic_add_ret
47 .type atomic_add_ret,#function
48atomic_add_ret: /* %o0 = increment, %o1 = atomic_ptr */
David S. Miller24f287e2007-10-15 16:41:44 -070049 BACKOFF_SETUP(%o2)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700501: lduw [%o1], %g1
51 add %g1, %o0, %g7
52 cas [%o1], %g1, %g7
53 cmp %g1, %g7
David S. Miller0f581892010-08-18 22:53:26 -070054 bne,pn %icc, BACKOFF_LABEL(2f, 1b)
Mikulas Patocka6ec27472010-08-18 08:03:37 +000055 add %g1, %o0, %g1
Linus Torvalds1da177e2005-04-16 15:20:36 -070056 retl
Mikulas Patocka6ec27472010-08-18 08:03:37 +000057 sra %g1, 0, %o0
David S. Miller24f287e2007-10-15 16:41:44 -0700582: BACKOFF_SPIN(%o2, %o3, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -070059 .size atomic_add_ret, .-atomic_add_ret
60
61 .globl atomic_sub_ret
62 .type atomic_sub_ret,#function
63atomic_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */
David S. Miller24f287e2007-10-15 16:41:44 -070064 BACKOFF_SETUP(%o2)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700651: lduw [%o1], %g1
66 sub %g1, %o0, %g7
67 cas [%o1], %g1, %g7
68 cmp %g1, %g7
David S. Miller0f581892010-08-18 22:53:26 -070069 bne,pn %icc, BACKOFF_LABEL(2f, 1b)
Mikulas Patocka6ec27472010-08-18 08:03:37 +000070 sub %g1, %o0, %g1
Linus Torvalds1da177e2005-04-16 15:20:36 -070071 retl
Mikulas Patocka6ec27472010-08-18 08:03:37 +000072 sra %g1, 0, %o0
David S. Miller24f287e2007-10-15 16:41:44 -0700732: BACKOFF_SPIN(%o2, %o3, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -070074 .size atomic_sub_ret, .-atomic_sub_ret
75
76 .globl atomic64_add
77 .type atomic64_add,#function
78atomic64_add: /* %o0 = increment, %o1 = atomic_ptr */
David S. Miller24f287e2007-10-15 16:41:44 -070079 BACKOFF_SETUP(%o2)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700801: ldx [%o1], %g1
81 add %g1, %o0, %g7
82 casx [%o1], %g1, %g7
83 cmp %g1, %g7
David S. Miller0f581892010-08-18 22:53:26 -070084 bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -070085 nop
86 retl
87 nop
David S. Miller24f287e2007-10-15 16:41:44 -0700882: BACKOFF_SPIN(%o2, %o3, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -070089 .size atomic64_add, .-atomic64_add
90
91 .globl atomic64_sub
92 .type atomic64_sub,#function
93atomic64_sub: /* %o0 = decrement, %o1 = atomic_ptr */
David S. Miller24f287e2007-10-15 16:41:44 -070094 BACKOFF_SETUP(%o2)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700951: ldx [%o1], %g1
96 sub %g1, %o0, %g7
97 casx [%o1], %g1, %g7
98 cmp %g1, %g7
David S. Miller0f581892010-08-18 22:53:26 -070099 bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700100 nop
101 retl
102 nop
David S. Miller24f287e2007-10-15 16:41:44 -07001032: BACKOFF_SPIN(%o2, %o3, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104 .size atomic64_sub, .-atomic64_sub
105
106 .globl atomic64_add_ret
107 .type atomic64_add_ret,#function
108atomic64_add_ret: /* %o0 = increment, %o1 = atomic_ptr */
David S. Miller24f287e2007-10-15 16:41:44 -0700109 BACKOFF_SETUP(%o2)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001101: ldx [%o1], %g1
111 add %g1, %o0, %g7
112 casx [%o1], %g1, %g7
113 cmp %g1, %g7
David S. Miller0f581892010-08-18 22:53:26 -0700114 bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
David S. Millerb445e262005-06-27 15:42:04 -0700115 nop
Mikulas Patocka6ec27472010-08-18 08:03:37 +0000116 retl
117 add %g1, %o0, %o0
David S. Miller24f287e2007-10-15 16:41:44 -07001182: BACKOFF_SPIN(%o2, %o3, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700119 .size atomic64_add_ret, .-atomic64_add_ret
120
121 .globl atomic64_sub_ret
122 .type atomic64_sub_ret,#function
123atomic64_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */
David S. Miller24f287e2007-10-15 16:41:44 -0700124 BACKOFF_SETUP(%o2)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001251: ldx [%o1], %g1
126 sub %g1, %o0, %g7
127 casx [%o1], %g1, %g7
128 cmp %g1, %g7
David S. Miller0f581892010-08-18 22:53:26 -0700129 bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
David S. Millerb445e262005-06-27 15:42:04 -0700130 nop
Mikulas Patocka6ec27472010-08-18 08:03:37 +0000131 retl
132 sub %g1, %o0, %o0
David S. Miller24f287e2007-10-15 16:41:44 -07001332: BACKOFF_SPIN(%o2, %o3, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700134 .size atomic64_sub_ret, .-atomic64_sub_ret