]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgcc/sync.c
Daily bump.
[thirdparty/gcc.git] / libgcc / sync.c
CommitLineData
f92518d7 1/* Out-of-line libgcc versions of __sync_* builtins. */
99dee823 2/* Copyright (C) 2008-2021 Free Software Foundation, Inc.
f92518d7
RS
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
748086b7 8Software Foundation; either version 3, or (at your option) any later
f92518d7
RS
9version.
10
f92518d7
RS
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
15
748086b7
JJ
16Under Section 7 of GPL version 3, you are granted additional
17permissions described in the GCC Runtime Library Exception, version
183.1, as published by the Free Software Foundation.
19
20You should have received a copy of the GNU General Public License and
21a copy of the GCC Runtime Library Exception along with this program;
22see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23<http://www.gnu.org/licenses/>. */
f92518d7 24
c6412d86
RO
25/* This file is used by targets whose makefiles define SYNC
26 to "yes". It is compiled with SYNC_CFLAGS and provides
f92518d7
RS
27 out-of-line versions of all relevant __sync_* primitives.
28
29 These routines are intended for targets like MIPS that have two
30 ISA encodings (the "normal" ISA and the MIPS16 ISA). The normal
31 ISA provides full synchronization capabilities but the MIPS16 ISA
32 has no encoding for them. MIPS16 code must therefore call external
33 non-MIPS16 implementations of the __sync_* routines.
34
35 The file is compiled once for each routine. The following __foo
36 routines are selected by defining a macro called L<foo>:
37
38 __sync_synchronize
39
40 The following __foo_N routines are selected by defining FN=foo
41 and SIZE=N:
42
43 __sync_fetch_and_add_N
44 __sync_fetch_and_sub_N
45 __sync_fetch_and_or_N
46 __sync_fetch_and_and_N
47 __sync_fetch_and_xor_N
48 __sync_fetch_and_nand_N
49 __sync_add_and_fetch_N
50 __sync_sub_and_fetch_N
51 __sync_or_and_fetch_N
52 __sync_and_and_fetch_N
53 __sync_xor_and_fetch_N
54 __sync_nand_and_fetch_N
55 __sync_bool_compare_and_swap_N
56 __sync_val_compare_and_swap_N
57 __sync_lock_test_and_set_N
58
59 SIZE can be 1, 2, 4, 8 or 16. __foo_N is omitted if the target does
60 not provide __sync_compare_and_swap_N.
61
62 Note that __sync_lock_release does not fall back on external
63 __sync_lock_release_N functions. The default implementation
64 of __sync_lock_release is a call to __sync_synchronize followed
65 by a store of zero, so we don't need separate library functions
66 for it. */
67
68#if defined FN
69
16022041
RS
70/* Define functions called __sync_<NAME>_<UNITS>, with one macro per
71 signature. TYPE is a type that has UNITS bytes. */
f92518d7
RS
72
73#define DEFINE_V_PV(NAME, UNITS, TYPE) \
16022041
RS
74 TYPE \
75 __##NAME##_##UNITS (TYPE *ptr, TYPE value) \
f92518d7
RS
76 { \
77 return __##NAME (ptr, value); \
78 }
79
16022041
RS
80#define DEFINE_V_PVV(NAME, UNITS, TYPE) \
81 TYPE \
82 __##NAME##_##UNITS (TYPE *ptr, TYPE value1, TYPE value2) \
f92518d7
RS
83 { \
84 return __##NAME (ptr, value1, value2); \
85 }
86
87#define DEFINE_BOOL_PVV(NAME, UNITS, TYPE) \
16022041
RS
88 _Bool \
89 __##NAME##_##UNITS (TYPE *ptr, TYPE value1, TYPE value2) \
f92518d7
RS
90 { \
91 return __##NAME (ptr, value1, value2); \
92 }
93
94/* Map function names to the appropriate DEFINE_* macro. */
95
96#define local_sync_fetch_and_add DEFINE_V_PV
97#define local_sync_fetch_and_sub DEFINE_V_PV
98#define local_sync_fetch_and_or DEFINE_V_PV
99#define local_sync_fetch_and_and DEFINE_V_PV
100#define local_sync_fetch_and_xor DEFINE_V_PV
101#define local_sync_fetch_and_nand DEFINE_V_PV
102
103#define local_sync_add_and_fetch DEFINE_V_PV
104#define local_sync_sub_and_fetch DEFINE_V_PV
105#define local_sync_or_and_fetch DEFINE_V_PV
106#define local_sync_and_and_fetch DEFINE_V_PV
107#define local_sync_xor_and_fetch DEFINE_V_PV
108#define local_sync_nand_and_fetch DEFINE_V_PV
109
110#define local_sync_bool_compare_and_swap DEFINE_BOOL_PVV
111#define local_sync_val_compare_and_swap DEFINE_V_PVV
112
113#define local_sync_lock_test_and_set DEFINE_V_PV
114
115/* Define the function __<NAME>_<UNITS>, given that TYPE is a type with
116 UNITS bytes. */
117#define DEFINE1(NAME, UNITS, TYPE) \
118 static int unused[sizeof (TYPE) == UNITS ? 1 : -1] \
119 __attribute__((unused)); \
16022041 120 local_##NAME (NAME, UNITS, TYPE);
f92518d7
RS
121
122/* As above, but performing macro expansion on the arguments. */
123#define DEFINE(NAME, UNITS, TYPE) DEFINE1 (NAME, UNITS, TYPE)
124
125/* Find an appropriate type TYPE for SIZE and invoke DEFINE (FN, SIZE, TYPE).
126
127 The types chosen here may be incorrect for some targets.
128 For example, targets with 16-byte atomicity support might not
129 support OImode. We would need some kind of target-specific
130 override if that becomes a problem. */
131
132#if SIZE == 1 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1
133
134typedef unsigned int UQItype __attribute__((mode (QI)));
135DEFINE (FN, 1, UQItype)
136
137#elif SIZE == 2 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2
138
139typedef unsigned int UHItype __attribute__((mode (HI)));
140DEFINE (FN, 2, UHItype)
141
142#elif SIZE == 4 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
143
144typedef unsigned int USItype __attribute__((mode (SI)));
145DEFINE (FN, 4, USItype)
146
147#elif SIZE == 8 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8
148
149typedef unsigned int UDItype __attribute__((mode (DI)));
150DEFINE (FN, 8, UDItype)
151
152#elif SIZE == 16 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16
153
154typedef unsigned int UOItype __attribute__((mode (OI)));
155DEFINE (FN, 8, UOItype)
156
157#endif
158
159#elif __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 \
160 || __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 \
161 || __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 \
162 || __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 \
163 || __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16
164
165#if defined Lsync_synchronize
166
16022041
RS
167void
168__sync_synchronize (void)
f92518d7
RS
169{
170 __sync_synchronize ();
171}
f92518d7
RS
172
173#endif
174
175#endif