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