annotate libgcc/sync.c @ 158:494b0b89df80 default tip

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