diff options
Diffstat (limited to 'libgcc')
-rw-r--r-- | libgcc/ChangeLog | 34 | ||||
-rw-r--r-- | libgcc/Makefile.in | 5 | ||||
-rw-r--r-- | libgcc/libgcc2.c | 23 | ||||
-rw-r--r-- | libgcc/libgcc2.h | 14 | ||||
-rw-r--r-- | libgcc/libgcov-profiler.c | 23 | ||||
-rw-r--r-- | libgcc/unwind-dw2-fde.c | 41 |
6 files changed, 125 insertions, 15 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index d5ecf7776a7..b5c7ea4a9af 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,37 @@ +2016-09-16 Jakub Jelinek <jakub@redhat.com> + + PR libgcc/71744 + * unwind-dw2-fde.c (ATOMIC_FDE_FAST_PATH): Define if __register_frame* + is not the primary registry and atomics are available. + (any_objects_registered): New variable. + (__register_frame_info_bases, __register_frame_info_table_bases): + Atomically store 1 to any_objects_registered after registering first + unwind info. + (_Unwind_Find_FDE): Return early if any_objects_registered is 0. + +2016-09-09 James Greenhalgh <james.greenhalgh@arm.com> + + PR target/63250 + * Makefile.in (lib2funcs): Build _mulhc3 and _divhc3. + * libgcc2.h (LIBGCC_HAS_HF_MODE): Conditionally define. + (HFtype): Likewise. + (HCtype): Likewise. + (__divhc3): Likewise. + (__mulhc3): Likewise. + * libgcc2.c: Support _mulhc3 and _divhc3. + +2016-09-07 Joseph Myers <joseph@codesourcery.com> + + PR libgcc/77519 + * libgcc2.c (NOTRUNC): Invert settings. + +2016-09-06 Martin Liska <mliska@suse.cz> + + PR gcov-profile/77378 + PR gcov-profile/77466 + * libgcov-profiler.c: Use __GCC_HAVE_SYNC_COMPARE_AND_SWAP_{4,8} to + conditionaly enable/disable *_atomic functions. + 2016-08-26 Joseph Myers <joseph@codesourcery.com> * config.host (i[34567]86-*-* | x86_64-*-*): Enable TFmode soft-fp diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in index ba37c657baf..53e3ea20b12 100644 --- a/libgcc/Makefile.in +++ b/libgcc/Makefile.in @@ -414,8 +414,9 @@ lib2funcs = _muldi3 _negdi2 _lshrdi3 _ashldi3 _ashrdi3 _cmpdi2 _ucmpdi2 \ _negvsi2 _negvdi2 _ctors _ffssi2 _ffsdi2 _clz _clzsi2 _clzdi2 \ _ctzsi2 _ctzdi2 _popcount_tab _popcountsi2 _popcountdi2 \ _paritysi2 _paritydi2 _powisf2 _powidf2 _powixf2 _powitf2 \ - _mulsc3 _muldc3 _mulxc3 _multc3 _divsc3 _divdc3 _divxc3 \ - _divtc3 _bswapsi2 _bswapdi2 _clrsbsi2 _clrsbdi2 + _mulhc3 _mulsc3 _muldc3 _mulxc3 _multc3 _divhc3 _divsc3 \ + _divdc3 _divxc3 _divtc3 _bswapsi2 _bswapdi2 _clrsbsi2 \ + _clrsbdi2 # The floating-point conversion routines that involve a single-word integer. # XX stands for the integer mode. diff --git a/libgcc/libgcc2.c b/libgcc/libgcc2.c index 0a716bf7b8f..9fb150b2dd5 100644 --- a/libgcc/libgcc2.c +++ b/libgcc/libgcc2.c @@ -1852,7 +1852,8 @@ NAME (TYPE x, int m) #endif -#if ((defined(L_mulsc3) || defined(L_divsc3)) && LIBGCC2_HAS_SF_MODE) \ +#if((defined(L_mulhc3) || defined(L_divhc3)) && LIBGCC2_HAS_HF_MODE) \ + || ((defined(L_mulsc3) || defined(L_divsc3)) && LIBGCC2_HAS_SF_MODE) \ || ((defined(L_muldc3) || defined(L_divdc3)) && LIBGCC2_HAS_DF_MODE) \ || ((defined(L_mulxc3) || defined(L_divxc3)) && LIBGCC2_HAS_XF_MODE) \ || ((defined(L_multc3) || defined(L_divtc3)) && LIBGCC2_HAS_TF_MODE) @@ -1861,30 +1862,36 @@ NAME (TYPE x, int m) #undef double #undef long -#if defined(L_mulsc3) || defined(L_divsc3) +#if defined(L_mulhc3) || defined(L_divhc3) +# define MTYPE HFtype +# define CTYPE HCtype +# define MODE hc +# define CEXT __LIBGCC_HF_FUNC_EXT__ +# define NOTRUNC (!__LIBGCC_HF_EXCESS_PRECISION__) +#elif defined(L_mulsc3) || defined(L_divsc3) # define MTYPE SFtype # define CTYPE SCtype # define MODE sc # define CEXT __LIBGCC_SF_FUNC_EXT__ -# define NOTRUNC __LIBGCC_SF_EXCESS_PRECISION__ +# define NOTRUNC (!__LIBGCC_SF_EXCESS_PRECISION__) #elif defined(L_muldc3) || defined(L_divdc3) # define MTYPE DFtype # define CTYPE DCtype # define MODE dc # define CEXT __LIBGCC_DF_FUNC_EXT__ -# define NOTRUNC __LIBGCC_DF_EXCESS_PRECISION__ +# define NOTRUNC (!__LIBGCC_DF_EXCESS_PRECISION__) #elif defined(L_mulxc3) || defined(L_divxc3) # define MTYPE XFtype # define CTYPE XCtype # define MODE xc # define CEXT __LIBGCC_XF_FUNC_EXT__ -# define NOTRUNC __LIBGCC_XF_EXCESS_PRECISION__ +# define NOTRUNC (!__LIBGCC_XF_EXCESS_PRECISION__) #elif defined(L_multc3) || defined(L_divtc3) # define MTYPE TFtype # define CTYPE TCtype # define MODE tc # define CEXT __LIBGCC_TF_FUNC_EXT__ -# define NOTRUNC __LIBGCC_TF_EXCESS_PRECISION__ +# define NOTRUNC (!__LIBGCC_TF_EXCESS_PRECISION__) #else # error #endif @@ -1922,7 +1929,7 @@ extern void *compile_type_assert[sizeof(INFINITY) == sizeof(MTYPE) ? 1 : -1]; # define TRUNC(x) __asm__ ("" : "=m"(x) : "m"(x)) #endif -#if defined(L_mulsc3) || defined(L_muldc3) \ +#if defined(L_mulhc3) || defined(L_mulsc3) || defined(L_muldc3) \ || defined(L_mulxc3) || defined(L_multc3) CTYPE @@ -1992,7 +1999,7 @@ CONCAT3(__mul,MODE,3) (MTYPE a, MTYPE b, MTYPE c, MTYPE d) } #endif /* complex multiply */ -#if defined(L_divsc3) || defined(L_divdc3) \ +#if defined(L_divhc3) || defined(L_divsc3) || defined(L_divdc3) \ || defined(L_divxc3) || defined(L_divtc3) CTYPE diff --git a/libgcc/libgcc2.h b/libgcc/libgcc2.h index 72bb873ac33..c46fb77a6ec 100644 --- a/libgcc/libgcc2.h +++ b/libgcc/libgcc2.h @@ -34,6 +34,12 @@ extern void __clear_cache (char *, char *); extern void __eprintf (const char *, const char *, unsigned int, const char *) __attribute__ ((__noreturn__)); +#ifdef __LIBGCC_HAS_HF_MODE__ +#define LIBGCC2_HAS_HF_MODE 1 +#else +#define LIBGCC2_HAS_HF_MODE 0 +#endif + #ifdef __LIBGCC_HAS_SF_MODE__ #define LIBGCC2_HAS_SF_MODE 1 #else @@ -133,6 +139,10 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); #endif #endif +#if LIBGCC2_HAS_HF_MODE +typedef float HFtype __attribute__ ((mode (HF))); +typedef _Complex float HCtype __attribute__ ((mode (HC))); +#endif #if LIBGCC2_HAS_SF_MODE typedef float SFtype __attribute__ ((mode (SF))); typedef _Complex float SCtype __attribute__ ((mode (SC))); @@ -424,6 +434,10 @@ extern SItype __negvsi2 (SItype); #endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */ #undef int +#if LIBGCC2_HAS_HF_MODE +extern HCtype __divhc3 (HFtype, HFtype, HFtype, HFtype); +extern HCtype __mulhc3 (HFtype, HFtype, HFtype, HFtype); +#endif #if LIBGCC2_HAS_SF_MODE extern DWtype __fixsfdi (SFtype); extern SFtype __floatdisf (DWtype); diff --git a/libgcc/libgcov-profiler.c b/libgcc/libgcov-profiler.c index 70a821dc625..d9217b9885b 100644 --- a/libgcc/libgcov-profiler.c +++ b/libgcc/libgcov-profiler.c @@ -26,6 +26,17 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #include "libgcov.h" #if !defined(inhibit_libc) +/* Detect whether target can support atomic update of profilers. */ +#if __SIZEOF_LONG_LONG__ == 4 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 +#define GCOV_SUPPORTS_ATOMIC 1 +#else +#if __SIZEOF_LONG_LONG__ == 8 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 +#define GCOV_SUPPORTS_ATOMIC 1 +#else +#define GCOV_SUPPORTS_ATOMIC 0 +#endif +#endif + #ifdef L_gcov_interval_profiler /* If VALUE is in interval <START, START + STEPS - 1>, then increases the corresponding counter in COUNTERS. If the VALUE is above or below @@ -46,7 +57,7 @@ __gcov_interval_profiler (gcov_type *counters, gcov_type value, } #endif -#ifdef L_gcov_interval_profiler_atomic +#if defined(L_gcov_interval_profiler_atomic) && GCOV_SUPPORTS_ATOMIC /* If VALUE is in interval <START, START + STEPS - 1>, then increases the corresponding counter in COUNTERS. If the VALUE is above or below the interval, COUNTERS[STEPS] or COUNTERS[STEPS + 1] is increased @@ -80,7 +91,7 @@ __gcov_pow2_profiler (gcov_type *counters, gcov_type value) } #endif -#ifdef L_gcov_pow2_profiler_atomic +#if defined(L_gcov_pow2_profiler_atomic) && GCOV_SUPPORTS_ATOMIC /* If VALUE is a power of two, COUNTERS[1] is incremented. Otherwise COUNTERS[0] is incremented. Function is thread-safe. */ @@ -134,7 +145,7 @@ __gcov_one_value_profiler (gcov_type *counters, gcov_type value) } #endif -#ifdef L_gcov_one_value_profiler_atomic +#if defined(L_gcov_one_value_profiler_atomic) && GCOV_SUPPORTS_ATOMIC /* Update one value profilers (COUNTERS) for a given VALUE. @@ -342,6 +353,7 @@ __gcov_time_profiler (gcov_type* counters) counters[0] = ++function_counter; } +#if GCOV_SUPPORTS_ATOMIC /* Sets corresponding COUNTERS if there is no value. Function is thread-safe. */ @@ -352,6 +364,7 @@ __gcov_time_profiler_atomic (gcov_type* counters) counters[0] = __atomic_add_fetch (&function_counter, 1, MEMMODEL_RELAXED); } #endif +#endif #ifdef L_gcov_average_profiler @@ -366,7 +379,7 @@ __gcov_average_profiler (gcov_type *counters, gcov_type value) } #endif -#ifdef L_gcov_average_profiler_atomic +#if defined(L_gcov_average_profiler_atomic) && GCOV_SUPPORTS_ATOMIC /* Increase corresponding COUNTER by VALUE. FIXME: Perhaps we want to saturate up. Function is thread-safe. */ @@ -388,7 +401,7 @@ __gcov_ior_profiler (gcov_type *counters, gcov_type value) } #endif -#ifdef L_gcov_ior_profiler_atomic +#if defined(L_gcov_ior_profiler_atomic) && GCOV_SUPPORTS_ATOMIC /* Bitwise-OR VALUE into COUNTER. Function is thread-safe. */ void diff --git a/libgcc/unwind-dw2-fde.c b/libgcc/unwind-dw2-fde.c index 5b16a1f87e2..be82f65b916 100644 --- a/libgcc/unwind-dw2-fde.c +++ b/libgcc/unwind-dw2-fde.c @@ -35,6 +35,11 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #include "unwind-pe.h" #include "unwind-dw2-fde.h" #include "gthr.h" +#else +#if (defined(__GTHREAD_MUTEX_INIT) || defined(__GTHREAD_MUTEX_INIT_FUNCTION)) \ + && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) +#define ATOMIC_FDE_FAST_PATH 1 +#endif #endif /* The unseen_objects list contains objects that have been registered @@ -43,6 +48,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see by decreasing value of pc_begin. */ static struct object *unseen_objects; static struct object *seen_objects; +#ifdef ATOMIC_FDE_FAST_PATH +static int any_objects_registered; +#endif #ifdef __GTHREAD_MUTEX_INIT static __gthread_mutex_t object_mutex = __GTHREAD_MUTEX_INIT; @@ -96,6 +104,16 @@ __register_frame_info_bases (const void *begin, struct object *ob, ob->next = unseen_objects; unseen_objects = ob; +#ifdef ATOMIC_FDE_FAST_PATH + /* Set flag that at least one library has registered FDEs. + Use relaxed MO here, it is up to the app to ensure that the library + loading/initialization happens-before using that library in other + threads (in particular unwinding with that library's functions + appearing in the backtraces). Calling that library's functions + without waiting for the library to initialize would be racy. */ + if (!any_objects_registered) + __atomic_store_n (&any_objects_registered, 1, __ATOMIC_RELAXED); +#endif __gthread_mutex_unlock (&object_mutex); } @@ -140,6 +158,16 @@ __register_frame_info_table_bases (void *begin, struct object *ob, ob->next = unseen_objects; unseen_objects = ob; +#ifdef ATOMIC_FDE_FAST_PATH + /* Set flag that at least one library has registered FDEs. + Use relaxed MO here, it is up to the app to ensure that the library + loading/initialization happens-before using that library in other + threads (in particular unwinding with that library's functions + appearing in the backtraces). Calling that library's functions + without waiting for the library to initialize would be racy. */ + if (!any_objects_registered) + __atomic_store_n (&any_objects_registered, 1, __ATOMIC_RELAXED); +#endif __gthread_mutex_unlock (&object_mutex); } @@ -1001,6 +1029,19 @@ _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases) struct object *ob; const fde *f = NULL; +#ifdef ATOMIC_FDE_FAST_PATH + /* For targets where unwind info is usually not registered through these + APIs anymore, avoid taking a global lock. + Use relaxed MO here, it is up to the app to ensure that the library + loading/initialization happens-before using that library in other + threads (in particular unwinding with that library's functions + appearing in the backtraces). Calling that library's functions + without waiting for the library to initialize would be racy. */ + if (__builtin_expect (!__atomic_load_n (&any_objects_registered, + __ATOMIC_RELAXED), 1)) + return NULL; +#endif + init_object_mutex_once (); __gthread_mutex_lock (&object_mutex); |