blob: 0268210ca1683f7bd0bb018953d93a22e207c701 [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. Miller24f287e2007-10-15 16:41:44 -070024 bne,pn %icc, 2f
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. Miller24f287e2007-10-15 16:41:44 -070039 bne,pn %icc, 2f
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. Miller24f287e2007-10-15 16:41:44 -070054 bne,pn %icc, 2f
Linus Torvalds1da177e2005-04-16 15:20:36 -070055 add %g7, %o0, %g7
David S. Millerb445e262005-06-27 15:42:04 -070056 sra %g7, 0, %o0
Linus Torvalds1da177e2005-04-16 15:20:36 -070057 retl
David S. Millerb445e262005-06-27 15:42:04 -070058 nop
David S. Miller24f287e2007-10-15 16:41:44 -0700592: BACKOFF_SPIN(%o2, %o3, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -070060 .size atomic_add_ret, .-atomic_add_ret
61
62 .globl atomic_sub_ret
63 .type atomic_sub_ret,#function
64atomic_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */
David S. Miller24f287e2007-10-15 16:41:44 -070065 BACKOFF_SETUP(%o2)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700661: lduw [%o1], %g1
67 sub %g1, %o0, %g7
68 cas [%o1], %g1, %g7
69 cmp %g1, %g7
David S. Miller24f287e2007-10-15 16:41:44 -070070 bne,pn %icc, 2f
Linus Torvalds1da177e2005-04-16 15:20:36 -070071 sub %g7, %o0, %g7
David S. Millerb445e262005-06-27 15:42:04 -070072 sra %g7, 0, %o0
Linus Torvalds1da177e2005-04-16 15:20:36 -070073 retl
David S. Millerb445e262005-06-27 15:42:04 -070074 nop
David S. Miller24f287e2007-10-15 16:41:44 -0700752: BACKOFF_SPIN(%o2, %o3, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -070076 .size atomic_sub_ret, .-atomic_sub_ret
77
78 .globl atomic64_add
79 .type atomic64_add,#function
80atomic64_add: /* %o0 = increment, %o1 = atomic_ptr */
David S. Miller24f287e2007-10-15 16:41:44 -070081 BACKOFF_SETUP(%o2)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700821: ldx [%o1], %g1
83 add %g1, %o0, %g7
84 casx [%o1], %g1, %g7
85 cmp %g1, %g7
David S. Miller24f287e2007-10-15 16:41:44 -070086 bne,pn %xcc, 2f
Linus Torvalds1da177e2005-04-16 15:20:36 -070087 nop
88 retl
89 nop
David S. Miller24f287e2007-10-15 16:41:44 -0700902: BACKOFF_SPIN(%o2, %o3, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -070091 .size atomic64_add, .-atomic64_add
92
93 .globl atomic64_sub
94 .type atomic64_sub,#function
95atomic64_sub: /* %o0 = decrement, %o1 = atomic_ptr */
David S. Miller24f287e2007-10-15 16:41:44 -070096 BACKOFF_SETUP(%o2)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700971: ldx [%o1], %g1
98 sub %g1, %o0, %g7
99 casx [%o1], %g1, %g7
100 cmp %g1, %g7
David S. Miller24f287e2007-10-15 16:41:44 -0700101 bne,pn %xcc, 2f
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102 nop
103 retl
104 nop
David S. Miller24f287e2007-10-15 16:41:44 -07001052: BACKOFF_SPIN(%o2, %o3, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106 .size atomic64_sub, .-atomic64_sub
107
108 .globl atomic64_add_ret
109 .type atomic64_add_ret,#function
110atomic64_add_ret: /* %o0 = increment, %o1 = atomic_ptr */
David S. Miller24f287e2007-10-15 16:41:44 -0700111 BACKOFF_SETUP(%o2)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001121: ldx [%o1], %g1
113 add %g1, %o0, %g7
114 casx [%o1], %g1, %g7
115 cmp %g1, %g7
David S. Miller24f287e2007-10-15 16:41:44 -0700116 bne,pn %xcc, 2f
Linus Torvalds1da177e2005-04-16 15:20:36 -0700117 add %g7, %o0, %g7
David S. Millerb445e262005-06-27 15:42:04 -0700118 mov %g7, %o0
Linus Torvalds1da177e2005-04-16 15:20:36 -0700119 retl
David S. Millerb445e262005-06-27 15:42:04 -0700120 nop
David S. Miller24f287e2007-10-15 16:41:44 -07001212: BACKOFF_SPIN(%o2, %o3, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122 .size atomic64_add_ret, .-atomic64_add_ret
123
124 .globl atomic64_sub_ret
125 .type atomic64_sub_ret,#function
126atomic64_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */
David S. Miller24f287e2007-10-15 16:41:44 -0700127 BACKOFF_SETUP(%o2)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001281: ldx [%o1], %g1
129 sub %g1, %o0, %g7
130 casx [%o1], %g1, %g7
131 cmp %g1, %g7
David S. Miller24f287e2007-10-15 16:41:44 -0700132 bne,pn %xcc, 2f
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133 sub %g7, %o0, %g7
David S. Millerb445e262005-06-27 15:42:04 -0700134 mov %g7, %o0
Linus Torvalds1da177e2005-04-16 15:20:36 -0700135 retl
David S. Millerb445e262005-06-27 15:42:04 -0700136 nop
David S. Miller24f287e2007-10-15 16:41:44 -07001372: BACKOFF_SPIN(%o2, %o3, 1b)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700138 .size atomic64_sub_ret, .-atomic64_sub_ret