atomic-android-armv6.S revision dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0
1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17
18    .text
19    .align
20
21    .global android_atomic_write
22
23    .global android_atomic_inc
24    .global android_atomic_dec
25
26    .global android_atomic_add
27    .global android_atomic_and
28    .global android_atomic_or
29
30    .global android_atomic_swap
31
32    .global android_atomic_cmpxchg
33
34
35
36/* FIXME: On SMP systems memory barriers may be needed */
37#warning  "this file is not safe with SMP systems"
38
39
40/*
41 * ----------------------------------------------------------------------------
42 * android_atomic_write
43 * input: r0=value, r1=address
44 * output: void
45 */
46
47android_atomic_write:
481:  ldrex   r12, [r1]
49    strex   r12, r0, [r1]
50    cmp     r12, #0
51    bne     1b
52    bx      lr
53
54/*
55 * ----------------------------------------------------------------------------
56 * android_atomic_inc
57 * input: r0 = address
58 * output: r0 = old value
59 */
60
61android_atomic_inc:
62    mov     r12, r0
631:  ldrex   r0, [r12]
64    add     r2, r0, #1
65    strex   r1, r2, [r12]
66    cmp     r1, #0
67    bxeq    lr
68    b       1b
69
70/*
71 * ----------------------------------------------------------------------------
72 * android_atomic_dec
73 * input: r0=address
74 * output: r0 = old value
75 */
76
77android_atomic_dec:
78    mov     r12, r0
791:  ldrex   r0, [r12]
80    sub     r2, r0, #1
81    strex   r1, r2, [r12]
82    cmp     r1, #0
83    bxeq    lr
84    b       1b
85
86
87/*
88 * ----------------------------------------------------------------------------
89 * android_atomic_add
90 * input: r0=value, r1=address
91 * output: r0 = old value
92 */
93
94android_atomic_add:
95    mov     r12, r0
961:  ldrex   r0, [r1]
97    add     r2, r0, r12
98    strex   r3, r2, [r1]
99    cmp     r3, #0
100    bxeq    lr
101    b       1b
102
103/*
104 * ----------------------------------------------------------------------------
105 * android_atomic_and
106 * input: r0=value, r1=address
107 * output: r0 = old value
108 */
109
110android_atomic_and:
111    mov     r12, r0
1121:  ldrex   r0, [r1]
113    and     r2, r0, r12
114    strex   r3, r2, [r1]
115    cmp     r3, #0
116    bxeq    lr
117    b       1b
118
119
120/*
121 * ----------------------------------------------------------------------------
122 * android_atomic_or
123 * input: r0=value, r1=address
124 * output: r0 = old value
125 */
126
127android_atomic_or:
128    mov     r12, r0
1291:  ldrex   r0, [r1]
130    orr     r2, r0, r12
131    strex   r3, r2, [r1]
132    cmp     r3, #0
133    bxeq    lr
134    b       1b
135
136/*
137 * ----------------------------------------------------------------------------
138 * android_atomic_swap
139 * input: r0=value, r1=address
140 * output: r0 = old value
141 */
142
143android_atomic_swap:
144    swp     r0, r0, [r1]
145    bx      lr
146
147/*
148 * ----------------------------------------------------------------------------
149 * android_atomic_cmpxchg
150 * input: r0=oldvalue, r1=newvalue, r2=address
151 * output: r0 = 0 (xchg done) or non-zero (xchg not done)
152 */
153
154android_atomic_cmpxchg:
155    mov     r12, r1
156    ldrex   r3, [r2]
157    eors    r0, r0, r3
158    strexeq r0, r12, [r2]
159    bx      lr
160
161
162
163/*
164 * ----------------------------------------------------------------------------
165 * android_atomic_cmpxchg_64
166 * input: r0-r1=oldvalue, r2-r3=newvalue, arg4 (on stack)=address
167 * output: r0 = 0 (xchg done) or non-zero (xchg not done)
168 */
169/* TODO: NEED IMPLEMENTATION FOR THIS ARCHITECTURE */
170