aboutsummaryrefslogtreecommitdiff
path: root/libgcc
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2018-06-07 18:05:45 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2018-06-07 18:05:45 +0000
commitce311a8cae4489058f8601bebdf511b7fb5fce26 (patch)
tree81494302b4f5708ad6c96bad6ecfd9c109574c38 /libgcc
parent48ec607c1f8d1f1783850f1d2729fd23716b1b1b (diff)
parentdc23fb4d72eed9ea09fbf4704b26e0e36414a57a (diff)
downloadgcc-ce311a8cae4489058f8601bebdf511b7fb5fce26.zip
gcc-ce311a8cae4489058f8601bebdf511b7fb5fce26.tar.gz
gcc-ce311a8cae4489058f8601bebdf511b7fb5fce26.tar.bz2
Merge from trunk revision 261284.
From-SVN: r261288
Diffstat (limited to 'libgcc')
-rw-r--r--libgcc/ChangeLog281
-rw-r--r--libgcc/config.host26
-rw-r--r--libgcc/config.in7
-rw-r--r--libgcc/config/arm/cmse.c5
-rw-r--r--libgcc/config/arm/freebsd-atomic.c22
-rw-r--r--libgcc/config/arm/libunwind.S4
-rw-r--r--libgcc/config/i386/cpuinfo.c195
-rw-r--r--libgcc/config/i386/cpuinfo.h14
-rw-r--r--libgcc/config/i386/cygwin.S26
-rw-r--r--libgcc/config/i386/i386-asm.h32
-rw-r--r--libgcc/config/i386/linux-unwind.h2
-rw-r--r--libgcc/config/i386/morestack.S1
-rw-r--r--libgcc/config/i386/resms64fx.h5
-rw-r--r--libgcc/config/i386/resms64x.h4
-rw-r--r--libgcc/config/i386/shadow-stack-unwind.h7
-rw-r--r--libgcc/config/m68k/lb1sf68.S4
-rw-r--r--libgcc/config/nds32/linux-atomic.c282
-rw-r--r--libgcc/config/nds32/linux-unwind.h156
-rw-r--r--libgcc/config/nds32/sfp-machine.h19
-rw-r--r--libgcc/config/nds32/t-nds32-newlib2
-rw-r--r--libgcc/config/pa/fptr.c20
-rw-r--r--libgcc/config/riscv/save-restore.S46
-rw-r--r--libgcc/config/rs6000/_powikf2.c63
-rw-r--r--libgcc/config/rs6000/float128-ifunc.c9
-rw-r--r--libgcc/config/rs6000/quad-float128.h3
-rw-r--r--libgcc/config/rs6000/t-crtstuff2
-rw-r--r--libgcc/config/rs6000/t-float1282
-rw-r--r--libgcc/config/rs6000/t-float128-hw8
-rw-r--r--libgcc/config/t-vxworks4
-rw-r--r--libgcc/config/t-vxworks78
-rw-r--r--libgcc/configure49
-rw-r--r--libgcc/configure.ac18
-rw-r--r--libgcc/crtstuff.c3
-rw-r--r--libgcc/libgcov-driver-system.c108
-rw-r--r--libgcc/libgcov-driver.c210
-rw-r--r--libgcc/libgcov-util.c97
-rw-r--r--libgcc/unwind-generic.h3
-rw-r--r--libgcc/unwind.inc4
38 files changed, 1430 insertions, 321 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index 0e9e775..fc24d8e 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,283 @@
+2018-06-07 Olivier Hainque <hainque@adacore.com>
+
+ * config/t-vxworks (LIBGCC_INCLUDES): Add
+ -I$(MULTIBUILDTOP)../../gcc/include.
+ * config/t-vxworks7: Likewise. Reformat a bit to match
+ the t-vxworks layout.
+
+2018-06-07 Olga Makhotina <olga.makhotina@intel.com>
+
+ * config/i386/cpuinfo.h (processor_types): Add INTEL_TREMONT.
+
+2018-06-07 Martin Liska <mliska@suse.cz>
+
+ * libgcov-driver.c: Rename cs_all to all and assign it from
+ all_prg.
+
+2018-06-07 Martin Liska <mliska@suse.cz>
+
+ PR bootstrap/86057
+ * libgcov-driver-system.c (replace_filename_variables): Use
+ memcpy instead of mempcpy.
+ (allocate_filename_struct): Do not allocate filename, allocate
+ prefix and set it.
+ (gcov_exit_open_gcda_file): Allocate memory for gf->filename
+ here and properly copy content into it.
+ * libgcov-driver.c (struct gcov_filename): Remove max_length
+ field, change prefix from size_t into char *.
+ (compute_summary): Do not calculate longest filename.
+ (gcov_do_dump): Release memory of gf.filename after each file.
+ * libgcov-util.c (compute_summary): Use new signature of
+ compute_summary.
+ (calculate_overlap): Likewise.
+
+2018-06-05 Martin Liska <mliska@suse.cz>
+
+ PR gcov-profile/47618
+ * libgcov-driver-system.c (replace_filename_variables): New
+ function.
+ (gcov_exit_open_gcda_file): Use it.
+
+2018-06-05 Martin Liska <mliska@suse.cz>
+
+ * libgcov-driver.c (gcov_compute_histogram): Remove usage
+ of gcov_ctr_summary.
+ (compute_summary): Do it just for a single summary.
+ (merge_one_data): Likewise.
+ (merge_summary): Simplify as we read just single summary.
+ (dump_one_gcov): Pass proper argument.
+ * libgcov-util.c (compute_one_gcov): Simplify as we have just
+ single summary.
+ (gcov_info_count_all_cold): Likewise.
+ (calculate_overlap): Likewise.
+
+2018-06-02 Chung-Ju Wu <jasonwucj@gmail.com>
+ Monk Chiang <sh.chiang04@gmail.com>
+
+ * config.host (nds32*-linux*): New.
+ * config/nds32/linux-atomic.c: New file.
+ * config/nds32/linux-unwind.h: New file.
+
+2018-05-31 Uros Bizjak <ubizjak@gmail.com>
+
+ PR target/85591
+ * config/i386/cpuinfo.c (get_amd_cpu): Return
+ AMDFAM15H_BDVER2 for AMDFAM15H model 0x2.
+
+2018-05-30 Rasmus Villemoes <rasmus.villemoes@prevas.dk>
+
+ * crtstuff.c: Remove declaration of _Jv_RegisterClasses.
+
+2018-05-29 Martin Liska <mliska@suse.cz>
+
+ PR gcov-profile/85759
+ * libgcov-driver-system.c (gcov_error): Introduce usage of
+ GCOV_EXIT_AT_ERROR env. variable.
+ * libgcov-driver.c (merge_one_data): Print error that we
+ overwrite a gcov file with a different timestamp.
+
+2018-05-23 Kalamatee <kalamatee@gmail.com>
+
+ * config/m68k/lb1sf68.S (Laddsf$nf): Fix sign bit handling in
+ path to Lf$finfty.
+
+2018-05-18 Kito Cheng <kito.cheng@gmail.com>
+ Monk Chiang <sh.chiang04@gmail.com>
+ Jim Wilson <jimw@sifive.com>
+
+ * config/riscv/save-restore.S: Add support for rv32e.
+
+2018-05-18 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/arm/libunwind.S: Update comment relating to armv5.
+
+2018-05-17 Jerome Lambourg <lambourg@adacore.com>
+
+ * config/arm/cmse.c (cmse_check_address_range): Replace
+ UINTPTR_MAX with __UINTPTR_MAX__ and uintptr_t with __UINTPTR_TYPE__.
+
+2018-05-17 Olga Makhotina <olga.makhotina@intel.com>
+
+ * config/i386/cpuinfo.h (processor_types): Add INTEL_GOLDMONT_PLUS.
+ * config/i386/cpuinfo.c (get_intel_cpu): Detect Goldmont Plus.
+
+2018-05-08 Olga Makhotina <olga.makhotina@intel.com>
+
+ * config/i386/cpuinfo.h (processor_types): Add INTEL_GOLDMONT.
+ * config/i386/cpuinfo.c (get_intel_cpu): Detect Goldmont.
+
+2018-05-07 Amaan Cheval <amaan.cheval@gmail.com>
+
+ * config.host (x86_64-*-rtems*): Build crti.o and crtn.o.
+
+2018-04-27 Andreas Tobler <andreast@gcc.gnu.org>
+ Maryse Levavasseur <maryse.levavasseur@stormshield.eu>
+
+ PR libgcc/84292
+ * config/arm/freebsd-atomic.c (SYNC_OP_AND_FETCH_N): Fix the
+ op_and_fetch to return the right result.
+
+2018-04-27 Alan Modra <amodra@gmail.com>
+
+ PR libgcc/85532
+ * config/rs6000/t-crtstuff (CRTSTUFF_T_CFLAGS): Add
+ -fno-asynchronous-unwind-tables.
+
+2018-04-25 Chung-Ju Wu <jasonwucj@gmail.com>
+
+ * config/nds32/sfp-machine.h: Fix settings for NDS32_ABI_2FP_PLUS.
+ * config/nds32/t-nds32-newlib (HOST_LIBGCC2_CFLAGS): Use -fwrapv.
+
+2018-04-24 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/i386/linux-unwind.h: Add (__CET__ & 2) != 0 check
+ when including "config/i386/shadow-stack-unwind.h".
+
+2018-04-24 H.J. Lu <hongjiu.lu@intel.com>
+
+ * configure: Regenerated.
+
+2018-04-20 Michael Meissner <meissner@linux.ibm.com>
+
+ PR target/85456
+ * config/rs6000/_powikf2.c: New file. Add support for the
+ __builtin_powil function when long double is IEEE 128-bit floating
+ point.
+ * config/rs6000/float128-ifunc.c (__powikf2_resolve): Add
+ __powikf2 support.
+ (__powikf2): Likewise.
+ * config/rs6000/quad-float128.h (__powikf2_sw): Likewise.
+ (__powikf2_hw): Likewise.
+ (__powikf2): Likewise.
+ * config/rs6000/t-float128 (fp128_ppc_funcs): Likewise.
+ * config/rs6000/t-float128-hw (fp128_hw_func): Likewise.
+ (_powikf2-hw.c): Likewise.
+
+2018-04-19 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR libgcc/85334
+ * unwind-generic.h (_Unwind_Frames_Increment): New.
+ * config/i386/shadow-stack-unwind.h (_Unwind_Frames_Increment):
+ Likewise.
+ * unwind.inc (_Unwind_RaiseException_Phase2): Increment frame
+ count with _Unwind_Frames_Increment.
+ (_Unwind_ForcedUnwind_Phase2): Likewise.
+
+2018-04-19 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR libgcc/85379
+ * config/i386/morestack.S (__stack_split_initialize): Add
+ _CET_ENDBR.
+
+2018-04-19 Jakub Jelinek <jakub@redhat.com>
+
+ * configure: Regenerated.
+
+2018-04-18 David Malcolm <dmalcolm@redhat.com>
+
+ PR jit/85384
+ * configure: Regenerate.
+
+2018-04-16 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/84945
+ * config/i386/cpuinfo.c (set_feature): Wrap into do while (0) to avoid
+ -Wdangling-else warnings. Mask shift counts to avoid
+ -Wshift-count-negative and -Wshift-count-overflow false positives.
+
+2018-04-06 Ruslan Bukin <br@bsdpad.com>
+
+ * config.host (riscv*-*-freebsd*): Add RISC-V FreeBSD support.
+
+2018-03-29 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/85100
+ * config/i386/cpuinfo.c (XCR_XFEATURE_ENABLED_MASK): New.
+ (XSTATE_FP): Likewise.
+ (XSTATE_SSE): Likewise.
+ (XSTATE_YMM): Likewise.
+ (XSTATE_OPMASK): Likewise.
+ (XSTATE_ZMM): Likewise.
+ (XSTATE_HI_ZMM): Likewise.
+ (XCR_AVX_ENABLED_MASK): Likewise.
+ (XCR_AVX512F_ENABLED_MASK): Likewise.
+ (get_available_features): Enable AVX and AVX512 features only
+ if their states are supported by OSXSAVE.
+
+2018-03-22 Igor Tsimbalist <igor.v.tsimbalist@intel.com>
+
+ PR target/85025
+ * config/i386/shadow-stack-unwind.h (_Unwind_Frames_Extra):
+ Fix a typo, tmp => 255.
+
+2018-03-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/84945
+ * config/i386/cpuinfo.h (__cpu_features2): Declare.
+ * config/i386/cpuinfo.c (__cpu_features2): New variable for
+ ifndef SHARED only.
+ (set_feature): Define.
+ (get_available_features): Use set_feature macro. Set __cpu_features2
+ to the second word of features ifndef SHARED.
+
+2018-03-15 Julia Koval <julia.koval@intel.com>
+
+ * config/i386/cpuinfo.c (get_available_features): Add
+ FEATURE_AVX512VBMI2, FEATURE_GFNI, FEATURE_VPCLMULQDQ,
+ FEATURE_AVX512VNNI, FEATURE_AVX512BITALG.
+ * config/i386/cpuinfo.h (processor_features): Add FEATURE_AVX512VBMI2,
+ FEATURE_GFNI, FEATURE_VPCLMULQDQ, FEATURE_AVX512VNNI,
+ FEATURE_AVX512BITALG.
+
+2018-03-14 Julia Koval <julia.koval@intel.com>
+
+ * config/i386/cpuinfo.h (processor_subtypes): Split up icelake on
+ icelake client and icelake server.
+
+2018-03-06 John David Anglin <danglin@gcc.gnu.org>
+
+ * config/pa/fptr.c (_dl_read_access_allowed): New.
+ (__canonicalize_funcptr_for_compare): Use it.
+
+2018-02-28 Jakub Jelinek <jakub@redhat.com>
+
+ PR debug/83917
+ * configure.ac (AS_HIDDEN_DIRECTIVE): AC_DEFINE_UNQUOTED this to
+ $asm_hidden_op if visibility ("hidden") attribute works.
+ (HAVE_AS_CFI_SECTIONS): New AC_DEFINE.
+ * config/i386/i386-asm.h: Don't include auto-host.h.
+ (PACKAGE_VERSION, PACKAGE_NAME, PACKAGE_STRING, PACKAGE_TARNAME,
+ PACKAGE_URL): Don't undefine.
+ (USE_GAS_CFI_DIRECTIVES): Don't use nor define this macro, instead
+ guard cfi_startproc only on ifdef __GCC_HAVE_DWARF2_CFI_ASM.
+ (FN_HIDDEN): Change guard from #ifdef HAVE_GAS_HIDDEN to
+ #ifdef AS_HIDDEN_DIRECTIVE, use AS_HIDDEN_DIRECTIVE macro in the
+ definition instead of hardcoded .hidden.
+ * config/i386/cygwin.S: Include i386-asm.h first before .cfi_sections
+ directive. Use #ifdef HAVE_AS_CFI_SECTIONS rather than
+ #ifdef HAVE_GAS_CFI_SECTIONS_DIRECTIVE to guard .cfi_sections.
+ (USE_GAS_CFI_DIRECTIVES): Don't define.
+ * configure: Regenerated.
+ * config.in: Likewise.
+
+2018-02-26 Jakub Jelinek <jakub@redhat.com>
+
+ PR debug/83917
+ * config/i386/i386-asm.h (PACKAGE_VERSION, PACKAGE_NAME,
+ PACKAGE_STRING, PACKAGE_TARNAME, PACKAGE_URL): Undefine between
+ inclusion of auto-target.h and auto-host.h.
+ (USE_GAS_CFI_DIRECTIVES): Define if not defined already based on
+ __GCC_HAVE_DWARF2_CFI_ASM.
+ (cfi_startproc, cfi_endproc, cfi_adjust_cfa_offset,
+ cfi_def_cfa_register, cfi_def_cfa, cfi_register, cfi_offset, cfi_push,
+ cfi_pop): Define.
+ * config/i386/cygwin.S: Don't include auto-host.h here, just
+ define USE_GAS_CFI_DIRECTIVES to 1 or 0 and include i386-asm.h.
+ (cfi_startproc, cfi_endproc, cfi_adjust_cfa_offset,
+ cfi_def_cfa_register, cfi_register, cfi_push, cfi_pop): Remove.
+ * config/i386/resms64fx.h: Add cfi_* directives.
+ * config/i386/resms64x.h: Likewise.
+
2018-02-20 Max Filippov <jcmvbkbc@gmail.com>
* config/xtensa/ieee754-df.S (__adddf3_aux): Add
@@ -365,7 +645,6 @@
* config/i386/t-msabi: Modified to add avx and sse versions of stubs.
2017-09-01 Olivier Hainque <hainque@adacore.com>
-
* config.host (*-*-vxworks7): Widen scope to vxworks7*.
2017-08-31 Olivier Hainque <hainque@adacore.com>
diff --git a/libgcc/config.host b/libgcc/config.host
index 96d55a4..18cabaf 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -611,6 +611,11 @@ i[34567]86-*-elf*)
;;
x86_64-*-elf* | x86_64-*-rtems*)
tmake_file="$tmake_file i386/t-crtstuff t-crtstuff-pic t-libgcc-pic"
+ case ${host} in
+ x86_64-*-rtems*)
+ extra_parts="$extra_parts crti.o crtn.o"
+ ;;
+ esac
;;
x86_64-*-fuchsia*)
tmake_file="$tmake_file t-libgcc-pic"
@@ -974,6 +979,23 @@ msp430*-*-elf)
tmake_file="$tm_file t-crtstuff t-fdpbit msp430/t-msp430"
extra_parts="$extra_parts libmul_none.a libmul_16.a libmul_32.a libmul_f5.a"
;;
+nds32*-linux*)
+ # Basic makefile fragment and extra_parts for crt stuff.
+ # We also append c-isr library implementation.
+ tmake_file="${tmake_file} t-slibgcc-libgcc"
+ tmake_file="${tmake_file} nds32/t-nds32-glibc nds32/t-crtstuff t-softfp-sfdf t-softfp"
+ # The header file of defining MD_FALLBACK_FRAME_STATE_FOR.
+ md_unwind_header=nds32/linux-unwind.h
+ # Append library definition makefile fragment according to --with-nds32-lib=X setting.
+ case "${with_nds32_lib}" in
+ "" | glibc | uclibc )
+ ;;
+ *)
+ echo "Cannot accept --with-nds32-lib=$with_nds32_lib, available values are: glibc uclibc" 1>&2
+ exit 1
+ ;;
+ esac
+ ;;
nds32*-elf*)
# Basic makefile fragment and extra_parts for crt stuff.
# We also append c-isr library implementation.
@@ -1128,6 +1150,10 @@ riscv*-*-linux*)
extra_parts="$extra_parts crtbegin.o crtend.o crti.o crtn.o crtendS.o crtbeginT.o"
md_unwind_header=riscv/linux-unwind.h
;;
+riscv*-*-freebsd*)
+ tmake_file="${tmake_file} riscv/t-softfp${host_address} t-softfp riscv/t-elf riscv/t-elf${host_address}"
+ extra_parts="$extra_parts crtbegin.o crtend.o crti.o crtn.o crtendS.o crtbeginT.o"
+ ;;
riscv*-*-*)
tmake_file="${tmake_file} riscv/t-softfp${host_address} t-softfp riscv/t-elf riscv/t-elf${host_address}"
extra_parts="$extra_parts crtbegin.o crtend.o crti.o crtn.o"
diff --git a/libgcc/config.in b/libgcc/config.in
index f9fb253..d634af9 100644
--- a/libgcc/config.in
+++ b/libgcc/config.in
@@ -1,8 +1,15 @@
/* config.in. Generated from configure.ac by autoheader. */
+/* Define to the .hidden-like directive if it exists. */
+#undef AS_HIDDEN_DIRECTIVE
+
/* Define to 1 if the assembler supports AVX. */
#undef HAVE_AS_AVX
+/* Define to 1 if the assembler supports .cfi_sections .debug_frame directive.
+ */
+#undef HAVE_AS_CFI_SECTIONS
+
/* Define to 1 if the target assembler supports thread-local storage. */
#undef HAVE_CC_TLS
diff --git a/libgcc/config/arm/cmse.c b/libgcc/config/arm/cmse.c
index 3ded385..2ad0af2 100644
--- a/libgcc/config/arm/cmse.c
+++ b/libgcc/config/arm/cmse.c
@@ -36,7 +36,7 @@ cmse_check_address_range (void *p, size_t size, int flags)
char *pb = (char *) p, *pe;
/* Check if the range wraps around. */
- if (UINTPTR_MAX - (uintptr_t) p < size)
+ if (__UINTPTR_MAX__ - (__UINTPTR_TYPE__) p < size)
return NULL;
/* Check if an unknown flag is present. */
@@ -51,7 +51,8 @@ cmse_check_address_range (void *p, size_t size, int flags)
/* Execute the right variant of the TT instructions. */
pe = pb + size - 1;
- const int singleCheck = (((uintptr_t) pb ^ (uintptr_t) pe) < 32);
+ const int singleCheck
+ = (((__UINTPTR_TYPE__) pb ^ (__UINTPTR_TYPE__) pe) < 32);
switch (flags & known_secure_level)
{
case 0:
diff --git a/libgcc/config/arm/freebsd-atomic.c b/libgcc/config/arm/freebsd-atomic.c
index 73a9ac6..77618da 100644
--- a/libgcc/config/arm/freebsd-atomic.c
+++ b/libgcc/config/arm/freebsd-atomic.c
@@ -171,32 +171,32 @@ __sync_fetch_and_##NAME##_##N (TYPE *mem, TYPE val) \
#define SYNC_OP_AND_FETCH_N(N, TYPE, LDR, STR, NAME, OP) \
TYPE HIDDEN \
-__sync_##NAME##_and_fetch_##N (TYPE *mem, TYPE val) \
+__sync_##NAME##_and_fetch_##N (TYPE *mem, TYPE val) \
{ \
- unsigned int old, temp, ras_start; \
+ unsigned int old, temp, ras_start, res; \
\
ras_start = ARM_RAS_START; \
__asm volatile ( \
/* Set up Restartable Atomic Sequence. */ \
"1:" \
"\tadr %2, 1b\n" \
- "\tstr %2, [%5]\n" \
+ "\tstr %2, [%6]\n" \
"\tadr %2, 2f\n" \
- "\tstr %2, [%5, #4]\n" \
+ "\tstr %2, [%6, #4]\n" \
\
- "\t"LDR" %0, %4\n" /* Load old value. */ \
- "\t"OP" %2, %0, %3\n" /* Calculate new value. */ \
- "\t"STR" %2, %1\n" /* Store new value. */ \
+ "\t"LDR" %0, %5\n" /* Load old value. */ \
+ "\t"OP" %3, %0, %4\n" /* Calculate new value. */ \
+ "\t"STR" %3, %1\n" /* Store new value. */ \
\
/* Tear down Restartable Atomic Sequence. */ \
"2:" \
"\tmov %2, #0x00000000\n" \
- "\tstr %2, [%5]\n" \
+ "\tstr %2, [%6]\n" \
"\tmov %2, #0xffffffff\n" \
- "\tstr %2, [%5, #4]\n" \
- : "=&r" (old), "=m" (*mem), "=&r" (temp) \
+ "\tstr %2, [%6, #4]\n" \
+ : "=&r" (old), "=m" (*mem), "=&r" (temp), "=&r" (res) \
: "r" (val), "m" (*mem), "r" (ras_start)); \
- return (old); \
+ return (res); \
}
#define EMIT_ALL_OPS_N(N, TYPE, LDR, STR, STREQ) \
diff --git a/libgcc/config/arm/libunwind.S b/libgcc/config/arm/libunwind.S
index 8d0ef97..3302447 100644
--- a/libgcc/config/arm/libunwind.S
+++ b/libgcc/config/arm/libunwind.S
@@ -47,8 +47,8 @@
.endm
#if (__ARM_ARCH__ == 4)
-/* Some coprocessors require armv5. We know this code will never be run on
- other cpus. Tell gas to allow armv5, but only mark the objects as armv4.
+/* Some coprocessors require armv5t. We know this code will never be run on
+ other cpus. Tell gas to allow armv5t, but only mark the objects as armv4.
*/
.arch armv5t
#ifdef __ARM_ARCH_4T__
diff --git a/libgcc/config/i386/cpuinfo.c b/libgcc/config/i386/cpuinfo.c
index a8821af..a7bb9da 100644
--- a/libgcc/config/i386/cpuinfo.c
+++ b/libgcc/config/i386/cpuinfo.c
@@ -39,6 +39,13 @@ int __cpu_indicator_init (void)
struct __processor_model __cpu_model = { };
+#ifndef SHARED
+/* We want to move away from __cpu_model in libgcc_s.so.1 and the
+ size of __cpu_model is part of ABI. So, new features that don't
+ fit into __cpu_model.__cpu_features[0] go into extra variables
+ in libgcc.a only, preferrably hidden. */
+unsigned int __cpu_features2;
+#endif
/* Get the specific type of AMD CPU. */
@@ -76,17 +83,20 @@ get_amd_cpu (unsigned int family, unsigned int model)
/* AMD Family 15h "Bulldozer". */
case 0x15:
__cpu_model.__cpu_type = AMDFAM15H;
+
+ if (model == 0x2)
+ __cpu_model.__cpu_subtype = AMDFAM15H_BDVER2;
/* Bulldozer version 1. */
- if ( model <= 0xf)
+ else if (model <= 0xf)
__cpu_model.__cpu_subtype = AMDFAM15H_BDVER1;
/* Bulldozer version 2 "Piledriver" */
- if (model >= 0x10 && model <= 0x2f)
+ else if (model <= 0x2f)
__cpu_model.__cpu_subtype = AMDFAM15H_BDVER2;
/* Bulldozer version 3 "Steamroller" */
- if (model >= 0x30 && model <= 0x4f)
+ else if (model <= 0x4f)
__cpu_model.__cpu_subtype = AMDFAM15H_BDVER3;
/* Bulldozer version 4 "Excavator" */
- if (model >= 0x60 && model <= 0x7f)
+ else if (model <= 0x7f)
__cpu_model.__cpu_subtype = AMDFAM15H_BDVER4;
break;
/* AMD Family 16h "btver2" */
@@ -133,6 +143,15 @@ get_intel_cpu (unsigned int family, unsigned int model, unsigned int brand_id)
/* Silvermont. */
__cpu_model.__cpu_type = INTEL_SILVERMONT;
break;
+ case 0x5c:
+ case 0x5f:
+ /* Goldmont. */
+ __cpu_model.__cpu_type = INTEL_GOLDMONT;
+ break;
+ case 0x7a:
+ /* Goldmont Plus. */
+ __cpu_model.__cpu_type = INTEL_GOLDMONT_PLUS;
+ break;
case 0x57:
/* Knights Landing. */
__cpu_model.__cpu_type = INTEL_KNL;
@@ -231,68 +250,132 @@ get_available_features (unsigned int ecx, unsigned int edx,
unsigned int ext_level;
unsigned int features = 0;
+ unsigned int features2 = 0;
+
+ /* Get XCR_XFEATURE_ENABLED_MASK register with xgetbv. */
+#define XCR_XFEATURE_ENABLED_MASK 0x0
+#define XSTATE_FP 0x1
+#define XSTATE_SSE 0x2
+#define XSTATE_YMM 0x4
+#define XSTATE_OPMASK 0x20
+#define XSTATE_ZMM 0x40
+#define XSTATE_HI_ZMM 0x80
+
+#define XCR_AVX_ENABLED_MASK \
+ (XSTATE_SSE | XSTATE_YMM)
+#define XCR_AVX512F_ENABLED_MASK \
+ (XSTATE_SSE | XSTATE_YMM | XSTATE_OPMASK | XSTATE_ZMM | XSTATE_HI_ZMM)
+
+ /* Check if AVX and AVX512 are usable. */
+ int avx_usable = 0;
+ int avx512_usable = 0;
+ if ((ecx & bit_OSXSAVE))
+ {
+ /* Check if XMM, YMM, OPMASK, upper 256 bits of ZMM0-ZMM15 and
+ ZMM16-ZMM31 states are supported by OSXSAVE. */
+ unsigned int xcrlow;
+ unsigned int xcrhigh;
+ asm (".byte 0x0f, 0x01, 0xd0"
+ : "=a" (xcrlow), "=d" (xcrhigh)
+ : "c" (XCR_XFEATURE_ENABLED_MASK));
+ if ((xcrlow & XCR_AVX_ENABLED_MASK) == XCR_AVX_ENABLED_MASK)
+ {
+ avx_usable = 1;
+ avx512_usable = ((xcrlow & XCR_AVX512F_ENABLED_MASK)
+ == XCR_AVX512F_ENABLED_MASK);
+ }
+ }
+
+#define set_feature(f) \
+ do \
+ { \
+ if (f < 32) \
+ features |= (1U << (f & 31)); \
+ else \
+ features2 |= (1U << ((f - 32) & 31)); \
+ } \
+ while (0)
if (edx & bit_CMOV)
- features |= (1 << FEATURE_CMOV);
+ set_feature (FEATURE_CMOV);
if (edx & bit_MMX)
- features |= (1 << FEATURE_MMX);
+ set_feature (FEATURE_MMX);
if (edx & bit_SSE)
- features |= (1 << FEATURE_SSE);
+ set_feature (FEATURE_SSE);
if (edx & bit_SSE2)
- features |= (1 << FEATURE_SSE2);
+ set_feature (FEATURE_SSE2);
if (ecx & bit_POPCNT)
- features |= (1 << FEATURE_POPCNT);
+ set_feature (FEATURE_POPCNT);
if (ecx & bit_AES)
- features |= (1 << FEATURE_AES);
+ set_feature (FEATURE_AES);
if (ecx & bit_PCLMUL)
- features |= (1 << FEATURE_PCLMUL);
+ set_feature (FEATURE_PCLMUL);
if (ecx & bit_SSE3)
- features |= (1 << FEATURE_SSE3);
+ set_feature (FEATURE_SSE3);
if (ecx & bit_SSSE3)
- features |= (1 << FEATURE_SSSE3);
+ set_feature (FEATURE_SSSE3);
if (ecx & bit_SSE4_1)
- features |= (1 << FEATURE_SSE4_1);
+ set_feature (FEATURE_SSE4_1);
if (ecx & bit_SSE4_2)
- features |= (1 << FEATURE_SSE4_2);
- if (ecx & bit_AVX)
- features |= (1 << FEATURE_AVX);
- if (ecx & bit_FMA)
- features |= (1 << FEATURE_FMA);
+ set_feature (FEATURE_SSE4_2);
+ if (avx_usable)
+ {
+ if (ecx & bit_AVX)
+ set_feature (FEATURE_AVX);
+ if (ecx & bit_FMA)
+ set_feature (FEATURE_FMA);
+ }
/* Get Advanced Features at level 7 (eax = 7, ecx = 0). */
if (max_cpuid_level >= 7)
{
__cpuid_count (7, 0, eax, ebx, ecx, edx);
if (ebx & bit_BMI)
- features |= (1 << FEATURE_BMI);
- if (ebx & bit_AVX2)
- features |= (1 << FEATURE_AVX2);
+ set_feature (FEATURE_BMI);
+ if (avx_usable)
+ {
+ if (ebx & bit_AVX2)
+ set_feature (FEATURE_AVX2);
+ }
if (ebx & bit_BMI2)
- features |= (1 << FEATURE_BMI2);
- if (ebx & bit_AVX512F)
- features |= (1 << FEATURE_AVX512F);
- if (ebx & bit_AVX512VL)
- features |= (1 << FEATURE_AVX512VL);
- if (ebx & bit_AVX512BW)
- features |= (1 << FEATURE_AVX512BW);
- if (ebx & bit_AVX512DQ)
- features |= (1 << FEATURE_AVX512DQ);
- if (ebx & bit_AVX512CD)
- features |= (1 << FEATURE_AVX512CD);
- if (ebx & bit_AVX512PF)
- features |= (1 << FEATURE_AVX512PF);
- if (ebx & bit_AVX512ER)
- features |= (1 << FEATURE_AVX512ER);
- if (ebx & bit_AVX512IFMA)
- features |= (1 << FEATURE_AVX512IFMA);
- if (ecx & bit_AVX512VBMI)
- features |= (1 << FEATURE_AVX512VBMI);
- if (ecx & bit_AVX512VPOPCNTDQ)
- features |= (1 << FEATURE_AVX512VPOPCNTDQ);
- if (edx & bit_AVX5124VNNIW)
- features |= (1 << FEATURE_AVX5124VNNIW);
- if (edx & bit_AVX5124FMAPS)
- features |= (1 << FEATURE_AVX5124FMAPS);
+ set_feature (FEATURE_BMI2);
+ if (avx512_usable)
+ {
+ if (ebx & bit_AVX512F)
+ set_feature (FEATURE_AVX512F);
+ if (ebx & bit_AVX512VL)
+ set_feature (FEATURE_AVX512VL);
+ if (ebx & bit_AVX512BW)
+ set_feature (FEATURE_AVX512BW);
+ if (ebx & bit_AVX512DQ)
+ set_feature (FEATURE_AVX512DQ);
+ if (ebx & bit_AVX512CD)
+ set_feature (FEATURE_AVX512CD);
+ if (ebx & bit_AVX512PF)
+ set_feature (FEATURE_AVX512PF);
+ if (ebx & bit_AVX512ER)
+ set_feature (FEATURE_AVX512ER);
+ if (ebx & bit_AVX512IFMA)
+ set_feature (FEATURE_AVX512IFMA);
+ if (ecx & bit_AVX512VBMI)
+ set_feature (FEATURE_AVX512VBMI);
+ if (ecx & bit_AVX512VBMI2)
+ set_feature (FEATURE_AVX512VBMI2);
+ if (ecx & bit_GFNI)
+ set_feature (FEATURE_GFNI);
+ if (ecx & bit_VPCLMULQDQ)
+ set_feature (FEATURE_VPCLMULQDQ);
+ if (ecx & bit_AVX512VNNI)
+ set_feature (FEATURE_AVX512VNNI);
+ if (ecx & bit_AVX512BITALG)
+ set_feature (FEATURE_AVX512BITALG);
+ if (ecx & bit_AVX512VPOPCNTDQ)
+ set_feature (FEATURE_AVX512VPOPCNTDQ);
+ if (edx & bit_AVX5124VNNIW)
+ set_feature (FEATURE_AVX5124VNNIW);
+ if (edx & bit_AVX5124FMAPS)
+ set_feature (FEATURE_AVX5124FMAPS);
+ }
}
/* Check cpuid level of extended features. */
@@ -303,14 +386,22 @@ get_available_features (unsigned int ecx, unsigned int edx,
__cpuid (0x80000001, eax, ebx, ecx, edx);
if (ecx & bit_SSE4a)
- features |= (1 << FEATURE_SSE4_A);
- if (ecx & bit_FMA4)
- features |= (1 << FEATURE_FMA4);
- if (ecx & bit_XOP)
- features |= (1 << FEATURE_XOP);
+ set_feature (FEATURE_SSE4_A);
+ if (avx_usable)
+ {
+ if (ecx & bit_FMA4)
+ set_feature (FEATURE_FMA4);
+ if (ecx & bit_XOP)
+ set_feature (FEATURE_XOP);
+ }
}
__cpu_model.__cpu_features[0] = features;
+#ifndef SHARED
+ __cpu_features2 = features2;
+#else
+ (void) features2;
+#endif
}
/* A constructor function that is sets __cpu_model and __cpu_features with
diff --git a/libgcc/config/i386/cpuinfo.h b/libgcc/config/i386/cpuinfo.h
index a247072..0aa887b 100644
--- a/libgcc/config/i386/cpuinfo.h
+++ b/libgcc/config/i386/cpuinfo.h
@@ -48,6 +48,9 @@ enum processor_types
AMD_BTVER2,
AMDFAM17H,
INTEL_KNM,
+ INTEL_GOLDMONT,
+ INTEL_GOLDMONT_PLUS,
+ INTEL_TREMONT,
CPU_TYPE_MAX
};
@@ -70,7 +73,8 @@ enum processor_subtypes
INTEL_COREI7_SKYLAKE,
INTEL_COREI7_SKYLAKE_AVX512,
INTEL_COREI7_CANNONLAKE,
- INTEL_COREI7_ICELAKE,
+ INTEL_COREI7_ICELAKE_CLIENT,
+ INTEL_COREI7_ICELAKE_SERVER,
CPU_SUBTYPE_MAX
};
@@ -108,7 +112,12 @@ enum processor_features
FEATURE_AVX512IFMA,
FEATURE_AVX5124VNNIW,
FEATURE_AVX5124FMAPS,
- FEATURE_AVX512VPOPCNTDQ
+ FEATURE_AVX512VPOPCNTDQ,
+ FEATURE_AVX512VBMI2,
+ FEATURE_GFNI,
+ FEATURE_VPCLMULQDQ,
+ FEATURE_AVX512VNNI,
+ FEATURE_AVX512BITALG
};
extern struct __processor_model
@@ -118,3 +127,4 @@ extern struct __processor_model
unsigned int __cpu_subtype;
unsigned int __cpu_features[1];
} __cpu_model;
+extern unsigned int __cpu_features2;
diff --git a/libgcc/config/i386/cygwin.S b/libgcc/config/i386/cygwin.S
index 449b7d7..ece17f8 100644
--- a/libgcc/config/i386/cygwin.S
+++ b/libgcc/config/i386/cygwin.S
@@ -23,31 +23,11 @@
* <http://www.gnu.org/licenses/>.
*/
-#include "auto-host.h"
+#include "i386-asm.h"
-#ifdef HAVE_GAS_CFI_SECTIONS_DIRECTIVE
+#ifdef HAVE_AS_CFI_SECTIONS
.cfi_sections .debug_frame
-# define cfi_startproc() .cfi_startproc
-# define cfi_endproc() .cfi_endproc
-# define cfi_adjust_cfa_offset(X) .cfi_adjust_cfa_offset X
-# define cfi_def_cfa_register(X) .cfi_def_cfa_register X
-# define cfi_register(D,S) .cfi_register D, S
-# ifdef __x86_64__
-# define cfi_push(X) .cfi_adjust_cfa_offset 8; .cfi_rel_offset X, 0
-# define cfi_pop(X) .cfi_adjust_cfa_offset -8; .cfi_restore X
-# else
-# define cfi_push(X) .cfi_adjust_cfa_offset 4; .cfi_rel_offset X, 0
-# define cfi_pop(X) .cfi_adjust_cfa_offset -4; .cfi_restore X
-# endif
-#else
-# define cfi_startproc()
-# define cfi_endproc()
-# define cfi_adjust_cfa_offset(X)
-# define cfi_def_cfa_register(X)
-# define cfi_register(D,S)
-# define cfi_push(X)
-# define cfi_pop(X)
-#endif /* HAVE_GAS_CFI_SECTIONS_DIRECTIVE */
+#endif
#ifdef L_chkstk
/* Function prologue calls __chkstk to probe the stack when allocating more
diff --git a/libgcc/config/i386/i386-asm.h b/libgcc/config/i386/i386-asm.h
index 267133a..b5b7fb4 100644
--- a/libgcc/config/i386/i386-asm.h
+++ b/libgcc/config/i386/i386-asm.h
@@ -27,7 +27,33 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define I386_ASM_H
#include "auto-target.h"
-#include "auto-host.h"
+
+#ifdef __GCC_HAVE_DWARF2_CFI_ASM
+# define cfi_startproc() .cfi_startproc
+# define cfi_endproc() .cfi_endproc
+# define cfi_adjust_cfa_offset(X) .cfi_adjust_cfa_offset X
+# define cfi_def_cfa_register(X) .cfi_def_cfa_register X
+# define cfi_def_cfa(R,O) .cfi_def_cfa R, O
+# define cfi_register(D,S) .cfi_register D, S
+# define cfi_offset(R,O) .cfi_offset R, O
+# ifdef __x86_64__
+# define cfi_push(X) .cfi_adjust_cfa_offset 8; .cfi_rel_offset X, 0
+# define cfi_pop(X) .cfi_adjust_cfa_offset -8; .cfi_restore X
+# else
+# define cfi_push(X) .cfi_adjust_cfa_offset 4; .cfi_rel_offset X, 0
+# define cfi_pop(X) .cfi_adjust_cfa_offset -4; .cfi_restore X
+# endif
+#else
+# define cfi_startproc()
+# define cfi_endproc()
+# define cfi_adjust_cfa_offset(X)
+# define cfi_def_cfa_register(X)
+# define cfi_def_cfa(R,O)
+# define cfi_register(D,S)
+# define cfi_offset(R,O)
+# define cfi_push(X)
+# define cfi_pop(X)
+#endif
#define PASTE2(a, b) PASTE2a(a, b)
#define PASTE2a(a, b) a ## b
@@ -37,8 +63,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#ifdef __ELF__
# define FN_TYPE(fn) .type fn,@function
# define FN_SIZE(fn) .size fn,.-fn
-# ifdef HAVE_GAS_HIDDEN
-# define FN_HIDDEN(fn) .hidden fn
+# ifdef AS_HIDDEN_DIRECTIVE
+# define FN_HIDDEN(fn) AS_HIDDEN_DIRECTIVE fn
# endif
#else
# define FN_TYPE(fn)
diff --git a/libgcc/config/i386/linux-unwind.h b/libgcc/config/i386/linux-unwind.h
index f1f5233..ea838e4 100644
--- a/libgcc/config/i386/linux-unwind.h
+++ b/libgcc/config/i386/linux-unwind.h
@@ -23,7 +23,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
/* Unwind shadow stack for -fcf-protection -mshstk. */
-#if defined __SHSTK__ && defined __CET__
+#if defined __SHSTK__ && defined __CET__ && (__CET__ & 2) != 0
# include "config/i386/shadow-stack-unwind.h"
#endif
diff --git a/libgcc/config/i386/morestack.S b/libgcc/config/i386/morestack.S
index eca441a..99e65ea 100644
--- a/libgcc/config/i386/morestack.S
+++ b/libgcc/config/i386/morestack.S
@@ -730,6 +730,7 @@ __morestack_large_model:
#endif
__stack_split_initialize:
+ _CET_ENDBR
#ifndef __x86_64__
diff --git a/libgcc/config/i386/resms64fx.h b/libgcc/config/i386/resms64fx.h
index c5f63d8..88d36f3 100644
--- a/libgcc/config/i386/resms64fx.h
+++ b/libgcc/config/i386/resms64fx.h
@@ -33,6 +33,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
* from the function. */
.text
+ cfi_startproc()
+ cfi_offset(%rbp, -16)
+ cfi_def_cfa(%rbp, 16)
MS2SYSV_STUB_BEGIN(resms64fx_17)
mov -0x68(%rsi),%r15
MS2SYSV_STUB_BEGIN(resms64fx_16)
@@ -48,7 +51,9 @@ MS2SYSV_STUB_BEGIN(resms64fx_12)
SSE_RESTORE
mov -0x38(%rsi),%rsi
leaveq
+ cfi_def_cfa(%rsp, 8)
ret
+ cfi_endproc()
MS2SYSV_STUB_END(resms64fx_12)
MS2SYSV_STUB_END(resms64fx_13)
MS2SYSV_STUB_END(resms64fx_14)
diff --git a/libgcc/config/i386/resms64x.h b/libgcc/config/i386/resms64x.h
index 1b44938..cf6830f 100644
--- a/libgcc/config/i386/resms64x.h
+++ b/libgcc/config/i386/resms64x.h
@@ -32,6 +32,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
* function. */
.text
+ cfi_startproc()
+ cfi_def_cfa(%r10, 8)
MS2SYSV_STUB_BEGIN(resms64x_18)
mov -0x70(%rsi),%r15
MS2SYSV_STUB_BEGIN(resms64x_17)
@@ -49,7 +51,9 @@ MS2SYSV_STUB_BEGIN(resms64x_12)
SSE_RESTORE
mov -0x38(%rsi),%rsi
mov %r10,%rsp
+ cfi_def_cfa_register(%rsp)
ret
+ cfi_endproc()
MS2SYSV_STUB_END(resms64x_12)
MS2SYSV_STUB_END(resms64x_13)
MS2SYSV_STUB_END(resms64x_14)
diff --git a/libgcc/config/i386/shadow-stack-unwind.h b/libgcc/config/i386/shadow-stack-unwind.h
index b7c3d98..a32f3e7 100644
--- a/libgcc/config/i386/shadow-stack-unwind.h
+++ b/libgcc/config/i386/shadow-stack-unwind.h
@@ -42,10 +42,15 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
_Unwind_Word tmp = (x); \
while (tmp > 255) \
{ \
- _inc_ssp (tmp); \
+ _inc_ssp (255); \
tmp -= 255; \
} \
_inc_ssp (tmp); \
} \
} \
while (0)
+
+/* Increment frame count. Skip signal frames. */
+#undef _Unwind_Frames_Increment
+#define _Unwind_Frames_Increment(context, frames) \
+ if (!_Unwind_IsSignalFrame (context)) frames++
diff --git a/libgcc/config/m68k/lb1sf68.S b/libgcc/config/m68k/lb1sf68.S
index 1d9392a..325a7c1 100644
--- a/libgcc/config/m68k/lb1sf68.S
+++ b/libgcc/config/m68k/lb1sf68.S
@@ -3111,6 +3111,8 @@ Laddsf$nf:
movel a6@(12),d1 | did some processing already)
movel IMM (INFINITY),d4 | useful constant (INFINITY)
movel d0,d2 | save sign bits
+ movel d0,d7 | into d7 as well as we may need the sign
+ | bit before jumping to LfSinfty
movel d1,d3
bclr IMM (31),d0 | clear sign bits
bclr IMM (31),d1
@@ -3125,7 +3127,6 @@ Laddsf$nf:
| are adding or subtracting them.
eorl d3,d2 | to check sign bits
bmi 1f
- movel d0,d7
andl IMM (0x80000000),d7 | get (common) sign bit
bra Lf$infty
1:
@@ -3135,7 +3136,6 @@ Laddsf$nf:
cmpl d1,d0 | are both infinite?
beq Lf$inop | if so return NaN
- movel d0,d7
andl IMM (0x80000000),d7 | get a's sign bit '
cmpl d4,d0 | test now for infinity
beq Lf$infty | if a is INFINITY return with this sign
diff --git a/libgcc/config/nds32/linux-atomic.c b/libgcc/config/nds32/linux-atomic.c
new file mode 100644
index 0000000..6da7be9
--- /dev/null
+++ b/libgcc/config/nds32/linux-atomic.c
@@ -0,0 +1,282 @@
+/* Linux-specific atomic operations for NDS32 Linux.
+ Copyright (C) 2012-2018 Free Software Foundation, Inc.
+
+This file is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3, or (at your option) any
+later version.
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+/* We implement byte, short and int versions of each atomic operation
+ using the kernel helper defined below. There is no support for
+ 64-bit operations yet. */
+
+/* This function copy form NDS32 Linux-kernal. */
+static inline int
+__kernel_cmpxchg (int oldval, int newval, int *mem)
+{
+ int temp1, temp2, temp3, offset;
+
+ asm volatile ("msync\tall\n"
+ "movi\t%0, #0\n"
+ "1:\n"
+ "\tllw\t%1, [%4+%0]\n"
+ "\tsub\t%3, %1, %6\n"
+ "\tcmovz\t%2, %5, %3\n"
+ "\tcmovn\t%2, %1, %3\n"
+ "\tscw\t%2, [%4+%0]\n"
+ "\tbeqz\t%2, 1b\n"
+ : "=&r" (offset), "=&r" (temp3), "=&r" (temp2), "=&r" (temp1)
+ : "r" (mem), "r" (newval), "r" (oldval) : "memory");
+
+ return temp1;
+}
+
+#define HIDDEN __attribute__ ((visibility ("hidden")))
+
+#ifdef __NDS32_EL__
+#define INVERT_MASK_1 0
+#define INVERT_MASK_2 0
+#else
+#define INVERT_MASK_1 24
+#define INVERT_MASK_2 16
+#endif
+
+#define MASK_1 0xffu
+#define MASK_2 0xffffu
+
+#define FETCH_AND_OP_WORD(OP, PFX_OP, INF_OP) \
+ int HIDDEN \
+ __sync_fetch_and_##OP##_4 (int *ptr, int val) \
+ { \
+ int failure, tmp; \
+ \
+ do { \
+ tmp = __atomic_load_n (ptr, __ATOMIC_SEQ_CST); \
+ failure = __kernel_cmpxchg (tmp, PFX_OP (tmp INF_OP val), ptr); \
+ } while (failure != 0); \
+ \
+ return tmp; \
+ }
+
+FETCH_AND_OP_WORD (add, , +)
+FETCH_AND_OP_WORD (sub, , -)
+FETCH_AND_OP_WORD (or, , |)
+FETCH_AND_OP_WORD (and, , &)
+FETCH_AND_OP_WORD (xor, , ^)
+FETCH_AND_OP_WORD (nand, ~, &)
+
+#define NAME_oldval(OP, WIDTH) __sync_fetch_and_##OP##_##WIDTH
+#define NAME_newval(OP, WIDTH) __sync_##OP##_and_fetch_##WIDTH
+
+/* Implement both __sync_<op>_and_fetch and __sync_fetch_and_<op> for
+ subword-sized quantities. */
+
+#define SUBWORD_SYNC_OP(OP, PFX_OP, INF_OP, TYPE, WIDTH, RETURN) \
+ TYPE HIDDEN \
+ NAME##_##RETURN (OP, WIDTH) (TYPE *ptr, TYPE val) \
+ { \
+ int *wordptr = (int *) ((unsigned long) ptr & ~3); \
+ unsigned int mask, shift, oldval, newval; \
+ int failure; \
+ \
+ shift = (((unsigned long) ptr & 3) << 3) ^ INVERT_MASK_##WIDTH; \
+ mask = MASK_##WIDTH << shift; \
+ \
+ do { \
+ oldval = __atomic_load_n (wordptr, __ATOMIC_SEQ_CST); \
+ newval = ((PFX_OP (((oldval & mask) >> shift) \
+ INF_OP (unsigned int) val)) << shift) & mask; \
+ newval |= oldval & ~mask; \
+ failure = __kernel_cmpxchg (oldval, newval, wordptr); \
+ } while (failure != 0); \
+ \
+ return (RETURN & mask) >> shift; \
+ }
+
+
+SUBWORD_SYNC_OP (add, , +, unsigned short, 2, oldval)
+SUBWORD_SYNC_OP (sub, , -, unsigned short, 2, oldval)
+SUBWORD_SYNC_OP (or, , |, unsigned short, 2, oldval)
+SUBWORD_SYNC_OP (and, , &, unsigned short, 2, oldval)
+SUBWORD_SYNC_OP (xor, , ^, unsigned short, 2, oldval)
+SUBWORD_SYNC_OP (nand, ~, &, unsigned short, 2, oldval)
+
+SUBWORD_SYNC_OP (add, , +, unsigned char, 1, oldval)
+SUBWORD_SYNC_OP (sub, , -, unsigned char, 1, oldval)
+SUBWORD_SYNC_OP (or, , |, unsigned char, 1, oldval)
+SUBWORD_SYNC_OP (and, , &, unsigned char, 1, oldval)
+SUBWORD_SYNC_OP (xor, , ^, unsigned char, 1, oldval)
+SUBWORD_SYNC_OP (nand, ~, &, unsigned char, 1, oldval)
+
+#define OP_AND_FETCH_WORD(OP, PFX_OP, INF_OP) \
+ int HIDDEN \
+ __sync_##OP##_and_fetch_4 (int *ptr, int val) \
+ { \
+ int tmp, failure; \
+ \
+ do { \
+ tmp = __atomic_load_n (ptr, __ATOMIC_SEQ_CST); \
+ failure = __kernel_cmpxchg (tmp, PFX_OP (tmp INF_OP val), ptr); \
+ } while (failure != 0); \
+ \
+ return PFX_OP (tmp INF_OP val); \
+ }
+
+OP_AND_FETCH_WORD (add, , +)
+OP_AND_FETCH_WORD (sub, , -)
+OP_AND_FETCH_WORD (or, , |)
+OP_AND_FETCH_WORD (and, , &)
+OP_AND_FETCH_WORD (xor, , ^)
+OP_AND_FETCH_WORD (nand, ~, &)
+
+SUBWORD_SYNC_OP (add, , +, unsigned short, 2, newval)
+SUBWORD_SYNC_OP (sub, , -, unsigned short, 2, newval)
+SUBWORD_SYNC_OP (or, , |, unsigned short, 2, newval)
+SUBWORD_SYNC_OP (and, , &, unsigned short, 2, newval)
+SUBWORD_SYNC_OP (xor, , ^, unsigned short, 2, newval)
+SUBWORD_SYNC_OP (nand, ~, &, unsigned short, 2, newval)
+
+SUBWORD_SYNC_OP (add, , +, unsigned char, 1, newval)
+SUBWORD_SYNC_OP (sub, , -, unsigned char, 1, newval)
+SUBWORD_SYNC_OP (or, , |, unsigned char, 1, newval)
+SUBWORD_SYNC_OP (and, , &, unsigned char, 1, newval)
+SUBWORD_SYNC_OP (xor, , ^, unsigned char, 1, newval)
+SUBWORD_SYNC_OP (nand, ~, &, unsigned char, 1, newval)
+
+int HIDDEN
+__sync_val_compare_and_swap_4 (int *ptr, int oldval, int newval)
+{
+ int actual_oldval, fail;
+
+ while (1)
+ {
+ actual_oldval = __atomic_load_n (ptr, __ATOMIC_SEQ_CST);
+
+ if (oldval != actual_oldval)
+ return actual_oldval;
+
+ fail = __kernel_cmpxchg (actual_oldval, newval, ptr);
+
+ if (!fail)
+ return oldval;
+ }
+}
+
+#define SUBWORD_VAL_CAS(TYPE, WIDTH) \
+ TYPE HIDDEN \
+ __sync_val_compare_and_swap_##WIDTH (TYPE *ptr, TYPE oldval, \
+ TYPE newval) \
+ { \
+ int *wordptr = (int *)((unsigned long) ptr & ~3), fail; \
+ unsigned int mask, shift, actual_oldval, actual_newval; \
+ \
+ shift = (((unsigned long) ptr & 3) << 3) ^ INVERT_MASK_##WIDTH; \
+ mask = MASK_##WIDTH << shift; \
+ \
+ while (1) \
+ { \
+ actual_oldval = __atomic_load_n (wordptr, __ATOMIC_SEQ_CST); \
+ \
+ if (((actual_oldval & mask) >> shift) != (unsigned int) oldval) \
+ return (actual_oldval & mask) >> shift; \
+ \
+ actual_newval = (actual_oldval & ~mask) \
+ | (((unsigned int) newval << shift) & mask); \
+ \
+ fail = __kernel_cmpxchg (actual_oldval, actual_newval, \
+ wordptr); \
+ \
+ if (!fail) \
+ return oldval; \
+ } \
+ }
+
+SUBWORD_VAL_CAS (unsigned short, 2)
+SUBWORD_VAL_CAS (unsigned char, 1)
+
+typedef unsigned char bool;
+
+bool HIDDEN
+__sync_bool_compare_and_swap_4 (int *ptr, int oldval, int newval)
+{
+ int failure = __kernel_cmpxchg (oldval, newval, ptr);
+ return (failure == 0);
+}
+
+#define SUBWORD_BOOL_CAS(TYPE, WIDTH) \
+ bool HIDDEN \
+ __sync_bool_compare_and_swap_##WIDTH (TYPE *ptr, TYPE oldval, \
+ TYPE newval) \
+ { \
+ TYPE actual_oldval \
+ = __sync_val_compare_and_swap_##WIDTH (ptr, oldval, newval); \
+ return (oldval == actual_oldval); \
+ }
+
+SUBWORD_BOOL_CAS (unsigned short, 2)
+SUBWORD_BOOL_CAS (unsigned char, 1)
+
+int HIDDEN
+__sync_lock_test_and_set_4 (int *ptr, int val)
+{
+ int failure, oldval;
+
+ do {
+ oldval = __atomic_load_n (ptr, __ATOMIC_SEQ_CST);
+ failure = __kernel_cmpxchg (oldval, val, ptr);
+ } while (failure != 0);
+
+ return oldval;
+}
+
+#define SUBWORD_TEST_AND_SET(TYPE, WIDTH) \
+ TYPE HIDDEN \
+ __sync_lock_test_and_set_##WIDTH (TYPE *ptr, TYPE val) \
+ { \
+ int failure; \
+ unsigned int oldval, newval, shift, mask; \
+ int *wordptr = (int *) ((unsigned long) ptr & ~3); \
+ \
+ shift = (((unsigned long) ptr & 3) << 3) ^ INVERT_MASK_##WIDTH; \
+ mask = MASK_##WIDTH << shift; \
+ \
+ do { \
+ oldval = __atomic_load_n (wordptr, __ATOMIC_SEQ_CST); \
+ newval = (oldval & ~mask) \
+ | (((unsigned int) val << shift) & mask); \
+ failure = __kernel_cmpxchg (oldval, newval, wordptr); \
+ } while (failure != 0); \
+ \
+ return (oldval & mask) >> shift; \
+ }
+
+SUBWORD_TEST_AND_SET (unsigned short, 2)
+SUBWORD_TEST_AND_SET (unsigned char, 1)
+
+#define SYNC_LOCK_RELEASE(TYPE, WIDTH) \
+ void HIDDEN \
+ __sync_lock_release_##WIDTH (TYPE *ptr) \
+ { \
+ /* All writes before this point must be seen before we release \
+ the lock itself. */ \
+ __builtin_nds32_msync_all (); \
+ *ptr = 0; \
+ }
+
+SYNC_LOCK_RELEASE (int, 4)
+SYNC_LOCK_RELEASE (short, 2)
+SYNC_LOCK_RELEASE (char, 1)
diff --git a/libgcc/config/nds32/linux-unwind.h b/libgcc/config/nds32/linux-unwind.h
new file mode 100644
index 0000000..921edf9
--- /dev/null
+++ b/libgcc/config/nds32/linux-unwind.h
@@ -0,0 +1,156 @@
+/* DWARF2 EH unwinding support for NDS32 Linux signal frame.
+ Copyright (C) 2014-2015 Free Software Foundation, Inc.
+ Contributed by Andes Technology Corporation.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef inhibit_libc
+
+/* Do code reading to identify a signal frame, and set the frame
+ state data appropriately. See unwind-dw2.c for the structs.
+ The corresponding bits in the Linux kernel are in
+ arch/nds32/kernel/signal.c. */
+
+#include <signal.h>
+#include <asm/unistd.h>
+
+/* Exactly the same layout as the kernel structures, unique names. */
+
+/* arch/nds32/kernel/signal.c */
+struct _sigframe {
+ struct ucontext uc;
+ unsigned long retcode;
+};
+
+struct _rt_sigframe {
+ siginfo_t info;
+ struct _sigframe sig;
+};
+#define SIGRETURN 0xeb0e0a64
+#define RT_SIGRETURN 0xab150a64
+
+#define MD_FALLBACK_FRAME_STATE_FOR nds32_fallback_frame_state
+
+/* This function is supposed to be invoked by uw_frame_state_for()
+ when there is no unwind data available.
+
+ Generally, given the _Unwind_Context CONTEXT for a stack frame,
+ we need to look up its caller and decode information into FS.
+ However, if the exception handling happens within a signal handler,
+ the return address of signal handler is a special module, which
+ contains signal return syscall and has no FDE in the .eh_frame section.
+ We need to implement MD_FALLBACK_FRAME_STATE_FOR so that we can
+ unwind through signal frames. */
+static _Unwind_Reason_Code
+nds32_fallback_frame_state (struct _Unwind_Context *context,
+ _Unwind_FrameState *fs)
+{
+ u_int32_t *pc = (u_int32_t *) context->ra;
+ struct sigcontext *sc_;
+ _Unwind_Ptr new_cfa;
+
+#ifdef __NDS32_EB__
+#error "Signal handler is not supported for force unwind."
+#endif
+
+ if ((_Unwind_Ptr) pc & 3)
+ return _URC_END_OF_STACK;
+
+ /* Check if we are going through a signal handler.
+ See arch/nds32/kernel/signal.c implementation.
+ SWI_SYS_SIGRETURN -> (0xeb0e0a64)
+ SWI_SYS_RT_SIGRETURN -> (0xab150a64)
+ FIXME: Currently we only handle little endian (EL) case. */
+ if (pc[0] == SIGRETURN)
+ {
+ /* Using '_sigfame' memory address to locate kernal's sigcontext.
+ The sigcontext structures in arch/nds32/include/asm/sigcontext.h. */
+ struct _sigframe *rt_;
+ rt_ = context->cfa;
+ sc_ = &rt_->uc.uc_mcontext;
+ }
+ else if (pc[0] == RT_SIGRETURN)
+ {
+ /* Using '_sigfame' memory address to locate kernal's sigcontext. */
+ struct _rt_sigframe *rt_;
+ rt_ = context->cfa;
+ sc_ = &rt_->sig.uc.uc_mcontext;
+ }
+ else
+ return _URC_END_OF_STACK;
+
+ /* Update cfa from sigcontext. */
+ new_cfa = (_Unwind_Ptr) sc_;
+ fs->regs.cfa_how = CFA_REG_OFFSET;
+ fs->regs.cfa_reg = STACK_POINTER_REGNUM;
+ fs->regs.cfa_offset = new_cfa - (_Unwind_Ptr) context->cfa;
+
+#define NDS32_PUT_FS_REG(NUM, NAME) \
+ (fs->regs.reg[NUM].how = REG_SAVED_OFFSET, \
+ fs->regs.reg[NUM].loc.offset = (_Unwind_Ptr) &(sc_->NAME) - new_cfa)
+
+ /* Restore all registers value. */
+ NDS32_PUT_FS_REG (0, nds32_r0);
+ NDS32_PUT_FS_REG (1, nds32_r1);
+ NDS32_PUT_FS_REG (2, nds32_r2);
+ NDS32_PUT_FS_REG (3, nds32_r3);
+ NDS32_PUT_FS_REG (4, nds32_r4);
+ NDS32_PUT_FS_REG (5, nds32_r5);
+ NDS32_PUT_FS_REG (6, nds32_r6);
+ NDS32_PUT_FS_REG (7, nds32_r7);
+ NDS32_PUT_FS_REG (8, nds32_r8);
+ NDS32_PUT_FS_REG (9, nds32_r9);
+ NDS32_PUT_FS_REG (10, nds32_r10);
+ NDS32_PUT_FS_REG (11, nds32_r11);
+ NDS32_PUT_FS_REG (12, nds32_r12);
+ NDS32_PUT_FS_REG (13, nds32_r13);
+ NDS32_PUT_FS_REG (14, nds32_r14);
+ NDS32_PUT_FS_REG (15, nds32_r15);
+ NDS32_PUT_FS_REG (16, nds32_r16);
+ NDS32_PUT_FS_REG (17, nds32_r17);
+ NDS32_PUT_FS_REG (18, nds32_r18);
+ NDS32_PUT_FS_REG (19, nds32_r19);
+ NDS32_PUT_FS_REG (20, nds32_r20);
+ NDS32_PUT_FS_REG (21, nds32_r21);
+ NDS32_PUT_FS_REG (22, nds32_r22);
+ NDS32_PUT_FS_REG (23, nds32_r23);
+ NDS32_PUT_FS_REG (24, nds32_r24);
+ NDS32_PUT_FS_REG (25, nds32_r25);
+
+ NDS32_PUT_FS_REG (28, nds32_fp);
+ NDS32_PUT_FS_REG (29, nds32_gp);
+ NDS32_PUT_FS_REG (30, nds32_lp);
+ NDS32_PUT_FS_REG (31, nds32_sp);
+
+ /* Restore PC, point to trigger signal instruction. */
+ NDS32_PUT_FS_REG (32, nds32_ipc);
+
+#undef NDS32_PUT_FS_REG
+
+ /* The retaddr is PC, use PC to find FDE. */
+ fs->retaddr_column = 32;
+ fs->signal_frame = 1;
+
+ return _URC_NO_REASON;
+}
+
+#endif
diff --git a/libgcc/config/nds32/sfp-machine.h b/libgcc/config/nds32/sfp-machine.h
index 499bdad..bfbdaf9 100644
--- a/libgcc/config/nds32/sfp-machine.h
+++ b/libgcc/config/nds32/sfp-machine.h
@@ -76,6 +76,25 @@ typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
R##_c = FP_CLS_NAN; \
} while (0)
+#ifdef NDS32_ABI_2FP_PLUS
+#define FP_RND_NEAREST 0x0
+#define FP_RND_PINF 0x1
+#define FP_RND_MINF 0x2
+#define FP_RND_ZERO 0x3
+#define FP_RND_MASK 0x3
+
+#define _FP_DECL_EX \
+ unsigned long int _fcsr __attribute__ ((unused)) = FP_RND_NEAREST
+
+#define FP_INIT_ROUNDMODE \
+ do { \
+ _fcsr = __builtin_nds32_fmfcsr (); \
+ } while (0)
+
+#define FP_ROUNDMODE (_fcsr & FP_RND_MASK)
+
+#endif
+
/* Not checked. */
#define _FP_TININESS_AFTER_ROUNDING 0
diff --git a/libgcc/config/nds32/t-nds32-newlib b/libgcc/config/nds32/t-nds32-newlib
index 1ea2bc3..a59646f 100644
--- a/libgcc/config/nds32/t-nds32-newlib
+++ b/libgcc/config/nds32/t-nds32-newlib
@@ -19,7 +19,7 @@
# <http://www.gnu.org/licenses/>.
# Compiler flags to use when compiling 'libgcc2.c'
-HOST_LIBGCC2_CFLAGS = -O2
+HOST_LIBGCC2_CFLAGS = -O2 -fwrapv
#LIB1ASMSRC = nds32/lib1asmsrc-newlib.S
diff --git a/libgcc/config/pa/fptr.c b/libgcc/config/pa/fptr.c
index 02f7e4b..944ed44 100644
--- a/libgcc/config/pa/fptr.c
+++ b/libgcc/config/pa/fptr.c
@@ -52,6 +52,16 @@ typedef int (*fptr_t) (void);
typedef int (*fixup_t) (struct link_map *, unsigned int);
extern unsigned int _GLOBAL_OFFSET_TABLE_;
+static inline int
+_dl_read_access_allowed (unsigned int *addr)
+{
+ int result;
+
+ asm ("proberi (%1),3,%0" : "=r" (result) : "r" (addr) : );
+
+ return result;
+}
+
/* __canonicalize_funcptr_for_compare must be hidden so that it is not
placed in the dynamic symbol table. Like millicode functions, it
must be linked into all binaries in order access the got table of
@@ -82,6 +92,16 @@ __canonicalize_funcptr_for_compare (fptr_t fptr)
The second word in the plabel contains the relocation offset for the
function. */
plabel = (unsigned int *) ((unsigned int) fptr & ~3);
+ if (!_dl_read_access_allowed (plabel))
+ return (unsigned int) fptr;
+
+ /* Load first word of candidate descriptor. It should be a pointer
+ with word alignment and point to memory that can be read. */
+ got = (unsigned int *) plabel[0];
+ if (((unsigned int) got & 3) != 0
+ || !_dl_read_access_allowed (got))
+ return (unsigned int) fptr;
+
got = (unsigned int *) (plabel[0] + GOT_FROM_PLT_STUB);
/* Return the address of the function if the plabel has been resolved. */
diff --git a/libgcc/config/riscv/save-restore.S b/libgcc/config/riscv/save-restore.S
index 9a6d0c9..a76c978 100644
--- a/libgcc/config/riscv/save-restore.S
+++ b/libgcc/config/riscv/save-restore.S
@@ -294,6 +294,48 @@ FUNC_END (__riscv_restore_0)
#else
+#ifdef __riscv_32e
+FUNC_BEGIN(__riscv_save_2)
+FUNC_BEGIN(__riscv_save_1)
+FUNC_BEGIN(__riscv_save_0)
+ .cfi_startproc
+ # __riscv_save_* routine use t0/x5 as return address
+ .cfi_return_column 5
+ addi sp, sp, -12
+ .cfi_def_cfa_offset 12
+ sw s1, 0(sp)
+ .cfi_offset 9, -12
+ sw s0, 4(sp)
+ .cfi_offset 8, -8
+ sw ra, 8(sp)
+ .cfi_offset 1, 0
+ jr t0
+ .cfi_endproc
+FUNC_END(__riscv_save_2)
+FUNC_END(__riscv_save_1)
+FUNC_END(__riscv_save_0)
+
+FUNC_BEGIN(__riscv_restore_2)
+FUNC_BEGIN(__riscv_restore_1)
+FUNC_BEGIN(__riscv_restore_0)
+ .cfi_startproc
+ .cfi_def_cfa_offset 14
+ lw s1, 0(sp)
+ .cfi_restore 9
+ lw s0, 4(sp)
+ .cfi_restore 8
+ lw ra, 8(sp)
+ .cfi_restore 1
+ addi sp, sp, 12
+ .cfi_def_cfa_offset 0
+ ret
+ .cfi_endproc
+FUNC_END(__riscv_restore_2)
+FUNC_END(__riscv_restore_1)
+FUNC_END(__riscv_restore_0)
+
+#else
+
FUNC_BEGIN (__riscv_save_12)
.cfi_startproc
# __riscv_save_* routine use t0/x5 as return address
@@ -486,4 +528,6 @@ FUNC_END (__riscv_restore_2)
FUNC_END (__riscv_restore_1)
FUNC_END (__riscv_restore_0)
-#endif
+#endif /* __riscv_32e */
+
+#endif /* __riscv_xlen == 64 */
diff --git a/libgcc/config/rs6000/_powikf2.c b/libgcc/config/rs6000/_powikf2.c
new file mode 100644
index 0000000..7afd096
--- /dev/null
+++ b/libgcc/config/rs6000/_powikf2.c
@@ -0,0 +1,63 @@
+/* Copyright (C) 1989-2018 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+#include "soft-fp.h"
+#include "quad-float128.h"
+
+/* __powikf3 can be compiled 3 different ways:
+
+ 1) If the assembler does not have support for the IEEE 128-bit insns
+ (xsaddqp, etc.) it is just compiled as __powikf2.
+
+ 2) If the assembler has IEEE 128-bit floating point support, and __powikf2
+ is not previously defined, it is defined as __powikf2_sw.
+
+ 3) If the assembler has IEEE 128-bit floating point support, and __powikf2
+ is included by _powikf2-hw.c, which defines __powikf2 as __powikf2_hw. The
+ __powikf2_hw.c is compiled with -mcpu=power9 and it automatically uses the
+ IEEE 128-bit instructions.
+
+ For #2/#3, float128-ifunc.c defines an ifunc function for __powikf2, that
+ will use the software version on power7/power8 systems, and the hardware
+ version on power9 systems.
+
+ The code is cloned from the code in libgcc2.c (which handles the standard
+ SF, DF, TF, and XF types). */
+
+#if defined(FLOAT128_HW_INSNS) && !defined(__powikf2)
+#define __powikf2 __powikf2_sw
+#endif
+
+TFtype
+__powikf2 (TFtype x, SItype_ppc m)
+{
+ unsigned int n = m < 0 ? -m : m;
+ TFtype y = n % 2 ? x : 1;
+ while (n >>= 1)
+ {
+ x = x * x;
+ if (n % 2)
+ y = y * x;
+ }
+ return m < 0 ? 1/y : y;
+}
diff --git a/libgcc/config/rs6000/float128-ifunc.c b/libgcc/config/rs6000/float128-ifunc.c
index 13a6045..8fcac24 100644
--- a/libgcc/config/rs6000/float128-ifunc.c
+++ b/libgcc/config/rs6000/float128-ifunc.c
@@ -84,6 +84,12 @@ __negkf2_resolve (void)
return SW_OR_HW (__negkf2_sw, __negkf2_hw);
}
+static __typeof__ (__powikf2_sw) *
+__powikf2_resolve (void)
+{
+ return SW_OR_HW (__powikf2_sw, __powikf2_hw);
+}
+
static __typeof__ (__floatsikf_sw) *
__floatsikf_resolve (void)
{
@@ -243,6 +249,9 @@ TFtype __divkf3 (TFtype, TFtype)
TFtype __negkf2 (TFtype)
__attribute__ ((__ifunc__ ("__negkf2_resolve")));
+TFtype __powikf2 (TFtype, SItype_ppc)
+ __attribute__ ((__ifunc__ ("__powikf2_resolve")));
+
CMPtype __eqkf2 (TFtype, TFtype)
__attribute__ ((__ifunc__ ("__eqkf2_resolve")));
diff --git a/libgcc/config/rs6000/quad-float128.h b/libgcc/config/rs6000/quad-float128.h
index e10b25f..1d4d513 100644
--- a/libgcc/config/rs6000/quad-float128.h
+++ b/libgcc/config/rs6000/quad-float128.h
@@ -72,6 +72,7 @@ extern TFtype __subkf3_sw (TFtype, TFtype);
extern TFtype __mulkf3_sw (TFtype, TFtype);
extern TFtype __divkf3_sw (TFtype, TFtype);
extern TFtype __negkf2_sw (TFtype);
+extern TFtype __powikf2_sw (TFtype, SItype_ppc);
extern CMPtype __eqkf2_sw (TFtype, TFtype);
extern CMPtype __gekf2_sw (TFtype, TFtype);
extern CMPtype __lekf2_sw (TFtype, TFtype);
@@ -114,6 +115,7 @@ extern TFtype __subkf3_hw (TFtype, TFtype);
extern TFtype __mulkf3_hw (TFtype, TFtype);
extern TFtype __divkf3_hw (TFtype, TFtype);
extern TFtype __negkf2_hw (TFtype);
+extern TFtype __powikf2_hw (TFtype, SItype_ppc);
extern CMPtype __eqkf2_hw (TFtype, TFtype);
extern CMPtype __gekf2_hw (TFtype, TFtype);
extern CMPtype __lekf2_hw (TFtype, TFtype);
@@ -142,6 +144,7 @@ extern TFtype __subkf3 (TFtype, TFtype);
extern TFtype __mulkf3 (TFtype, TFtype);
extern TFtype __divkf3 (TFtype, TFtype);
extern TFtype __negkf2 (TFtype);
+extern TFtype __powikf2 (TFtype, SItype_ppc);
extern CMPtype __eqkf2 (TFtype, TFtype);
extern CMPtype __nekf2 (TFtype, TFtype);
extern CMPtype __gekf2 (TFtype, TFtype);
diff --git a/libgcc/config/rs6000/t-crtstuff b/libgcc/config/rs6000/t-crtstuff
index 0b2601b..d5ff959 100644
--- a/libgcc/config/rs6000/t-crtstuff
+++ b/libgcc/config/rs6000/t-crtstuff
@@ -3,4 +3,4 @@
# Do not build crtend.o with -Os as that can result in references to
# out-of-line register save/restore functions, which may be unresolved
# as crtend.o is linked after libgcc.a. See PR45053.
-CRTSTUFF_T_CFLAGS = -msdata=none -O2
+CRTSTUFF_T_CFLAGS = -msdata=none -O2 -fno-asynchronous-unwind-tables
diff --git a/libgcc/config/rs6000/t-float128 b/libgcc/config/rs6000/t-float128
index 41ad527..8d52521 100644
--- a/libgcc/config/rs6000/t-float128
+++ b/libgcc/config/rs6000/t-float128
@@ -25,7 +25,7 @@ fp128_softfp_obj = $(fp128_softfp_static_obj) $(fp128_softfp_shared_obj)
# New functions for software emulation
fp128_ppc_funcs = floattikf floatuntikf fixkfti fixunskfti \
extendkftf2-sw trunctfkf2-sw \
- sfp-exceptions _mulkc3 _divkc3
+ sfp-exceptions _mulkc3 _divkc3 _powikf2
fp128_ppc_src = $(addprefix $(srcdir)/config/rs6000/,$(addsuffix \
.c,$(fp128_ppc_funcs)))
diff --git a/libgcc/config/rs6000/t-float128-hw b/libgcc/config/rs6000/t-float128-hw
index 7ab1069..acdddb0 100644
--- a/libgcc/config/rs6000/t-float128-hw
+++ b/libgcc/config/rs6000/t-float128-hw
@@ -6,9 +6,9 @@ FLOAT128_HW_INSNS = -DFLOAT128_HW_INSNS
# New functions for hardware support
fp128_hardfp_src = _mulkc3-hw.c _divkc3-hw.c
-fp128_hw_funcs = float128-hw _mulkc3-hw _divkc3-hw
+fp128_hw_funcs = float128-hw _mulkc3-hw _divkc3-hw _powikf2-hw
fp128_hw_src = $(srcdir)/config/rs6000/float128-hw.c _mulkc3-hw.c \
- _divkc3-hw.c
+ _divkc3-hw.c _powikf2-hw.c
fp128_hw_static_obj = $(addsuffix $(objext),$(fp128_hw_funcs))
fp128_hw_shared_obj = $(addsuffix _s$(objext),$(fp128_hw_funcs))
fp128_hw_obj = $(fp128_hw_static_obj) $(fp128_hw_shared_obj)
@@ -43,3 +43,7 @@ _mulkc3-hw.c: $(srcdir)/config/rs6000/_mulkc3.c
_divkc3-hw.c: $(srcdir)/config/rs6000/_divkc3.c
(echo "#define __divkc3 __divkc3_hw"; \
cat $(srcdir)/config/rs6000/_divkc3.c) > _divkc3-hw.c
+
+_powikf2-hw.c: $(srcdir)/config/rs6000/_powikf2.c
+ (echo "#define __powikf2 __powikf2_hw"; \
+ cat $(srcdir)/config/rs6000/_powikf2.c) > _powikf2-hw.c
diff --git a/libgcc/config/t-vxworks b/libgcc/config/t-vxworks
index bbbb16d..df70fee 100644
--- a/libgcc/config/t-vxworks
+++ b/libgcc/config/t-vxworks
@@ -7,8 +7,10 @@ LIB2ADDEH += $(srcdir)/config/vxlib.c $(srcdir)/config/vxlib-tls.c
# This ensures that the correct target headers are used; some VxWorks
# system headers have names that collide with GCC's internal (host)
# headers, e.g. regs.h. Make sure the local libgcc headers still
-# prevail (e.g. unwind.h).
+# prevail (e.g. unwind.h), and that gcc provided header files intended
+# to be user visible eventually are visible as well.
LIBGCC2_INCLUDES = -nostdinc -I. \
+ -I$(MULTIBUILDTOP)../../gcc/include \
`case "/$(MULTIDIR)" in \
*/mrtp*) echo -I$(WIND_USR)/h -I$(WIND_USR)/h/wrn/coreip ;; \
*) echo -I$(WIND_BASE)/target/h -I$(WIND_BASE)/target/h/wrn/coreip ;; \
diff --git a/libgcc/config/t-vxworks7 b/libgcc/config/t-vxworks7
index ae1dff9..f0293fe 100644
--- a/libgcc/config/t-vxworks7
+++ b/libgcc/config/t-vxworks7
@@ -7,9 +7,11 @@ LIB2ADDEH += $(srcdir)/config/vxlib.c $(srcdir)/config/vxlib-tls.c
# This ensures that the correct target headers are used; some VxWorks
# system headers have names that collide with GCC's internal (host)
# headers, e.g. regs.h. Make sure the local libgcc headers still
-# prevail (e.g. unwind.h).
-LIBGCC2_INCLUDES = -nostdinc \
- -I. -I$(VSB_DIR)/h -I$(VSB_DIR)/share/h \
+# prevail (e.g. unwind.h), and that gcc provided header files intended
+# to be user visible eventually are visible as well.
+LIBGCC2_INCLUDES = -nostdinc -I. \
+ -I$(VSB_DIR)/h -I$(VSB_DIR)/share/h \
+ -I$(MULTIBUILDTOP)../../gcc/include \
`case "/$(MULTIDIR)" in \
*/mrtp*) echo -I$(VSB_DIR)/usr/h/public -I$(VSB_DIR)/usr/h ;; \
*) echo -I$(VSB_DIR)/krnl/h/system -I$(VSB_DIR)/krnl/h/public ;; \
diff --git a/libgcc/configure b/libgcc/configure
index 3241f19..b2f3f87 100644
--- a/libgcc/configure
+++ b/libgcc/configure
@@ -1316,8 +1316,7 @@ Optional Features:
enable decimal float extension to C. Selecting 'bid'
or 'dpd' choses which decimal floating point format
to use
- --enable-cet enable Intel CET in target libraries
- [default=default]
+ --enable-cet enable Intel CET in target libraries [default=no]
--enable-explicit-exception-frame-registration
register exception tables explicitly at module
start, for use e.g. for compatibility with
@@ -4781,12 +4780,12 @@ $as_echo "$ac_cv_sjlj_exceptions" >&6; }
if test "${enable_cet+set}" = set; then :
enableval=$enable_cet;
case "$enableval" in
- yes|no|default) ;;
+ yes|no|auto) ;;
*) as_fn_error "Unknown argument to enable/disable cet" "$LINENO" 5 ;;
esac
else
- enable_cet=default
+ enable_cet=no
fi
@@ -4796,7 +4795,7 @@ $as_echo_n "checking for CET support... " >&6; }
case "$host" in
i[34567]86-*-linux* | x86_64-*-linux*)
case "$enable_cet" in
- default)
+ auto)
# Check if target supports multi-byte NOPs
# and if assembler supports CET insn.
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -4850,7 +4849,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
;;
esac
if test x$enable_cet = xyes; then
- CET_FLAGS="-fcf-protection -mcet"
+ CET_FLAGS="-fcf-protection -mshstk"
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
else
@@ -5214,11 +5213,47 @@ $as_echo "$libgcc_cv_hidden_visibility_attribute" >&6; }
if test $libgcc_cv_hidden_visibility_attribute = yes; then
vis_hide='-fvisibility=hidden -DHIDE_EXPORTS'
+
+cat >>confdefs.h <<_ACEOF
+#define AS_HIDDEN_DIRECTIVE $asm_hidden_op
+_ACEOF
+
else
vis_hide=
fi
+# Check for .cfi_sections .debug_frame support.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for .cfi_sections .debug_frame" >&5
+$as_echo_n "checking for .cfi_sections .debug_frame... " >&6; }
+if test "${libgcc_cv_cfi_sections_directive+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ echo 'int foo (int, char *);' > conftest.c
+ echo 'int bar (int x) { char *y = __builtin_alloca (x); return foo (x + 1, y) + 1; }' >> conftest.c
+ libgcc_cv_cfi_sections_directive=no
+ if { ac_try='${CC-cc} -Werror -g -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-exceptions -S conftest.c -o conftest.s 1>&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then
+ if grep "\\.cfi_sections.*\\.debug_frame" conftest.s >/dev/null; then
+ libgcc_cv_cfi_sections_directive=yes
+ fi
+ fi
+ rm -f conftest.*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgcc_cv_cfi_sections_directive" >&5
+$as_echo "$libgcc_cv_cfi_sections_directive" >&6; }
+if test $libgcc_cv_cfi_sections_directive = yes; then
+
+$as_echo "#define HAVE_AS_CFI_SECTIONS 1" >>confdefs.h
+
+fi
+
# See if we have thread-local storage. We can only test assembler
# since link-time and run-time tests require the newly built
# gcc, which can't be used to build executable due to that libgcc
@@ -5427,7 +5462,7 @@ esac
# Check whether --with-gcc-major-version-only was given.
if test "${with_gcc_major_version_only+set}" = set; then :
withval=$with_gcc_major_version_only; if test x$with_gcc_major_version_only = xyes ; then
- get_gcc_base_ver="sed -e 's/^\([0-9]*\).*\$\$/\1/'"
+ get_gcc_base_ver="sed -e 's/^\([0-9]*\).*/\1/'"
fi
fi
diff --git a/libgcc/configure.ac b/libgcc/configure.ac
index 6e76a68..b59aa74 100644
--- a/libgcc/configure.ac
+++ b/libgcc/configure.ac
@@ -486,11 +486,29 @@ AC_CACHE_CHECK([for __attribute__((visibility("hidden")))],
if test $libgcc_cv_hidden_visibility_attribute = yes; then
vis_hide='-fvisibility=hidden -DHIDE_EXPORTS'
+ AC_DEFINE_UNQUOTED(AS_HIDDEN_DIRECTIVE, $asm_hidden_op, [Define to the .hidden-like directive if it exists.])
else
vis_hide=
fi
AC_SUBST(vis_hide)
+# Check for .cfi_sections .debug_frame support.
+AC_CACHE_CHECK([for .cfi_sections .debug_frame],
+ libgcc_cv_cfi_sections_directive, [
+ echo 'int foo (int, char *);' > conftest.c
+ echo 'int bar (int x) { char *y = __builtin_alloca (x); return foo (x + 1, y) + 1; }' >> conftest.c
+ libgcc_cv_cfi_sections_directive=no
+ if AC_TRY_COMMAND(${CC-cc} -Werror -g -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-exceptions -S conftest.c -o conftest.s 1>&AS_MESSAGE_LOG_FD); then
+ if grep "\\.cfi_sections.*\\.debug_frame" conftest.s >/dev/null; then
+ libgcc_cv_cfi_sections_directive=yes
+ fi
+ fi
+ rm -f conftest.*
+ ])
+if test $libgcc_cv_cfi_sections_directive = yes; then
+ AC_DEFINE(HAVE_AS_CFI_SECTIONS, 1, [Define to 1 if the assembler supports .cfi_sections .debug_frame directive.])
+fi
+
# See if we have thread-local storage. We can only test assembler
# since link-time and run-time tests require the newly built
# gcc, which can't be used to build executable due to that libgcc
diff --git a/libgcc/crtstuff.c b/libgcc/crtstuff.c
index 5e89445..d81c527 100644
--- a/libgcc/crtstuff.c
+++ b/libgcc/crtstuff.c
@@ -188,9 +188,6 @@ extern void *__deregister_frame_info_bases (const void *)
TARGET_ATTRIBUTE_WEAK;
extern void __do_global_ctors_1 (void);
-/* Likewise for _Jv_RegisterClasses. */
-extern void _Jv_RegisterClasses (void *) TARGET_ATTRIBUTE_WEAK;
-
/* Likewise for transactional memory clone tables. */
extern void _ITM_registerTMCloneTable (void *, size_t) TARGET_ATTRIBUTE_WEAK;
extern void _ITM_deregisterTMCloneTable (void *) TARGET_ATTRIBUTE_WEAK;
diff --git a/libgcc/libgcov-driver-system.c b/libgcc/libgcov-driver-system.c
index 0df4423..8c1fef0 100644
--- a/libgcc/libgcov-driver-system.c
+++ b/libgcc/libgcov-driver-system.c
@@ -62,8 +62,16 @@ gcov_error (const char *fmt, ...)
va_list argp;
va_start (argp, fmt);
- ret = vfprintf (get_gcov_error_file (), fmt, argp);
+ FILE *f = get_gcov_error_file ();
+ ret = vfprintf (f, fmt, argp);
va_end (argp);
+
+ if (getenv ("GCOV_EXIT_AT_ERROR"))
+ {
+ fprintf (f, "profiling:exiting after an error\n");
+ exit (1);
+ }
+
return ret;
}
@@ -128,12 +136,84 @@ create_file_directory (char *filename)
#endif
}
+/* Replace filename variables in FILENAME. We currently support expansion:
+
+ %p - process ID
+ %q{ENV} - value of environment variable ENV
+ */
+
+static char *
+replace_filename_variables (char *filename)
+{
+ char buffer[16];
+ char empty[] = "";
+ for (char *p = filename; *p != '\0'; p++)
+ {
+ unsigned length = strlen (filename);
+ if (*p == '%' && *(p + 1) != '\0')
+ {
+ unsigned start = p - filename;
+ p++;
+ char *replacement = NULL;
+ switch (*p)
+ {
+ case 'p':
+ sprintf (buffer, "%d", getpid ());
+ replacement = buffer;
+ p++;
+ break;
+ case 'q':
+ if (*(p + 1) == '{')
+ {
+ p += 2;
+ char *e = strchr (p, '}');
+ if (e)
+ {
+ *e = '\0';
+ replacement = getenv (p);
+ if (replacement == NULL)
+ replacement = empty;
+ p = e + 1;
+ }
+ else
+ return filename;
+ }
+ break;
+ default:
+ return filename;
+ }
+
+ /* Concat beginning of the path, replacement and
+ ending of the path. */
+ unsigned end = length - (p - filename);
+ unsigned repl_length = strlen (replacement);
+
+ char *buffer = (char *)xmalloc (start + end + repl_length + 1);
+ char *buffer_ptr = buffer;
+ buffer_ptr = (char *)memcpy (buffer_ptr, filename, start);
+ buffer_ptr += start;
+ buffer_ptr = (char *)memcpy (buffer_ptr, replacement, repl_length);
+ buffer_ptr += repl_length;
+ buffer_ptr = (char *)memcpy (buffer_ptr, p, end);
+ buffer_ptr += end;
+ *buffer_ptr = '\0';
+
+ free (filename);
+ filename = buffer;
+ p = buffer + start + repl_length;
+ }
+ }
+
+ return filename;
+}
+
static void
allocate_filename_struct (struct gcov_filename *gf)
{
const char *gcov_prefix;
size_t prefix_length;
int strip = 0;
+ gf->filename = NULL;
{
/* Check if the level of dirs to strip off specified. */
@@ -163,12 +243,16 @@ allocate_filename_struct (struct gcov_filename *gf)
gcov_prefix = ".";
prefix_length = 1;
}
- gf->prefix = prefix_length;
/* Allocate and initialize the filename scratch space. */
- gf->filename = (char *) xmalloc (gf->max_length + prefix_length + 2);
if (prefix_length)
- memcpy (gf->filename, gcov_prefix, prefix_length);
+ {
+ gf->prefix = (char *) xmalloc (prefix_length + 1);
+ char *p = (char *) memcpy (gf->prefix, gcov_prefix, prefix_length);
+ *(p + prefix_length) = '\0';
+ }
+ else
+ gf->prefix = NULL;
}
/* Open a gcda file specified by GI_FILENAME.
@@ -179,7 +263,7 @@ gcov_exit_open_gcda_file (struct gcov_info *gi_ptr,
struct gcov_filename *gf)
{
const char *fname = gi_ptr->filename;
- char *dst = gf->filename + gf->prefix;
+ int append_slash = 0;
fname = gi_ptr->filename;
@@ -212,9 +296,19 @@ gcov_exit_open_gcda_file (struct gcov_info *gi_ptr,
fname += 2;
if (!IS_DIR_SEPARATOR (*fname))
- *dst++ = '/';
+ append_slash = 1;
}
- strcpy (dst, fname);
+
+ size_t prefix_length = gf->prefix ? strlen (gf->prefix) : 0;
+ gf->filename = (char *) xmalloc (prefix_length + strlen (fname) + 2);
+ *gf->filename = '\0';
+ if (prefix_length)
+ strcat (gf->filename, gf->prefix);
+ if (append_slash)
+ *gf->filename++ = '/';
+ strcat (gf->filename, fname);
+
+ gf->filename = replace_filename_variables (gf->filename);
if (!gcov_open (gf->filename))
{
diff --git a/libgcc/libgcov-driver.c b/libgcc/libgcov-driver.c
index b4f195b..1f2c4a7 100644
--- a/libgcc/libgcov-driver.c
+++ b/libgcc/libgcov-driver.c
@@ -72,9 +72,8 @@ struct gcov_summary_buffer
struct gcov_filename
{
char *filename; /* filename buffer */
- size_t max_length; /* maximum filename length */
int strip; /* leading chars to strip from filename */
- size_t prefix; /* chars to prepend to filename */
+ char *prefix; /* prefix string */
};
static struct gcov_fn_buffer *
@@ -221,40 +220,24 @@ gcov_compute_histogram (struct gcov_info *list, struct gcov_summary *sum)
struct gcov_info *gi_ptr;
const struct gcov_fn_info *gfi_ptr;
const struct gcov_ctr_info *ci_ptr;
- struct gcov_ctr_summary *cs_ptr;
- unsigned t_ix, f_ix, ctr_info_ix, ix;
+ unsigned f_ix, ix;
int h_ix;
- /* This currently only applies to arc counters. */
- t_ix = GCOV_COUNTER_ARCS;
-
/* First check if there are any counts recorded for this counter. */
- cs_ptr = &(sum->ctrs[t_ix]);
- if (!cs_ptr->num)
+ if (!sum->num)
return;
for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++)
{
- cs_ptr->histogram[h_ix].num_counters = 0;
- cs_ptr->histogram[h_ix].min_value = cs_ptr->run_max;
- cs_ptr->histogram[h_ix].cum_value = 0;
+ sum->histogram[h_ix].num_counters = 0;
+ sum->histogram[h_ix].min_value = sum->run_max;
+ sum->histogram[h_ix].cum_value = 0;
}
/* Walk through all the per-object structures and record each of
the count values in histogram. */
for (gi_ptr = list; gi_ptr; gi_ptr = gi_ptr->next)
{
- if (!gi_ptr->merge[t_ix])
- continue;
-
- /* Find the appropriate index into the gcov_ctr_info array
- for the counter we are currently working on based on the
- existence of the merge function pointer for this object. */
- for (ix = 0, ctr_info_ix = 0; ix < t_ix; ix++)
- {
- if (gi_ptr->merge[ix])
- ctr_info_ix++;
- }
for (f_ix = 0; f_ix != gi_ptr->n_functions; f_ix++)
{
gfi_ptr = gi_ptr->functions[f_ix];
@@ -262,9 +245,9 @@ gcov_compute_histogram (struct gcov_info *list, struct gcov_summary *sum)
if (!gfi_ptr || gfi_ptr->key != gi_ptr)
continue;
- ci_ptr = &gfi_ptr->ctrs[ctr_info_ix];
- for (ix = 0; ix < ci_ptr->num; ix++)
- gcov_histogram_insert (cs_ptr->histogram, ci_ptr->values[ix]);
+ ci_ptr = &gfi_ptr->ctrs[0];
+ for (ix = 0; ix < ci_ptr->num; ix++)
+ gcov_histogram_insert (sum->histogram, ci_ptr->values[ix]);
}
}
}
@@ -275,34 +258,25 @@ static struct gcov_fn_buffer *fn_buffer;
static struct gcov_summary_buffer *sum_buffer;
/* This function computes the program level summary and the histo-gram.
- It computes and returns CRC32 and stored summary in THIS_PRG.
- Also determines the longest filename length of the info files. */
+ It computes and returns CRC32 and stored summary in THIS_PRG. */
#if !IN_GCOV_TOOL
static
#endif
gcov_unsigned_t
-compute_summary (struct gcov_info *list, struct gcov_summary *this_prg,
- size_t *max_length)
+compute_summary (struct gcov_info *list, struct gcov_summary *this_prg)
{
struct gcov_info *gi_ptr;
const struct gcov_fn_info *gfi_ptr;
- struct gcov_ctr_summary *cs_ptr;
const struct gcov_ctr_info *ci_ptr;
int f_ix;
- unsigned t_ix;
gcov_unsigned_t c_num;
gcov_unsigned_t crc32 = 0;
/* Find the totals for this execution. */
memset (this_prg, 0, sizeof (*this_prg));
- *max_length = 0;
for (gi_ptr = list; gi_ptr; gi_ptr = gi_ptr->next)
{
- size_t len = strlen (gi_ptr->filename);
- if (len > *max_length)
- *max_length = len;
-
crc32 = crc32_unsigned (crc32, gi_ptr->stamp);
crc32 = crc32_unsigned (crc32, gi_ptr->n_functions);
@@ -319,25 +293,18 @@ compute_summary (struct gcov_info *list, struct gcov_summary *this_prg,
if (!gfi_ptr)
continue;
- ci_ptr = gfi_ptr->ctrs;
- for (t_ix = 0; t_ix != GCOV_COUNTERS_SUMMABLE; t_ix++)
- {
- if (!gi_ptr->merge[t_ix])
- continue;
-
- cs_ptr = &(this_prg->ctrs[t_ix]);
- cs_ptr->num += ci_ptr->num;
- crc32 = crc32_unsigned (crc32, ci_ptr->num);
-
- for (c_num = 0; c_num < ci_ptr->num; c_num++)
- {
- cs_ptr->sum_all += ci_ptr->values[c_num];
- if (cs_ptr->run_max < ci_ptr->values[c_num])
- cs_ptr->run_max = ci_ptr->values[c_num];
- }
- ci_ptr++;
- }
- }
+ ci_ptr = gfi_ptr->ctrs;
+ this_prg->num += ci_ptr->num;
+ crc32 = crc32_unsigned (crc32, ci_ptr->num);
+
+ for (c_num = 0; c_num < ci_ptr->num; c_num++)
+ {
+ this_prg->sum_all += ci_ptr->values[c_num];
+ if (this_prg->run_max < ci_ptr->values[c_num])
+ this_prg->run_max = ci_ptr->values[c_num];
+ }
+ ci_ptr++;
+ }
}
gcov_compute_histogram (list, this_prg);
return crc32;
@@ -372,8 +339,12 @@ merge_one_data (const char *filename,
length = gcov_read_unsigned ();
if (length != gi_ptr->stamp)
- /* Read from a different compilation. Overwrite the file. */
- return 0;
+ {
+ /* Read from a different compilation. Overwrite the file. */
+ gcov_error ("profiling:%s:overwriting an existing profile data "
+ "with a different timestamp\n", filename);
+ return 0;
+ }
/* Look for program summary. */
for (f_ix = 0;;)
@@ -407,9 +378,8 @@ merge_one_data (const char *filename,
if (tmp.checksum != crc32)
goto next_summary;
- for (t_ix = 0; t_ix != GCOV_COUNTERS_SUMMABLE; t_ix++)
- if (tmp.ctrs[t_ix].num != this_prg->ctrs[t_ix].num)
- goto next_summary;
+ if (tmp.num != this_prg->num)
+ goto next_summary;
*prg_p = tmp;
*summary_pos_p = *eof_pos_p;
@@ -596,77 +566,60 @@ write_one_data (const struct gcov_info *gi_ptr,
Return -1 on error. Return 0 on success. */
static int
-merge_summary (const char *filename, int run_counted,
- const struct gcov_info *gi_ptr, struct gcov_summary *prg,
+merge_summary (const char *filename __attribute__ ((unused)), int run_counted,
+ struct gcov_summary *prg,
struct gcov_summary *this_prg, gcov_unsigned_t crc32,
struct gcov_summary *all_prg __attribute__ ((unused)))
{
- struct gcov_ctr_summary *cs_prg, *cs_tprg;
- unsigned t_ix;
#if !GCOV_LOCKED
/* summary for all instances of program. */
- struct gcov_ctr_summary *cs_all;
+ struct gcov_summary *all;
#endif
- /* Merge the summaries. */
- for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++)
- {
- cs_prg = &(prg->ctrs[t_ix]);
- cs_tprg = &(this_prg->ctrs[t_ix]);
-
- if (gi_ptr->merge[t_ix])
- {
- int first = !cs_prg->runs;
-
- if (!run_counted)
- cs_prg->runs++;
- if (first)
- cs_prg->num = cs_tprg->num;
- cs_prg->sum_all += cs_tprg->sum_all;
- if (cs_prg->run_max < cs_tprg->run_max)
- cs_prg->run_max = cs_tprg->run_max;
- cs_prg->sum_max += cs_tprg->run_max;
- if (first)
- memcpy (cs_prg->histogram, cs_tprg->histogram,
- sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE);
- else
- gcov_histogram_merge (cs_prg->histogram, cs_tprg->histogram);
- }
- else if (cs_prg->runs)
- {
- gcov_error ("profiling:%s:Merge mismatch for summary.\n",
- filename);
- return -1;
- }
+ /* Merge the summary. */
+ int first = !prg->runs;
+
+ if (!run_counted)
+ prg->runs++;
+ if (first)
+ prg->num = this_prg->num;
+ prg->sum_all += this_prg->sum_all;
+ if (prg->run_max < this_prg->run_max)
+ prg->run_max = this_prg->run_max;
+ prg->sum_max += this_prg->run_max;
+ if (first)
+ memcpy (prg->histogram, this_prg->histogram,
+ sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE);
+ else
+ gcov_histogram_merge (prg->histogram, this_prg->histogram);
#if !GCOV_LOCKED
- cs_all = &all_prg->ctrs[t_ix];
- if (!cs_all->runs && cs_prg->runs)
- {
- cs_all->num = cs_prg->num;
- cs_all->runs = cs_prg->runs;
- cs_all->sum_all = cs_prg->sum_all;
- cs_all->run_max = cs_prg->run_max;
- cs_all->sum_max = cs_prg->sum_max;
- }
- else if (!all_prg->checksum
- /* Don't compare the histograms, which may have slight
- variations depending on the order they were updated
- due to the truncating integer divides used in the
- merge. */
- && (cs_all->num != cs_prg->num
- || cs_all->runs != cs_prg->runs
- || cs_all->sum_all != cs_prg->sum_all
- || cs_all->run_max != cs_prg->run_max
- || cs_all->sum_max != cs_prg->sum_max))
- {
- gcov_error ("profiling:%s:Data file mismatch - some "
- "data files may have been concurrently "
- "updated without locking support\n", filename);
- all_prg->checksum = ~0u;
- }
-#endif
+ all = all_prg;
+ if (!all->runs && prg->runs)
+ {
+ all->num = prg->num;
+ all->runs = prg->runs;
+ all->sum_all = prg->sum_all;
+ all->run_max = prg->run_max;
+ all->sum_max = prg->sum_max;
}
-
+ else if (!all_prg->checksum
+ /* Don't compare the histograms, which may have slight
+ variations depending on the order they were updated
+ due to the truncating integer divides used in the
+ merge. */
+ && (all->num != prg->num
+ || all->runs != prg->runs
+ || all->sum_all != prg->sum_all
+ || all->run_max != prg->run_max
+ || all->sum_max != prg->sum_max))
+ {
+ gcov_error ("profiling:%s:Data file mismatch - some "
+ "data files may have been concurrently "
+ "updated without locking support\n", filename);
+ all_prg->checksum = ~0u;
+ }
+#endif
+
prg->checksum = crc32;
return 0;
@@ -802,7 +755,7 @@ dump_one_gcov (struct gcov_info *gi_ptr, struct gcov_filename *gf,
summary_pos = eof_pos;
}
- error = merge_summary (gf->filename, run_counted, gi_ptr, &prg, this_prg,
+ error = merge_summary (gf->filename, run_counted, &prg, this_prg,
crc32, all_prg);
if (error == -1)
goto read_fatal;
@@ -838,7 +791,7 @@ gcov_do_dump (struct gcov_info *list, int run_counted)
struct gcov_summary all_prg;
struct gcov_summary this_prg;
- crc32 = compute_summary (list, &this_prg, &gf.max_length);
+ crc32 = compute_summary (list, &this_prg);
allocate_filename_struct (&gf);
#if !GCOV_LOCKED
@@ -847,9 +800,12 @@ gcov_do_dump (struct gcov_info *list, int run_counted)
/* Now merge each file. */
for (gi_ptr = list; gi_ptr; gi_ptr = gi_ptr->next)
- dump_one_gcov (gi_ptr, &gf, run_counted, crc32, &all_prg, &this_prg);
+ {
+ dump_one_gcov (gi_ptr, &gf, run_counted, crc32, &all_prg, &this_prg);
+ free (gf.filename);
+ }
- free (gf.filename);
+ free (gf.prefix);
}
#if IN_GCOV_TOOL
diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index 9cf56a8..37dd186 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -930,24 +930,13 @@ compute_one_gcov (const struct gcov_info *gcov_info1,
{
for (f_ix = 0; f_ix < gcov_info->n_functions; f_ix++)
{
- unsigned t_ix;
const struct gcov_fn_info *gfi_ptr = gcov_info->functions[f_ix];
if (!gfi_ptr || gfi_ptr->key != gcov_info)
continue;
const struct gcov_ctr_info *ci_ptr = gfi_ptr->ctrs;
- for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++)
- {
- unsigned c_num;
-
- if (!gcov_info->merge[t_ix])
- continue;
-
- for (c_num = 0; c_num < ci_ptr->num; c_num++)
- {
- cum_1 += ci_ptr->values[c_num] / sum;
- }
- ci_ptr++;
- }
+ unsigned c_num;
+ for (c_num = 0; c_num < ci_ptr->num; c_num++)
+ cum_1 += ci_ptr->values[c_num] / sum;
}
*cum_p = cum_1;
return 0.0;
@@ -955,7 +944,6 @@ compute_one_gcov (const struct gcov_info *gcov_info1,
for (f_ix = 0; f_ix < gcov_info1->n_functions; f_ix++)
{
- unsigned t_ix;
double func_cum_1 = 0.0;
double func_cum_2 = 0.0;
double func_val = 0.0;
@@ -971,32 +959,24 @@ compute_one_gcov (const struct gcov_info *gcov_info1,
const struct gcov_ctr_info *ci_ptr1 = gfi_ptr1->ctrs;
const struct gcov_ctr_info *ci_ptr2 = gfi_ptr2->ctrs;
- for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++)
- {
- unsigned c_num;
+ unsigned c_num;
+ for (c_num = 0; c_num < ci_ptr1->num; c_num++)
+ {
+ if (ci_ptr1->values[c_num] | ci_ptr2->values[c_num])
+ {
+ func_val += calculate_2_entries (ci_ptr1->values[c_num],
+ ci_ptr2->values[c_num],
+ sum_1, sum_2);
+
+ func_cum_1 += ci_ptr1->values[c_num] / sum_1;
+ func_cum_2 += ci_ptr2->values[c_num] / sum_2;
+ nonzero = 1;
+ if (ci_ptr1->values[c_num] / sum_1 >= overlap_hot_threshold
+ || ci_ptr2->values[c_num] / sum_2 >= overlap_hot_threshold)
+ hot = 1;
+ }
+ }
- if (!gcov_info1->merge[t_ix])
- continue;
-
- for (c_num = 0; c_num < ci_ptr1->num; c_num++)
- {
- if (ci_ptr1->values[c_num] | ci_ptr2->values[c_num])
- {
- func_val += calculate_2_entries (ci_ptr1->values[c_num],
- ci_ptr2->values[c_num],
- sum_1, sum_2);
-
- func_cum_1 += ci_ptr1->values[c_num] / sum_1;
- func_cum_2 += ci_ptr2->values[c_num] / sum_2;
- nonzero = 1;
- if (ci_ptr1->values[c_num] / sum_1 >= overlap_hot_threshold ||
- ci_ptr2->values[c_num] / sum_2 >= overlap_hot_threshold)
- hot = 1;
- }
- }
- ci_ptr1++;
- ci_ptr2++;
- }
ret += func_val;
cum_1 += func_cum_1;
cum_2 += func_cum_2;
@@ -1023,26 +1003,14 @@ gcov_info_count_all_cold (const struct gcov_info *gcov_info,
for (f_ix = 0; f_ix < gcov_info->n_functions; f_ix++)
{
- unsigned t_ix;
const struct gcov_fn_info *gfi_ptr = gcov_info->functions[f_ix];
if (!gfi_ptr || gfi_ptr->key != gcov_info)
continue;
const struct gcov_ctr_info *ci_ptr = gfi_ptr->ctrs;
- for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++)
- {
- unsigned c_num;
-
- if (!gcov_info->merge[t_ix])
- continue;
-
- for (c_num = 0; c_num < ci_ptr->num; c_num++)
- {
- if (ci_ptr->values[c_num] > threshold)
- return false;
- }
- ci_ptr++;
- }
+ for (unsigned c_num = 0; c_num < ci_ptr->num; c_num++)
+ if (ci_ptr->values[c_num] > threshold)
+ return false;
}
return true;
@@ -1234,7 +1202,7 @@ matched_gcov_info (const struct gcov_info *info1, const struct gcov_info *info2)
/* Defined in libgcov-driver.c. */
extern gcov_unsigned_t compute_summary (struct gcov_info *,
- struct gcov_summary *, size_t *);
+ struct gcov_summary *);
/* Compute the overlap score of two profiles with the head of GCOV_LIST1 and
GCOV_LIST1. Return a number ranging from [0.0, 1.0], with 0.0 meaning no
@@ -1247,18 +1215,17 @@ calculate_overlap (struct gcov_info *gcov_list1,
struct gcov_summary this_prg;
unsigned list1_cnt = 0, list2_cnt= 0, all_cnt;
unsigned int i, j;
- size_t max_length;
const struct gcov_info *gi_ptr;
struct overlap_t *all_infos;
- compute_summary (gcov_list1, &this_prg, &max_length);
- overlap_sum_1 = (double) (this_prg.ctrs[0].sum_all);
- p1_sum_all = this_prg.ctrs[0].sum_all;
- p1_run_max = this_prg.ctrs[0].run_max;
- compute_summary (gcov_list2, &this_prg, &max_length);
- overlap_sum_2 = (double) (this_prg.ctrs[0].sum_all);
- p2_sum_all = this_prg.ctrs[0].sum_all;
- p2_run_max = this_prg.ctrs[0].run_max;
+ compute_summary (gcov_list1, &this_prg);
+ overlap_sum_1 = (double) (this_prg.sum_all);
+ p1_sum_all = this_prg.sum_all;
+ p1_run_max = this_prg.run_max;
+ compute_summary (gcov_list2, &this_prg);
+ overlap_sum_2 = (double) (this_prg.sum_all);
+ p2_sum_all = this_prg.sum_all;
+ p2_run_max = this_prg.run_max;
for (gi_ptr = gcov_list1; gi_ptr; gi_ptr = gi_ptr->next)
list1_cnt++;
diff --git a/libgcc/unwind-generic.h b/libgcc/unwind-generic.h
index b5e3568..639c96f 100644
--- a/libgcc/unwind-generic.h
+++ b/libgcc/unwind-generic.h
@@ -291,4 +291,7 @@ EXCEPTION_DISPOSITION _GCC_specific_handler (PEXCEPTION_RECORD, void *,
/* Additional actions to unwind number of stack frames. */
#define _Unwind_Frames_Extra(frames)
+/* Increment frame count. */
+#define _Unwind_Frames_Increment(context, frames) frames++
+
#endif /* unwind.h */
diff --git a/libgcc/unwind.inc b/libgcc/unwind.inc
index 68c0896..19a8e4f 100644
--- a/libgcc/unwind.inc
+++ b/libgcc/unwind.inc
@@ -73,7 +73,7 @@ _Unwind_RaiseException_Phase2(struct _Unwind_Exception *exc,
gcc_assert (!match_handler);
uw_update_context (context, &fs);
- frames++;
+ _Unwind_Frames_Increment (context, frames);
}
*frames_p = frames;
@@ -190,7 +190,7 @@ _Unwind_ForcedUnwind_Phase2 (struct _Unwind_Exception *exc,
/* Update cur_context to describe the same frame as fs, and discard
the previous context if necessary. */
uw_advance_context (context, &fs);
- frames++;
+ _Unwind_Frames_Increment (context, frames);
}
*frames_p = frames;