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