Linux-2.6.12-rc2
[linux-2.6.git] / arch / frv / lib / atomic-ops.S
1 /* atomic-ops.S: kernel atomic operations
2  *
3  * For an explanation of how atomic ops work in this arch, see:
4  *   Documentation/fujitsu/frv/atomic-ops.txt
5  *
6  * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
7  * Written by David Howells (dhowells@redhat.com)
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version
12  * 2 of the License, or (at your option) any later version.
13  */
14
15 #include <asm/spr-regs.h>
16
17         .text
18         .balign 4
19
20 ###############################################################################
21 #
22 # unsigned long atomic_test_and_ANDNOT_mask(unsigned long mask, volatile unsigned long *v);
23 #
24 ###############################################################################
25         .globl          atomic_test_and_ANDNOT_mask
26         .type           atomic_test_and_ANDNOT_mask,@function
27 atomic_test_and_ANDNOT_mask:
28         not.p           gr8,gr10
29 0:
30         orcc            gr0,gr0,gr0,icc3                /* set ICC3.Z */
31         ckeq            icc3,cc7
32         ld.p            @(gr9,gr0),gr8                  /* LD.P/ORCR must be atomic */
33         orcr            cc7,cc7,cc3                     /* set CC3 to true */
34         and             gr8,gr10,gr11
35         cst.p           gr11,@(gr9,gr0)         ,cc3,#1
36         corcc           gr29,gr29,gr0           ,cc3,#1 /* clear ICC3.Z if store happens */
37         beq             icc3,#0,0b
38         bralr
39
40         .size           atomic_test_and_ANDNOT_mask, .-atomic_test_and_ANDNOT_mask
41
42 ###############################################################################
43 #
44 # unsigned long atomic_test_and_OR_mask(unsigned long mask, volatile unsigned long *v);
45 #
46 ###############################################################################
47         .globl          atomic_test_and_OR_mask
48         .type           atomic_test_and_OR_mask,@function
49 atomic_test_and_OR_mask:
50         or.p            gr8,gr8,gr10
51 0:
52         orcc            gr0,gr0,gr0,icc3                /* set ICC3.Z */
53         ckeq            icc3,cc7
54         ld.p            @(gr9,gr0),gr8                  /* LD.P/ORCR must be atomic */
55         orcr            cc7,cc7,cc3                     /* set CC3 to true */
56         or              gr8,gr10,gr11
57         cst.p           gr11,@(gr9,gr0)         ,cc3,#1
58         corcc           gr29,gr29,gr0           ,cc3,#1 /* clear ICC3.Z if store happens */
59         beq             icc3,#0,0b
60         bralr
61
62         .size           atomic_test_and_OR_mask, .-atomic_test_and_OR_mask
63
64 ###############################################################################
65 #
66 # unsigned long atomic_test_and_XOR_mask(unsigned long mask, volatile unsigned long *v);
67 #
68 ###############################################################################
69         .globl          atomic_test_and_XOR_mask
70         .type           atomic_test_and_XOR_mask,@function
71 atomic_test_and_XOR_mask:
72         or.p            gr8,gr8,gr10
73 0:
74         orcc            gr0,gr0,gr0,icc3                /* set ICC3.Z */
75         ckeq            icc3,cc7
76         ld.p            @(gr9,gr0),gr8                  /* LD.P/ORCR must be atomic */
77         orcr            cc7,cc7,cc3                     /* set CC3 to true */
78         xor             gr8,gr10,gr11
79         cst.p           gr11,@(gr9,gr0)         ,cc3,#1
80         corcc           gr29,gr29,gr0           ,cc3,#1 /* clear ICC3.Z if store happens */
81         beq             icc3,#0,0b
82         bralr
83
84         .size           atomic_test_and_XOR_mask, .-atomic_test_and_XOR_mask
85
86 ###############################################################################
87 #
88 # int atomic_add_return(int i, atomic_t *v)
89 #
90 ###############################################################################
91         .globl          atomic_add_return
92         .type           atomic_add_return,@function
93 atomic_add_return:
94         or.p            gr8,gr8,gr10
95 0:
96         orcc            gr0,gr0,gr0,icc3                /* set ICC3.Z */
97         ckeq            icc3,cc7
98         ld.p            @(gr9,gr0),gr8                  /* LD.P/ORCR must be atomic */
99         orcr            cc7,cc7,cc3                     /* set CC3 to true */
100         add             gr8,gr10,gr8
101         cst.p           gr8,@(gr9,gr0)          ,cc3,#1
102         corcc           gr29,gr29,gr0           ,cc3,#1 /* clear ICC3.Z if store happens */
103         beq             icc3,#0,0b
104         bralr
105
106         .size           atomic_add_return, .-atomic_add_return
107
108 ###############################################################################
109 #
110 # int atomic_sub_return(int i, atomic_t *v)
111 #
112 ###############################################################################
113         .globl          atomic_sub_return
114         .type           atomic_sub_return,@function
115 atomic_sub_return:
116         or.p            gr8,gr8,gr10
117 0:
118         orcc            gr0,gr0,gr0,icc3                /* set ICC3.Z */
119         ckeq            icc3,cc7
120         ld.p            @(gr9,gr0),gr8                  /* LD.P/ORCR must be atomic */
121         orcr            cc7,cc7,cc3                     /* set CC3 to true */
122         sub             gr8,gr10,gr8
123         cst.p           gr8,@(gr9,gr0)          ,cc3,#1
124         corcc           gr29,gr29,gr0           ,cc3,#1 /* clear ICC3.Z if store happens */
125         beq             icc3,#0,0b
126         bralr
127
128         .size           atomic_sub_return, .-atomic_sub_return
129
130 ###############################################################################
131 #
132 # uint8_t __xchg_8(uint8_t i, uint8_t *v)
133 #
134 ###############################################################################
135         .globl          __xchg_8
136         .type           __xchg_8,@function
137 __xchg_8:
138         or.p            gr8,gr8,gr10
139 0:
140         orcc            gr0,gr0,gr0,icc3                /* set ICC3.Z */
141         ckeq            icc3,cc7
142         ldub.p          @(gr9,gr0),gr8                  /* LD.P/ORCR must be atomic */
143         orcr            cc7,cc7,cc3                     /* set CC3 to true */
144         cstb.p          gr10,@(gr9,gr0)         ,cc3,#1
145         corcc           gr29,gr29,gr0           ,cc3,#1 /* clear ICC3.Z if store happens */
146         beq             icc3,#0,0b
147         bralr
148
149         .size           __xchg_8, .-__xchg_8
150
151 ###############################################################################
152 #
153 # uint16_t __xchg_16(uint16_t i, uint16_t *v)
154 #
155 ###############################################################################
156         .globl          __xchg_16
157         .type           __xchg_16,@function
158 __xchg_16:
159         or.p            gr8,gr8,gr10
160 0:
161         orcc            gr0,gr0,gr0,icc3                /* set ICC3.Z */
162         ckeq            icc3,cc7
163         lduh.p          @(gr9,gr0),gr8                  /* LD.P/ORCR must be atomic */
164         orcr            cc7,cc7,cc3                     /* set CC3 to true */
165         csth.p          gr10,@(gr9,gr0)         ,cc3,#1
166         corcc           gr29,gr29,gr0           ,cc3,#1 /* clear ICC3.Z if store happens */
167         beq             icc3,#0,0b
168         bralr
169
170         .size           __xchg_16, .-__xchg_16
171
172 ###############################################################################
173 #
174 # uint32_t __xchg_32(uint32_t i, uint32_t *v)
175 #
176 ###############################################################################
177         .globl          __xchg_32
178         .type           __xchg_32,@function
179 __xchg_32:
180         or.p            gr8,gr8,gr10
181 0:
182         orcc            gr0,gr0,gr0,icc3                /* set ICC3.Z */
183         ckeq            icc3,cc7
184         ld.p            @(gr9,gr0),gr8                  /* LD.P/ORCR must be atomic */
185         orcr            cc7,cc7,cc3                     /* set CC3 to true */
186         cst.p           gr10,@(gr9,gr0)         ,cc3,#1
187         corcc           gr29,gr29,gr0           ,cc3,#1 /* clear ICC3.Z if store happens */
188         beq             icc3,#0,0b
189         bralr
190
191         .size           __xchg_32, .-__xchg_32
192
193 ###############################################################################
194 #
195 # uint8_t __cmpxchg_8(uint8_t *v, uint8_t test, uint8_t new)
196 #
197 ###############################################################################
198         .globl          __cmpxchg_8
199         .type           __cmpxchg_8,@function
200 __cmpxchg_8:
201         or.p            gr8,gr8,gr11
202 0:
203         orcc            gr0,gr0,gr0,icc3
204         ckeq            icc3,cc7
205         ldub.p          @(gr11,gr0),gr8
206         orcr            cc7,cc7,cc3
207         sub             gr8,gr9,gr7
208         sllicc          gr7,#24,gr0,icc0
209         bne             icc0,#0,1f
210         cstb.p          gr10,@(gr11,gr0)        ,cc3,#1
211         corcc           gr29,gr29,gr0           ,cc3,#1
212         beq             icc3,#0,0b
213 1:
214         bralr
215
216         .size           __cmpxchg_8, .-__cmpxchg_8
217
218 ###############################################################################
219 #
220 # uint16_t __cmpxchg_16(uint16_t *v, uint16_t test, uint16_t new)
221 #
222 ###############################################################################
223         .globl          __cmpxchg_16
224         .type           __cmpxchg_16,@function
225 __cmpxchg_16:
226         or.p            gr8,gr8,gr11
227 0:
228         orcc            gr0,gr0,gr0,icc3
229         ckeq            icc3,cc7
230         lduh.p          @(gr11,gr0),gr8
231         orcr            cc7,cc7,cc3
232         sub             gr8,gr9,gr7
233         sllicc          gr7,#16,gr0,icc0
234         bne             icc0,#0,1f
235         csth.p          gr10,@(gr11,gr0)        ,cc3,#1
236         corcc           gr29,gr29,gr0           ,cc3,#1
237         beq             icc3,#0,0b
238 1:
239         bralr
240
241         .size           __cmpxchg_16, .-__cmpxchg_16
242
243 ###############################################################################
244 #
245 # uint32_t __cmpxchg_32(uint32_t *v, uint32_t test, uint32_t new)
246 #
247 ###############################################################################
248         .globl          __cmpxchg_32
249         .type           __cmpxchg_32,@function
250 __cmpxchg_32:
251         or.p            gr8,gr8,gr11
252 0:
253         orcc            gr0,gr0,gr0,icc3
254         ckeq            icc3,cc7
255         ld.p            @(gr11,gr0),gr8
256         orcr            cc7,cc7,cc3
257         subcc           gr8,gr9,gr7,icc0
258         bne             icc0,#0,1f
259         cst.p           gr10,@(gr11,gr0)        ,cc3,#1
260         corcc           gr29,gr29,gr0           ,cc3,#1
261         beq             icc3,#0,0b
262 1:
263         bralr
264
265         .size           __cmpxchg_32, .-__cmpxchg_32