OSDN Git Service

Move libgcc1 to toplevel libgcc
[pf3gnuchains/gcc-fork.git] / gcc / config / sh / linux-atomic.asm
1 /* Copyright (C) 2006, 2008, 2009 Free Software Foundation, Inc.
2
3    This file is part of GCC.
4
5    GCC is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 3, or (at your option)
8    any later version.
9
10    GCC is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    Under Section 7 of GPL version 3, you are granted additional
16    permissions described in the GCC Runtime Library Exception, version
17    3.1, as published by the Free Software Foundation.
18
19    You should have received a copy of the GNU General Public License and
20    a copy of the GCC Runtime Library Exception along with this program;
21    see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
22    <http://www.gnu.org/licenses/>.  */
23
24
25 !! Linux specific atomic routines for the Renesas / SuperH SH CPUs.
26 !! Linux kernel for SH3/4 has implemented the support for software
27 !! atomic sequences.
28
29 #define FUNC(X)         .type X,@function
30 #define HIDDEN_FUNC(X)  FUNC(X); .hidden X
31 #define ENDFUNC0(X)     .Lfe_##X: .size X,.Lfe_##X-X
32 #define ENDFUNC(X)      ENDFUNC0(X)
33
34 #if ! __SH5__
35
36 #define ATOMIC_TEST_AND_SET(N,T,EXT) \
37         .global __sync_lock_test_and_set_##N; \
38         HIDDEN_FUNC(__sync_lock_test_and_set_##N); \
39         .align  2; \
40 __sync_lock_test_and_set_##N:; \
41         mova    1f, r0; \
42         nop; \
43         mov     r15, r1; \
44         mov     #(0f-1f), r15; \
45 0:      mov.##T @r4, r2; \
46         mov.##T r5, @r4; \
47 1:      mov     r1, r15; \
48         rts; \
49          EXT    r2, r0; \
50         ENDFUNC(__sync_lock_test_and_set_##N)
51
52 ATOMIC_TEST_AND_SET (1,b,extu.b)
53 ATOMIC_TEST_AND_SET (2,w,extu.w)
54 ATOMIC_TEST_AND_SET (4,l,mov)
55
56 #define ATOMIC_COMPARE_AND_SWAP(N,T,EXTS,EXT) \
57         .global __sync_val_compare_and_swap_##N; \
58         HIDDEN_FUNC(__sync_val_compare_and_swap_##N); \
59         .align  2; \
60 __sync_val_compare_and_swap_##N:; \
61         mova    1f, r0; \
62         EXTS    r5, r5; \
63         mov     r15, r1; \
64         mov     #(0f-1f), r15; \
65 0:      mov.##T @r4, r2; \
66         cmp/eq  r2, r5; \
67         bf      1f; \
68         mov.##T r6, @r4; \
69 1:      mov     r1, r15; \
70         rts; \
71          EXT    r2, r0; \
72         ENDFUNC(__sync_val_compare_and_swap_##N)
73
74 ATOMIC_COMPARE_AND_SWAP (1,b,exts.b,extu.b)
75 ATOMIC_COMPARE_AND_SWAP (2,w,exts.w,extu.w)
76 ATOMIC_COMPARE_AND_SWAP (4,l,mov,mov)
77
78 #define ATOMIC_BOOL_COMPARE_AND_SWAP(N,T,EXTS) \
79         .global __sync_bool_compare_and_swap_##N; \
80         HIDDEN_FUNC(__sync_bool_compare_and_swap_##N); \
81         .align  2; \
82 __sync_bool_compare_and_swap_##N:; \
83         mova    1f, r0; \
84         EXTS    r5, r5; \
85         mov     r15, r1; \
86         mov     #(0f-1f), r15; \
87 0:      mov.##T @r4, r2; \
88         cmp/eq  r2, r5; \
89         bf      1f; \
90         mov.##T r6, @r4; \
91 1:      mov     r1, r15; \
92         rts; \
93          movt   r0; \
94         ENDFUNC(__sync_bool_compare_and_swap_##N)
95
96 ATOMIC_BOOL_COMPARE_AND_SWAP (1,b,exts.b)
97 ATOMIC_BOOL_COMPARE_AND_SWAP (2,w,exts.w)
98 ATOMIC_BOOL_COMPARE_AND_SWAP (4,l,mov)
99
100 #define ATOMIC_FETCH_AND_OP(OP,N,T,EXT) \
101         .global __sync_fetch_and_##OP##_##N; \
102         HIDDEN_FUNC(__sync_fetch_and_##OP##_##N); \
103         .align  2; \
104 __sync_fetch_and_##OP##_##N:; \
105         mova    1f, r0; \
106         nop; \
107         mov     r15, r1; \
108         mov     #(0f-1f), r15; \
109 0:      mov.##T @r4, r2; \
110         mov     r5, r3; \
111         OP      r2, r3; \
112         mov.##T r3, @r4; \
113 1:      mov     r1, r15; \
114         rts; \
115          EXT    r2, r0; \
116         ENDFUNC(__sync_fetch_and_##OP##_##N)
117
118 ATOMIC_FETCH_AND_OP(add,1,b,extu.b)
119 ATOMIC_FETCH_AND_OP(add,2,w,extu.w)
120 ATOMIC_FETCH_AND_OP(add,4,l,mov)
121
122 ATOMIC_FETCH_AND_OP(or,1,b,extu.b)
123 ATOMIC_FETCH_AND_OP(or,2,w,extu.w)
124 ATOMIC_FETCH_AND_OP(or,4,l,mov)
125
126 ATOMIC_FETCH_AND_OP(and,1,b,extu.b)
127 ATOMIC_FETCH_AND_OP(and,2,w,extu.w)
128 ATOMIC_FETCH_AND_OP(and,4,l,mov)
129
130 ATOMIC_FETCH_AND_OP(xor,1,b,extu.b)
131 ATOMIC_FETCH_AND_OP(xor,2,w,extu.w)
132 ATOMIC_FETCH_AND_OP(xor,4,l,mov)
133
134 #define ATOMIC_FETCH_AND_COMBOP(OP,OP0,OP1,N,T,EXT) \
135         .global __sync_fetch_and_##OP##_##N; \
136         HIDDEN_FUNC(__sync_fetch_and_##OP##_##N); \
137         .align  2; \
138 __sync_fetch_and_##OP##_##N:; \
139         mova    1f, r0; \
140         mov     r15, r1; \
141         mov     #(0f-1f), r15; \
142 0:      mov.##T @r4, r2; \
143         mov     r5, r3; \
144         OP0     r2, r3; \
145         OP1     r3, r3; \
146         mov.##T r3, @r4; \
147 1:      mov     r1, r15; \
148         rts; \
149          EXT    r2, r0; \
150         ENDFUNC(__sync_fetch_and_##OP##_##N)
151
152 ATOMIC_FETCH_AND_COMBOP(sub,sub,neg,1,b,extu.b)
153 ATOMIC_FETCH_AND_COMBOP(sub,sub,neg,2,w,extu.w)
154 ATOMIC_FETCH_AND_COMBOP(sub,sub,neg,4,l,mov)
155
156 ATOMIC_FETCH_AND_COMBOP(nand,and,not,1,b,extu.b)
157 ATOMIC_FETCH_AND_COMBOP(nand,and,not,2,w,extu.w)
158 ATOMIC_FETCH_AND_COMBOP(nand,and,not,4,l,mov)
159
160 #define ATOMIC_OP_AND_FETCH(OP,N,T,EXT) \
161         .global __sync_##OP##_and_fetch_##N; \
162         HIDDEN_FUNC(__sync_##OP##_and_fetch_##N); \
163         .align  2; \
164 __sync_##OP##_and_fetch_##N:; \
165         mova    1f, r0; \
166         nop; \
167         mov     r15, r1; \
168         mov     #(0f-1f), r15; \
169 0:      mov.##T @r4, r2; \
170         mov     r5, r3; \
171         OP      r2, r3; \
172         mov.##T r3, @r4; \
173 1:      mov     r1, r15; \
174         rts; \
175          EXT    r3, r0; \
176         ENDFUNC(__sync_##OP##_and_fetch_##N)
177
178 ATOMIC_OP_AND_FETCH(add,1,b,extu.b)
179 ATOMIC_OP_AND_FETCH(add,2,w,extu.w)
180 ATOMIC_OP_AND_FETCH(add,4,l,mov)
181
182 ATOMIC_OP_AND_FETCH(or,1,b,extu.b)
183 ATOMIC_OP_AND_FETCH(or,2,w,extu.w)
184 ATOMIC_OP_AND_FETCH(or,4,l,mov)
185
186 ATOMIC_OP_AND_FETCH(and,1,b,extu.b)
187 ATOMIC_OP_AND_FETCH(and,2,w,extu.w)
188 ATOMIC_OP_AND_FETCH(and,4,l,mov)
189
190 ATOMIC_OP_AND_FETCH(xor,1,b,extu.b)
191 ATOMIC_OP_AND_FETCH(xor,2,w,extu.w)
192 ATOMIC_OP_AND_FETCH(xor,4,l,mov)
193
194 #define ATOMIC_COMBOP_AND_FETCH(OP,OP0,OP1,N,T,EXT) \
195         .global __sync_##OP##_and_fetch_##N; \
196         HIDDEN_FUNC(__sync_##OP##_and_fetch_##N); \
197         .align  2; \
198 __sync_##OP##_and_fetch_##N:; \
199         mova    1f, r0; \
200         mov     r15, r1; \
201         mov     #(0f-1f), r15; \
202 0:      mov.##T @r4, r2; \
203         mov     r5, r3; \
204         OP0     r2, r3; \
205         OP1     r3, r3; \
206         mov.##T r3, @r4; \
207 1:      mov     r1, r15; \
208         rts; \
209          EXT    r3, r0; \
210         ENDFUNC(__sync_##OP##_and_fetch_##N)
211
212 ATOMIC_COMBOP_AND_FETCH(sub,sub,neg,1,b,extu.b)
213 ATOMIC_COMBOP_AND_FETCH(sub,sub,neg,2,w,extu.w)
214 ATOMIC_COMBOP_AND_FETCH(sub,sub,neg,4,l,mov)
215
216 ATOMIC_COMBOP_AND_FETCH(nand,and,not,1,b,extu.b)
217 ATOMIC_COMBOP_AND_FETCH(nand,and,not,2,w,extu.w)
218 ATOMIC_COMBOP_AND_FETCH(nand,and,not,4,l,mov)
219
220 .section .note.GNU-stack,"",%progbits
221 .previous
222
223 #endif /* ! __SH5__ */