1 /* Copyright (C) 2006, 2008, 2009 Free Software Foundation, Inc.
3 This file is part of GCC.
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)
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.
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.
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/>. */
25 !! Linux specific atomic routines for the Renesas / SuperH SH CPUs.
26 !! Linux kernel for SH3/4 has implemented the support for software
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)
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); \
40 __sync_lock_test_and_set_##N:; \
50 ENDFUNC(__sync_lock_test_and_set_##N)
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)
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); \
60 __sync_val_compare_and_swap_##N:; \
72 ENDFUNC(__sync_val_compare_and_swap_##N)
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)
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); \
82 __sync_bool_compare_and_swap_##N:; \
94 ENDFUNC(__sync_bool_compare_and_swap_##N)
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)
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); \
104 __sync_fetch_and_##OP##_##N:; \
109 0: mov.##T @r4, r2; \
116 ENDFUNC(__sync_fetch_and_##OP##_##N)
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)
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)
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)
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)
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); \
138 __sync_fetch_and_##OP##_##N:; \
142 0: mov.##T @r4, r2; \
150 ENDFUNC(__sync_fetch_and_##OP##_##N)
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)
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)
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); \
164 __sync_##OP##_and_fetch_##N:; \
169 0: mov.##T @r4, r2; \
176 ENDFUNC(__sync_##OP##_and_fetch_##N)
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)
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)
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)
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)
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); \
198 __sync_##OP##_and_fetch_##N:; \
202 0: mov.##T @r4, r2; \
210 ENDFUNC(__sync_##OP##_and_fetch_##N)
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)
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)
220 .section .note.GNU-stack,"",%progbits
223 #endif /* ! __SH5__ */