aboutsummaryrefslogtreecommitdiff
path: root/libgcc
diff options
context:
space:
mode:
Diffstat (limited to 'libgcc')
-rw-r--r--libgcc/ChangeLog34
-rw-r--r--libgcc/Makefile.in5
-rw-r--r--libgcc/libgcc2.c23
-rw-r--r--libgcc/libgcc2.h14
-rw-r--r--libgcc/libgcov-profiler.c23
-rw-r--r--libgcc/unwind-dw2-fde.c41
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);