diff options
author | Aldy Hernandez <aldyh@redhat.com> | 2020-06-17 07:50:57 -0400 |
---|---|---|
committer | Aldy Hernandez <aldyh@redhat.com> | 2020-06-17 07:50:57 -0400 |
commit | b9e67f2840ce0d8859d96e7f8df8fe9584af5eba (patch) | |
tree | ed3b7284ff15c802583f6409b9c71b3739642d15 /libgcc | |
parent | 1957047ed1c94bf17cf993a2b1866965f493ba87 (diff) | |
parent | 56638b9b1853666f575928f8baf17f70e4ed3517 (diff) | |
download | gcc-b9e67f2840ce0d8859d96e7f8df8fe9584af5eba.zip gcc-b9e67f2840ce0d8859d96e7f8df8fe9584af5eba.tar.gz gcc-b9e67f2840ce0d8859d96e7f8df8fe9584af5eba.tar.bz2 |
Merge from trunk at:
commit 56638b9b1853666f575928f8baf17f70e4ed3517
Author: GCC Administrator <gccadmin@gcc.gnu.org>
Date: Wed Jun 17 00:16:36 2020 +0000
Daily bump.
Diffstat (limited to 'libgcc')
62 files changed, 1740 insertions, 706 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 08e96e5..63167c3 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,426 @@ +2020-06-15 Max Filippov <jcmvbkbc@gmail.com> + + * configure: Regenerate. + * configure.ac: Use AC_COMPILE_IFELSE instead of manual + preprocessor invocation to check for __XTENSA_CALL0_ABI__. + +2020-06-09 Martin Liska <mliska@suse.cz> + + PR gcov-profile/95494 + * libgcov-driver.c (write_top_counters): Cast first to + intptr_t as sizeof(*) != sizeof(gcov_type). + * libgcov.h (gcov_counter_set_if_null): Remove. + (gcov_topn_add_value): Cast first to intptr_t and update + linked list directly. + +2020-06-09 Max Filippov <jcmvbkbc@gmail.com> + + * config/xtensa/unwind-dw2-xtensa.c (uw_install_context): Merge + with uw_install_context_1. + +2020-06-04 Andreas Schwab <schwab@suse.de> + + PR target/59230 + PR libfortran/59227 + * config/ia64/t-softfp-compat (softfp_file_list): Filter out + soft-fp/divtf3.c. + (LIB2ADD): Add config/ia64/divtf3.c. + * config/ia64/divtf3.c: New file. + +2020-06-03 Martin Liska <mliska@suse.cz> + + PR gcov-profile/95480 + * libgcov-profiler.c (GCOV_SUPPORTS_ATOMIC): Move to... + * libgcov.h (GCOV_SUPPORTS_ATOMIC): ...here. + (gcov_counter_add): Use GCOV_SUPPORTS_ATOMIC guard. + (gcov_counter_set_if_null): Likewise. + +2020-06-02 Jim Wilson <jimw@sifive.com> + + * config/riscv/div.S (__divdi3): For negative arguments, change bgez + to bgtz. + +2020-06-02 Martin Liska <mliska@suse.cz> + + * libgcov.h (gcov_topn_add_value): Use xcalloc instead + of xmalloc. + +2020-06-02 Martin Liska <mliska@suse.cz> + + * libgcov-driver.c (prune_topn_counter): Remove. + (prune_counters): Likewise. + (merge_one_data): Special case TOP N counters + as they have variable length. + (write_top_counters): New. + (write_one_data): Special case TOP N. + (dump_one_gcov): Do not prune TOP N counters. + * libgcov-merge.c (merge_topn_values_set): Remove. + (__gcov_merge_topn): Use gcov_topn_add_value. + * libgcov-profiler.c (__gcov_topn_values_profiler_body): + Likewise here. + * libgcov.h (gcov_counter_add): New. + (gcov_counter_set_if_null): Likewise. + (gcov_topn_add_value): New. + +2020-06-01 Uroš Bizjak <ubizjak@gmail.com> + + * config/i386/sfp-exceptions.c (struct fenv): + Add __attribute__ ((gcc_struct)). + +2020-05-29 H.J. Lu <hjl.tools@gmail.com> + + PR bootstrap/95413 + * configure: Regenerated. + +2020-05-28 Dong JianQiang <dongjianqiang2@huawei.com> + + PR gcov-profile/95332 + * libgcov-util.c (read_gcda_file): Call gcov_magic. + * libgcov.h (gcov_magic): Disable GCC poison. + +2020-05-21 H.J. Lu <hongjiu.lu@intel.com> + + PR target/95212 + * config/i386/cpuinfo.h (processor_features): Move + FEATURE_AVX512VP2INTERSECT after FEATURE_AVX512BF16. + +2020-05-20 H.J. Lu <hongjiu.lu@intel.com> + + PR target/91695 + * config/i386/cpuinfo.c (get_available_features): Fix VPCLMULQDQ + check. + +2020-05-19 H.J. Lu <hongjiu.lu@intel.com> + + PR target/95212 + PR target/95220 + * config/i386/cpuinfo.c (get_available_features): Fix + FEATURE_GFNI check. Also check FEATURE_AVX512VP2INTERSECT. + * config/i386/cpuinfo.h (processor_features): Add + FEATURE_AVX512VP2INTERSECT. + +2020-05-15 H.J. Lu <hongjiu.lu@intel.com> + + PR bootstrap/95147 + * configure: Regenerated. + +2020-05-14 H.J. Lu <hongjiu.lu@intel.com> + + * configure: Regenerated. + +2020-05-09 Hans-Peter Nilsson <hp@axis.com> + + * config.host: Remove support for crisv32-*-* and cris*-*-linux. + * config/cris/libgcc-glibc.ver, config/cris/t-linux: Remove. + +2020-05-06 Uroš Bizjak <ubizjak@gmail.com> + + * config/i386/sfp-exceptions.c (__math_force_eval): Remove. + (__math_force_eval_div): New define. + (__sfp_handle_exceptions): Use __math_force_eval_div to use + generic division to generate INVALID, DIVZERO and INEXACT + exceptions. + +2020-05-06 Kyrylo Tkachov <kyrylo.tkachov@arm.com> + + * config/aarch64/lse-init.c (init_have_lse_atomics): Use __getauxval + instead of getauxval. + (AT_HWCAP): Define. + (HWCAP_ATOMICS): Define. + Guard detection on __gnu_linux__. + +2020-05-05 Michael Meissner <meissner@linux.ibm.com> + + * config.host: Delete changes meant for a private branch. + * config/rs6000/t-float128: Likewise. + * configure.ac: Likewise. + * configure: Likewise. + +2020-05-05 Martin Liska <mliska@suse.cz> + + PR gcov-profile/93623 + * Makefile.in: Remove __gcov_flush. + * gcov.h (__gcov_flush): Remove. + * libgcov-interface.c (__gcov_flush): Remove. + (init_mx): Use renamed mutex. + (__gcov_lock): Likewise. + (__gcov_unlock): Likewise. + (__gcov_fork): Likewise. + (__gcov_flush): Remove. + +2020-05-05 Martin Liska <mliska@suse.cz> + + PR gcov-profile/93623 + * libgcov-interface.c (__gcov_fork): Do not flush + and reset only in child process. + (__gcov_execl): Dump counters only and reset them + only if exec* fails. + (__gcov_execlp): Likewise. + (__gcov_execle): Likewise. + (__gcov_execv): Likewise. + (__gcov_execvp): Likewise. + (__gcov_execve): Likewise. + +2020-05-05 Martin Liska <mliska@suse.cz> + + PR gcov-profile/93623 + * Makefile.in: Add _gcov_lock_unlock to LIBGCOV_INTERFACE. + * libgcov-interface.c (ALIAS_void_fn): Remove. + (__gcov_lock): New. + (__gcov_unlock): New. + (__gcov_flush): Use __gcov_lock and __gcov_unlock. + (__gcov_reset): Likewise. + (__gcov_dump): Likewise. + * libgcov.h (__gcov_lock): New declaration. + (__gcov_unlock): Likewise. + +2020-05-01 Uroš Bizjak <ubizjak@gmail.com> + + * config/i386/sfp-exceptions.c (__math_force_eval): New define. + (__sfp_handle_exceptions): Use __math_force_eval to evaluate + generic division to generate INVALID and DIVZERO exceptions. + +2020-04-27 Sebastian Huber <sebastian.huber@embedded-brains.de> + + * config/rs6000/crtresfpr.S: Use .machine ppc. + * config/rs6000/crtresxfpr.S: Likewise. + * config/rs6000/crtsavfpr.S: Likewise. + +2020-04-21 Szabolcs Nagy <szabolcs.nagy@arm.com> + + PR target/94514 + * config/aarch64/aarch64-unwind.h (aarch64_frob_update_context): + Update context->flags accroding to the frame state. + +2020-04-19 Uroš Bizjak <ubizjak@gmail.com> + + * config/i386/sfp-exceptions.c (__sfp_handle_exceptions) [__SSE_MATH__]: + Remove unneeded assignments to volatile memory. + +2020-04-15 Jakub Jelinek <jakub@redhat.com> + + PR target/93053 + * configure.ac (LIBGCC_CHECK_AS_LSE): Add HAVE_AS_LSE checking. + * config/aarch64/lse.S: Include auto-target.h, if HAVE_AS_LSE + is not defined, use just .arch armv8-a. + (B, M, N, OPN): Define. + (COMMENT): New .macro. + (CAS, CASP, SWP, LDOP): Use .inst directive if HAVE_AS_LSE is not + defined. Otherwise, move the operands right after the glue? and + comment out operands where the macros are used. + * configure: Regenerated. + * config.in: Regenerated. + +2020-04-07 Ian Lance Taylor <iant@golang.org> + + PR libgcc/94513 + * generic-morestack.c: Give up trying to use __mmap/__munmap, use + syscall instead. + +2020-04-04 Ian Lance Taylor <iant@golang.org> + + * generic-morestack.c: Only use __mmap on glibc >= 2.26. + +2020-04-03 Ian Lance Taylor <iant@golang.org> + + * generic-morestack.c: On GNU/Linux use __mmap/__munmap rather + than mmap/munmap, to avoid hooks. + +2020-04-03 Jim Johnston <jjohnst@us.ibm.com> + + * config/s390/tpf-unwind.h (MIN_PATRANGE, MAX_PATRANGE) + (TPFRA_OFFSET): Macros removed. + (CP_CNF, cinfc_fast, CINFC_CMRESET, CINTFC_CMCENBKST) + (CINTFC_CMCENBKED, ICST_CRET, ICST_SRET, LOWCORE_PAGE3_ADDR) + (PG3_SKIPPING_OFFSET): New macros. + (__isPATrange): Use cinfc_fast for the check. + (__isSkipResetAddr): New function. + (s390_fallback_frame_state): Check for skip trace addresses. Use + either ICST_CRET or ICST_SRET to calculate return address + location. + (__tpf_eh_return): Handle skip trace addresses. + +2020-03-26 Richard Earnshaw <rearnsha@arm.com> + + PR target/94220 + * config/arm/lib1funcs.asm (COND): Use a single definition for + unified syntax. + (aeabi_uidivmod): Unified syntax when optimizing Thumb for size. + (aeabi_idivmod): Likewise. + (divsi3_skip_div0_test): Likewise. + +2020-03-17 Mihail Ionescu <mihail.ionescu@arm.com> + + * config/arm/t-arm: Do not compile cmse_nonsecure_call.S for v8.1-m. + +2020-03-04 Andreas Krebbel <krebbel@linux.ibm.com> + + * config.host: Include the new makefile fragment. + * config/s390/t-tpf: New file. + +2020-03-03 Richard Earnshaw <rearnsha@arm.com> + + * config/arm/bpabi-v6m.S (aeabi_lcmp): Convert thumb1 code to unified + syntax. + (aeabi_ulcmp, aeabi_ldivmod, aeabi_uldivmod): Likewise. + (aeabi_frsub, aeabi_cfcmpeq, aeabi_fcmpeq): Likewise. + (aeabi_fcmp, aeabi_drsub, aeabi_cdrcmple): Likewise. + (aeabi_cdcmpeq, aeabi_dcmpeq, aeabi_dcmp): Likewise. + * config/arm/lib1funcs.S (Lend_fde): Convert thumb1 code to unified + syntax. + (divsi3, modsi3): Likewise. + (clzdi2, ctzsi2): Likewise. + * config/arm/libunwind.S (restore_core_regs): Convert thumb1 code to + unified syntax. + (UNWIND_WRAPPER): Likewise. + +2020-03-02 Martin Liska <mliska@suse.cz> + + * libgcov-interface.c: Remove duplicate + declaration of __gcov_flush_mx. + +2020-02-18 Martin Liska <mliska@suse.cz> + + PR ipa/92924 + * libgcov-merge.c (merge_topn_values_set): Record + when a TOP N counter becomes invalid. When merging + remove a smallest value if the space is needed. + +2020-02-12 Sandra Loosemore <sandra@codesourcery.com> + + PR libstdc++/79193 + PR libstdc++/88999 + + * configure: Regenerated. + +2020-02-10 Jeff Law <law@redhat.com> + + * config/frv/frvbegin.c: Use right flags for .ctors and .dtors + sections. + * config/frv/frvend.c: Similarly. + +2020-02-10 H.J. Lu <hongjiu.lu@intel.com> + + PR libgcc/85334 + * config/i386/shadow-stack-unwind.h (_Unwind_Frames_Increment): + New. + +2020-02-10 Christophe Lyon <christophe.lyon@linaro.org> + + PR target/93615 + * unwind-arm-common.inc: Replace uses of gnu_Unwind_Find_got with + _Unwind_gnu_Find_got. + * unwind-pe.h: Likewise. + +2020-02-07 Jakub Jelinek <jakub@redhat.com> + + PR target/93615 + * config/arm/unwind-arm.h (gnu_Unwind_Find_got): Rename to ... + (_Unwind_gnu_Find_got): ... this. Use __asm instead of asm. Remove + trailing :s in asm. Formatting fixes. + (_Unwind_decode_typeinfo_ptr): Adjust caller. + +2020-01-31 Sandra Loosemore <sandra@codesourcery.com> + + nios2: Support for GOT-relative DW_EH_PE_datarel encoding. + + * config.host [nios2-*-linux*] (tmake_file, tm_file): Adjust. + * config/nios2-elf-lib.h: New. + * unwind-dw2-fde-dip.c (_Unwind_IteratePhdrCallback): Use existing + code for finding GOT base for nios2. + +2020-01-27 Martin Liska <mliska@suse.cz> + + PR gcov-profile/93403 + * libgcov-profiler.c (__gcov_indirect_call_profiler_v4): + Call __gcov_indirect_call_profiler_body. + (__gcov_indirect_call_profiler_body): New. + (__gcov_indirect_call_profiler_v4_atomic): New. + * libgcov.h (__gcov_indirect_call_profiler_v4_atomic): + New declaration. + +2020-01-27 Claudiu Zissulescu <claziss@synopsys.com> + + * config/arc/crti.S: Add RF16 object attribute. + * config/arc/crtn.S: Likewise. + * config/arc/crttls.S: Likewise. + * config/arc/lib1funcs.S: Likewise. + * config/arc/fp-hack.h (ARC_OPTFPE): Define. + * config/arc/lib2funcs.c: New file. + * config/arc/t-arc: Add lib2funcs to LIB2ADD. + +2020-01-24 Maciej W. Rozycki <macro@wdc.com> + + * Makefile.in (configure_deps): Add `toolexeclibdir.m4'. + * configure.ac: Handle `--with-toolexeclibdir='. + * configure: Regenerate. + +2020-01-23 Dragan Mladjenovic <dmladjenovic@wavecomp.com> + + * config/mips/gnustack.h: Check for TARGET_LIBC_GNUSTACK also. + +2020-01-23 Dragan Mladjenovic <dmladjenovic@wavecomp.com> + + * config/mips/gnustack.h: New file. + * config/mips/crti.S: Include gnustack.h. + * config/mips/crtn.S: Likewise. + * config/mips/mips16.S: Likewise. + * config/mips/vr4120-div.S: Likewise. + +2020-01-23 Martin Liska <mliska@suse.cz> + + * libgcov-driver.c (prune_topn_counter): Remove + check for -1 as we only prune run-time counters + that do not generate an invalid state. + +2020-01-22 Martin Liska <mliska@suse.cz> + + PR tree-optimization/92924 + * libgcov-profiler.c (__gcov_topn_values_profiler_body): First + try to find an existing value, then find an empty slot + if not found. + +2020-01-22 Martin Liska <mliska@suse.cz> + + PR tree-optimization/92924 + * libgcov-driver.c (prune_topn_counter): New. + (prune_counters): Likewise. + (dump_one_gcov): Prune a run-time counter. + * libgcov-profiler.c (__gcov_topn_values_profiler_body): + For a known value, add GCOV_TOPN_VALUES to value. + Otherwise, decrement all counters by one. + +2020-01-18 Hans-Peter Nilsson <hp@axis.com> + + * config/cris/arit.c (DS): Apply attribute __fallthrough__. + +2020-01-18 John David Anglin <danglin@gcc.gnu.org> + + PR libgcc/92988 + * crtstuff.c (__do_global_dtors_aux): Only call __cxa_finalize if + DEFAULT_USE_CXA_ATEXIT is true. + +2020-01-16 Mihail-Calin Ionescu <mihail.ionescu@arm.com> + Thomas Preud'homme <thomas.preudhomme@arm.com> + + * config/arm/t-arm: Check return value of gcc rather than lack of + output. + +2020-01-14 Georg-Johann Lay <avr@gjlay.de> + + * config/avr/lib1funcs.S (skip): Simplify. + +2020-01-10 Kwok Cheung Yeung <kcy@codesourcery.com> + + * config/gcn/atomic.c: Remove include of stdint.h. + (__sync_val_compare_and_swap_##SIZE): Replace uintptr_t with + __UINTPTR_TYPE__. + +2020-01-09 Kwok Cheung Yeung <kcy@codesourcery.com> + + * config/gcn/atomic.c: New. + * config/gcn/t-amdgcn (LIB2ADD): Add atomic.c. + 2020-01-08 Georg-Johann Lay <avr@gjlay.de> Implement 64-bit double functions. diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in index 43bad01..5c50f9f 100644 --- a/libgcc/Makefile.in +++ b/libgcc/Makefile.in @@ -165,6 +165,7 @@ AUTOCONF = autoconf configure_deps = \ $(srcdir)/../config/enable.m4 \ $(srcdir)/../config/tls.m4 \ + $(srcdir)/../config/toolexeclibdir.m4 \ $(srcdir)/../config/acx.m4 \ $(srcdir)/../config/no-executables.m4 \ $(srcdir)/../config/lib-ld.m4 \ @@ -903,9 +904,10 @@ LIBGCOV_PROFILER = _gcov_interval_profiler \ _gcov_ior_profiler_atomic \ _gcov_indirect_call_profiler_v4 \ _gcov_time_profiler -LIBGCOV_INTERFACE = _gcov_dump _gcov_flush _gcov_fork \ +LIBGCOV_INTERFACE = _gcov_dump _gcov_fork \ _gcov_execl _gcov_execlp \ - _gcov_execle _gcov_execv _gcov_execvp _gcov_execve _gcov_reset + _gcov_execle _gcov_execv _gcov_execvp _gcov_execve _gcov_reset \ + _gcov_lock_unlock LIBGCOV_DRIVER = _gcov libgcov-merge-objects = $(patsubst %,%$(objext),$(LIBGCOV_MERGE)) diff --git a/libgcc/config.host b/libgcc/config.host index 8f0ea90..2cd4209 100644 --- a/libgcc/config.host +++ b/libgcc/config.host @@ -112,9 +112,6 @@ bpf-*-*) ;; cr16-*-*) ;; -crisv32-*-*) - cpu_type=cris - ;; csky*-*-*) cpu_type=csky ;; @@ -577,15 +574,9 @@ cr16-*-elf) tmake_file="${tmake_file} cr16/t-cr16 cr16/t-crtlibid t-fdpbit" extra_parts="$extra_parts crti.o crtn.o crtlibid.o" ;; -crisv32-*-elf) - tmake_file="$tmake_file cris/t-cris t-softfp-sfdf t-softfp" - ;; cris-*-elf) tmake_file="$tmake_file cris/t-cris t-softfp-sfdf t-softfp cris/t-elfmulti" ;; -cris-*-linux* | crisv32-*-linux*) - tmake_file="$tmake_file cris/t-cris t-softfp-sfdf t-softfp cris/t-linux" - ;; csky-*-elf*) tmake_file="csky/t-csky t-fdpbit" extra_parts="$extra_parts crti.o crtn.o" @@ -1112,7 +1103,8 @@ nds32*-elf*) esac ;; nios2-*-linux*) - tmake_file="$tmake_file nios2/t-nios2 nios2/t-linux t-libgcc-pic t-slibgcc-libgcc" + tmake_file="$tmake_file nios2/t-nios2 nios2/t-linux t-libgcc-pic t-eh-dw2-dip t-slibgcc-libgcc" + tm_file="$tm_file nios2/elf-lib.h" md_unwind_header=nios2/linux-unwind.h ;; nios2-*-*) @@ -1300,7 +1292,7 @@ s390x-*-linux*) md_unwind_header=s390/linux-unwind.h ;; s390x-ibm-tpf*) - tmake_file="${tmake_file} s390/t-crtstuff t-libgcc-pic t-eh-dw2-dip" + tmake_file="${tmake_file} s390/t-crtstuff t-libgcc-pic t-eh-dw2-dip s390/t-tpf" extra_parts="crtbeginS.o crtendS.o" md_unwind_header=s390/tpf-unwind.h ;; diff --git a/libgcc/config.in b/libgcc/config.in index 59a3d8d..5be5321 100644 --- a/libgcc/config.in +++ b/libgcc/config.in @@ -10,6 +10,9 @@ */ #undef HAVE_AS_CFI_SECTIONS +/* Define to 1 if the assembler supports LSE. */ +#undef HAVE_AS_LSE + /* Define to 1 if the target assembler supports thread-local storage. */ #undef HAVE_CC_TLS diff --git a/libgcc/config/aarch64/aarch64-unwind.h b/libgcc/config/aarch64/aarch64-unwind.h index 4c8790b..ed84a96 100644 --- a/libgcc/config/aarch64/aarch64-unwind.h +++ b/libgcc/config/aarch64/aarch64-unwind.h @@ -104,6 +104,8 @@ aarch64_frob_update_context (struct _Unwind_Context *context, if (fs->regs.reg[DWARF_REGNUM_AARCH64_RA_STATE].loc.offset & 0x1) /* The flag is used for re-authenticating EH handler's address. */ context->flags |= RA_SIGNED_BIT; + else + context->flags &= ~RA_SIGNED_BIT; return; } diff --git a/libgcc/config/aarch64/lse-init.c b/libgcc/config/aarch64/lse-init.c index 74acef2..00e9ab8 100644 --- a/libgcc/config/aarch64/lse-init.c +++ b/libgcc/config/aarch64/lse-init.c @@ -29,19 +29,20 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see _Bool __aarch64_have_lse_atomics __attribute__((visibility("hidden"), nocommon)); -/* Disable initialization of __aarch64_have_lse_atomics during bootstrap. */ -#if !defined(inhibit_libc) && defined(HAVE_SYS_AUXV_H) -# include <sys/auxv.h> +/* Gate availability of __getauxval on glibc. All AArch64-supporting glibc + versions support it. */ +#ifdef __gnu_linux__ -/* Disable initialization if the system headers are too old. */ -# if defined(AT_HWCAP) && defined(HWCAP_ATOMICS) +# define AT_HWCAP 16 +# define HWCAP_ATOMICS (1 << 8) + +unsigned long int __getauxval (unsigned long int); static void __attribute__((constructor)) init_have_lse_atomics (void) { - unsigned long hwcap = getauxval (AT_HWCAP); + unsigned long hwcap = __getauxval (AT_HWCAP); __aarch64_have_lse_atomics = (hwcap & HWCAP_ATOMICS) != 0; } -# endif /* HWCAP */ -#endif /* inhibit_libc */ +#endif /* __gnu_linux__ */ diff --git a/libgcc/config/aarch64/lse.S b/libgcc/config/aarch64/lse.S index ca6495f..f3ccf5c 100644 --- a/libgcc/config/aarch64/lse.S +++ b/libgcc/config/aarch64/lse.S @@ -48,8 +48,14 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see * separately to minimize code size. */ +#include "auto-target.h" + /* Tell the assembler to accept LSE instructions. */ +#ifdef HAVE_AS_LSE .arch armv8-a+lse +#else + .arch armv8-a +#endif /* Declare the symbol gating the LSE implementations. */ .hidden __aarch64_have_lse_atomics @@ -58,12 +64,19 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if SIZE == 1 # define S b # define UXT uxtb +# define B 0x00000000 #elif SIZE == 2 # define S h # define UXT uxth +# define B 0x40000000 #elif SIZE == 4 || SIZE == 8 || SIZE == 16 # define S # define UXT mov +# if SIZE == 4 +# define B 0x80000000 +# elif SIZE == 8 +# define B 0xc0000000 +# endif #else # error #endif @@ -72,18 +85,26 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see # define SUFF _relax # define A # define L +# define M 0x000000 +# define N 0x000000 #elif MODEL == 2 # define SUFF _acq # define A a # define L +# define M 0x400000 +# define N 0x800000 #elif MODEL == 3 # define SUFF _rel # define A # define L l +# define M 0x008000 +# define N 0x400000 #elif MODEL == 4 # define SUFF _acq_rel # define A a # define L l +# define M 0x408000 +# define N 0xc00000 #else # error #endif @@ -144,9 +165,13 @@ STARTFN NAME(cas) JUMP_IF_NOT_LSE 8f #if SIZE < 16 -#define CAS glue4(cas, A, L, S) +#ifdef HAVE_AS_LSE +# define CAS glue4(cas, A, L, S) s(0), s(1), [x2] +#else +# define CAS .inst 0x08a07c41 + B + M +#endif - CAS s(0), s(1), [x2] + CAS /* s(0), s(1), [x2] */ ret 8: UXT s(tmp0), s(0) @@ -160,9 +185,13 @@ STARTFN NAME(cas) #else #define LDXP glue3(ld, A, xp) #define STXP glue3(st, L, xp) -#define CASP glue3(casp, A, L) +#ifdef HAVE_AS_LSE +# define CASP glue3(casp, A, L) x0, x1, x2, x3, [x4] +#else +# define CASP .inst 0x48207c82 + M +#endif - CASP x0, x1, x2, x3, [x4] + CASP /* x0, x1, x2, x3, [x4] */ ret 8: mov x(tmp0), x0 @@ -181,12 +210,16 @@ ENDFN NAME(cas) #endif #ifdef L_swp -#define SWP glue4(swp, A, L, S) +#ifdef HAVE_AS_LSE +# define SWP glue4(swp, A, L, S) s(0), s(0), [x1] +#else +# define SWP .inst 0x38208020 + B + N +#endif STARTFN NAME(swp) JUMP_IF_NOT_LSE 8f - SWP s(0), s(0), [x1] + SWP /* s(0), s(0), [x1] */ ret 8: mov s(tmp0), s(0) @@ -204,24 +237,32 @@ ENDFN NAME(swp) #ifdef L_ldadd #define LDNM ldadd #define OP add +#define OPN 0x0000 #elif defined(L_ldclr) #define LDNM ldclr #define OP bic +#define OPN 0x1000 #elif defined(L_ldeor) #define LDNM ldeor #define OP eor +#define OPN 0x2000 #elif defined(L_ldset) #define LDNM ldset #define OP orr +#define OPN 0x3000 #else #error #endif -#define LDOP glue4(LDNM, A, L, S) +#ifdef HAVE_AS_LSE +# define LDOP glue4(LDNM, A, L, S) s(0), s(0), [x1] +#else +# define LDOP .inst 0x38200020 + OPN + B + N +#endif STARTFN NAME(LDNM) JUMP_IF_NOT_LSE 8f - LDOP s(0), s(0), [x1] + LDOP /* s(0), s(0), [x1] */ ret 8: mov s(tmp0), s(0) diff --git a/libgcc/config/arc/crti.S b/libgcc/config/arc/crti.S index 297ddc7..e05a789 100644 --- a/libgcc/config/arc/crti.S +++ b/libgcc/config/arc/crti.S @@ -28,6 +28,11 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see # This file contains the stack frame setup for contents of the .fini and # .init sections. +#ifdef __ARC_RF16__ + /* Use object attributes to inform other tools this file is + safe for RF16 configuration. */ + .arc_attribute Tag_ARC_ABI_rf16, 1 +#endif .section .init .global _init .word 0 diff --git a/libgcc/config/arc/crtn.S b/libgcc/config/arc/crtn.S index fc6197f..37eac5e 100644 --- a/libgcc/config/arc/crtn.S +++ b/libgcc/config/arc/crtn.S @@ -28,6 +28,11 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see # This file just makes sure that the .fini and .init sections do in # fact return. This file is the last thing linked into any executable. +#ifdef __ARC_RF16__ + /* Use object attributes to inform other tools this file is + safe for RF16 configuration. */ + .arc_attribute Tag_ARC_ABI_rf16, 1 +#endif .section .init pop_s blink j_s [blink] diff --git a/libgcc/config/arc/crttls.S b/libgcc/config/arc/crttls.S index 4c8faf9..b5aebf1 100644 --- a/libgcc/config/arc/crttls.S +++ b/libgcc/config/arc/crttls.S @@ -33,6 +33,12 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see the executable file might be covered by the GNU General Public License. */ +#ifdef __ARC_RF16__ + /* Use object attributes to inform other tools this file is + safe for RF16 configuration. */ + .arc_attribute Tag_ARC_ABI_rf16, 1 +#endif + #if (__ARC_TLS_REGNO__ != -1) /* ANSI concatenation macros. */ diff --git a/libgcc/config/arc/fp-hack.h b/libgcc/config/arc/fp-hack.h index 86b63d9..65cdcdd 100644 --- a/libgcc/config/arc/fp-hack.h +++ b/libgcc/config/arc/fp-hack.h @@ -30,7 +30,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define ARC_FP_DEBUG 1 #define FINE_GRAINED_LIBRARIES -#define ARC_OPTFPE (defined (__ARC700__) || defined (__ARC_FPX_QUARK__)) + +#if defined (__ARC700__) || defined (__ARC_FPX_QUARK__) +#define ARC_OPTFPE 1 +#endif #if !ARC_OPTFPE || ARC_FP_DEBUG #define L_pack_sf diff --git a/libgcc/config/arc/lib1funcs.S b/libgcc/config/arc/lib1funcs.S index 1ada0fe..cc54b40 100644 --- a/libgcc/config/arc/lib1funcs.S +++ b/libgcc/config/arc/lib1funcs.S @@ -53,7 +53,11 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define ENDFUNC0(X) .Lfe_##X: .size X,.Lfe_##X-X #define ENDFUNC(X) ENDFUNC0(X) - +#ifdef __ARC_RF16__ + /* Use object attributes to inform other tools this file is + safe for RF16 configuration. */ + .arc_attribute Tag_ARC_ABI_rf16, 1 +#endif #ifdef L_mulsi3 .section .text @@ -232,6 +236,7 @@ SYM(__umulsi3_highpart): #endif #endif /* L_umulsidi3 */ +#ifndef __ARC_RF16__ #ifdef L_muldi3 .section .text .align 4 @@ -285,6 +290,7 @@ SYM(__muldi3): #endif /* __LITTLE_ENDIAN__ */ ENDFUNC(__muldi3) #endif /* L_muldi3 */ +#endif /* !__ARC_RF16__ */ #ifdef L_umulsi3_highpart #include "ieee-754/arc-ieee-754.h" @@ -544,12 +550,6 @@ SYM(__udivmodsi4): SYM(__udivsi3): b @SYM(__udivmodsi4) ENDFUNC(__udivsi3) -#if 0 /* interferes with linux loader */ - .section .__arc_profile_forward, "a" - .long SYM(__udivsi3) - .long SYM(__udivmodsi4) - .long 65536 -#endif #endif /* L_udivsi3 */ @@ -948,12 +948,6 @@ SYM(__umodsi3): j.d [r7] mov r0,r1 ENDFUNC(__umodsi3) -#if 0 /* interferes with linux loader */ - .section .__arc_profile_forward, "a" - .long SYM(__umodsi3) - .long SYM(__udivmodsi4) - .long 65536 -#endif #endif /* L_umodsi3 */ @@ -1106,6 +1100,7 @@ SYM(__clzsi2): ;; ;#endif +#ifndef __ARC_RF16__ #ifdef L_millicodethunk_st .section .text .align 4 @@ -1315,9 +1310,7 @@ SYM(__ld_r13_to_r14_ret): #endif /* L_millicodethunk_ret */ -#define ARC_OPTFPE (defined (__ARC700__) || defined (__ARC_FPX_QUARK__)) - -#if ARC_OPTFPE +#if defined (__ARC700__) || defined (__ARC_FPX_QUARK__) #ifdef L_adddf3 #ifdef __ARC_NORM__ #include "ieee-754/adddf3.S" @@ -1482,3 +1475,5 @@ SYM(__ld_r13_to_r14_ret): #endif #endif #endif /* ARC_OPTFPE */ + +#endif /* !__ARC_RF16__ */ diff --git a/libgcc/config/arc/lib2funcs.c b/libgcc/config/arc/lib2funcs.c new file mode 100644 index 0000000..f9de7b2 --- /dev/null +++ b/libgcc/config/arc/lib2funcs.c @@ -0,0 +1,88 @@ +/* libgcc routines for ARC + Copyright (C) 2019 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/>. */ + + +typedef int sint64_t __attribute__ ((mode (DI))); +typedef unsigned int uint64_t __attribute__ ((mode (DI))); +typedef unsigned int nint32_t __attribute__ ((mode (SI))); +typedef int word_t __attribute__ ((mode (__word__))); + +sint64_t __muldi3 (sint64_t, sint64_t); +nint32_t __umodsi3 (nint32_t, nint32_t); + +#ifdef __ARC_RF16__ + +/* Generic multiplication procedure. No mpy operation involved. */ +sint64_t +__muldi3 (sint64_t a, sint64_t b) +{ + sint64_t res = 0; + uint64_t cnt = a; + + while (cnt) + { + if (cnt & 1) + res += b; + b <<= 1; + cnt >>= 1; + } + return res; +} + +/* Unsigned 32bit integer division/modulus. */ + +static inline __attribute__ ((__always_inline__)) +nint32_t +udivmodsi4 (nint32_t num, nint32_t den, word_t modwanted) +{ + nint32_t bit = 1; + nint32_t res = 0; + + while (den < num && bit && !(den & (1LL << 63))) + { + den <<= 1; + bit <<= 1; + } + while (bit) + { + if (num >= den) + { + num -= den; + res |= bit; + } + bit >>= 1; + den >>= 1; + } + if (modwanted) + return num; + return res; +} + +nint32_t +__umodsi3 (nint32_t a, nint32_t b) +{ + return udivmodsi4 (a, b, 1); +} + +#endif diff --git a/libgcc/config/arc/t-arc b/libgcc/config/arc/t-arc index 3844fef..34aa444 100644 --- a/libgcc/config/arc/t-arc +++ b/libgcc/config/arc/t-arc @@ -43,6 +43,7 @@ LIB1ASMFUNCS = _mulsi3 _umulsidi3 _umulsi3_highpart _muldi3 \ # used in an asm wrapper. LIB2ADD = fp-bit.c dp-bit.c +LIB2ADD += $(srcdir)/config/arc/lib2funcs.c dp-bit.c: $(srcdir)/fp-bit.c echo '#ifndef __big_endian__' > dp-bit.c diff --git a/libgcc/config/arm/bpabi-v6m.S b/libgcc/config/arm/bpabi-v6m.S index 29fe8fa..1a403ef 100644 --- a/libgcc/config/arm/bpabi-v6m.S +++ b/libgcc/config/arm/bpabi-v6m.S @@ -39,21 +39,21 @@ FUNC_START aeabi_lcmp cmp xxh, yyh beq 1f bgt 2f - mov r0, #1 - neg r0, r0 + movs r0, #1 + negs r0, r0 RET 2: - mov r0, #1 + movs r0, #1 RET 1: - sub r0, xxl, yyl + subs r0, xxl, yyl beq 1f bhi 2f - mov r0, #1 - neg r0, r0 + movs r0, #1 + negs r0, r0 RET 2: - mov r0, #1 + movs r0, #1 1: RET FUNC_END aeabi_lcmp @@ -65,15 +65,15 @@ FUNC_START aeabi_lcmp FUNC_START aeabi_ulcmp cmp xxh, yyh bne 1f - sub r0, xxl, yyl + subs r0, xxl, yyl beq 2f 1: bcs 1f - mov r0, #1 - neg r0, r0 + movs r0, #1 + negs r0, r0 RET 1: - mov r0, #1 + movs r0, #1 2: RET FUNC_END aeabi_ulcmp @@ -91,29 +91,29 @@ FUNC_START aeabi_ulcmp cmp xxl, #0 2: beq 3f - mov xxh, #0 - mvn xxh, xxh @ 0xffffffff - mov xxl, xxh + movs xxh, #0 + mvns xxh, xxh @ 0xffffffff + movs xxl, xxh 3: .else blt 6f bgt 4f cmp xxl, #0 beq 5f -4: mov xxl, #0 - mvn xxl, xxl @ 0xffffffff - lsr xxh, xxl, #1 @ 0x7fffffff +4: movs xxl, #0 + mvns xxl, xxl @ 0xffffffff + lsrs xxh, xxl, #1 @ 0x7fffffff b 5f -6: mov xxh, #0x80 - lsl xxh, xxh, #24 @ 0x80000000 - mov xxl, #0 +6: movs xxh, #0x80 + lsls xxh, xxh, #24 @ 0x80000000 + movs xxl, #0 5: .endif @ tailcalls are tricky on v6-m. push {r0, r1, r2} ldr r0, 1f adr r1, 1f - add r0, r1 + adds r0, r1 str r0, [sp, #8] @ We know we are not on armv4t, so pop pc is safe. pop {r0, r1, pc} @@ -128,15 +128,15 @@ FUNC_START aeabi_ulcmp FUNC_START aeabi_ldivmod test_div_by_zero signed - push {r0, r1} - mov r0, sp - push {r0, lr} - ldr r0, [sp, #8] - bl SYM(__gnu_ldivmod_helper) - ldr r3, [sp, #4] - mov lr, r3 - add sp, sp, #8 - pop {r2, r3} + push {r0, r1} + mov r0, sp + push {r0, lr} + ldr r0, [sp, #8] + bl SYM(__gnu_ldivmod_helper) + ldr r3, [sp, #4] + mov lr, r3 + add sp, sp, #8 + pop {r2, r3} RET FUNC_END aeabi_ldivmod @@ -147,15 +147,15 @@ FUNC_START aeabi_ldivmod FUNC_START aeabi_uldivmod test_div_by_zero unsigned - push {r0, r1} - mov r0, sp - push {r0, lr} - ldr r0, [sp, #8] - bl SYM(__udivmoddi4) - ldr r3, [sp, #4] - mov lr, r3 - add sp, sp, #8 - pop {r2, r3} + push {r0, r1} + mov r0, sp + push {r0, lr} + ldr r0, [sp, #8] + bl SYM(__udivmoddi4) + ldr r3, [sp, #4] + mov lr, r3 + add sp, sp, #8 + pop {r2, r3} RET FUNC_END aeabi_uldivmod @@ -166,9 +166,9 @@ FUNC_START aeabi_uldivmod FUNC_START aeabi_frsub push {r4, lr} - mov r4, #1 - lsl r4, #31 - eor r0, r0, r4 + movs r4, #1 + lsls r4, #31 + eors r0, r0, r4 bl __aeabi_fadd pop {r4, pc} @@ -181,7 +181,7 @@ FUNC_START aeabi_frsub FUNC_START aeabi_cfrcmple mov ip, r0 - mov r0, r1 + movs r0, r1 mov r1, ip b 6f @@ -196,8 +196,8 @@ FUNC_ALIAS aeabi_cfcmple aeabi_cfcmpeq cmp r0, #0 @ Clear the C flag if the return value was -1, indicating @ that the first operand was smaller than the second. - bmi 1f - mov r1, #0 + bmi 1f + movs r1, #0 cmn r0, r1 1: pop {r0, r1, r2, r3, r4, pc} @@ -210,8 +210,8 @@ FUNC_START aeabi_fcmpeq push {r4, lr} bl __eqsf2 - neg r0, r0 - add r0, r0, #1 + negs r0, r0 + adds r0, r0, #1 pop {r4, pc} FUNC_END aeabi_fcmpeq @@ -223,10 +223,10 @@ FUNC_START aeabi_fcmp\cond bl __\helper\mode cmp r0, #0 b\cond 1f - mov r0, #0 + movs r0, #0 pop {r4, pc} 1: - mov r0, #1 + movs r0, #1 pop {r4, pc} FUNC_END aeabi_fcmp\cond @@ -244,9 +244,9 @@ COMPARISON ge, ge FUNC_START aeabi_drsub push {r4, lr} - mov r4, #1 - lsl r4, #31 - eor xxh, xxh, r4 + movs r4, #1 + lsls r4, #31 + eors xxh, xxh, r4 bl __aeabi_dadd pop {r4, pc} @@ -259,10 +259,10 @@ FUNC_START aeabi_drsub FUNC_START aeabi_cdrcmple mov ip, r0 - mov r0, r2 + movs r0, r2 mov r2, ip mov ip, r1 - mov r1, r3 + movs r1, r3 mov r3, ip b 6f @@ -277,8 +277,8 @@ FUNC_ALIAS aeabi_cdcmple aeabi_cdcmpeq cmp r0, #0 @ Clear the C flag if the return value was -1, indicating @ that the first operand was smaller than the second. - bmi 1f - mov r1, #0 + bmi 1f + movs r1, #0 cmn r0, r1 1: pop {r0, r1, r2, r3, r4, pc} @@ -291,8 +291,8 @@ FUNC_START aeabi_dcmpeq push {r4, lr} bl __eqdf2 - neg r0, r0 - add r0, r0, #1 + negs r0, r0 + adds r0, r0, #1 pop {r4, pc} FUNC_END aeabi_dcmpeq @@ -304,10 +304,10 @@ FUNC_START aeabi_dcmp\cond bl __\helper\mode cmp r0, #0 b\cond 1f - mov r0, #0 + movs r0, #0 pop {r4, pc} 1: - mov r0, #1 + movs r0, #1 pop {r4, pc} FUNC_END aeabi_dcmp\cond diff --git a/libgcc/config/arm/lib1funcs.S b/libgcc/config/arm/lib1funcs.S index e4b73ca..a094417 100644 --- a/libgcc/config/arm/lib1funcs.S +++ b/libgcc/config/arm/lib1funcs.S @@ -22,6 +22,10 @@ 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/>. */ +/* Everything in this file should now use unified syntax. */ + + .syntax unified + /* An executable stack is *not* required for these functions. */ #if defined(__ELF__) && defined(__linux__) .section .note.GNU-stack,"",%progbits @@ -222,7 +226,6 @@ LSYM(Lend_fde): .endm #define do_push push #define do_pop pop -#define COND(op1, op2, cond) op1 ## op2 ## cond /* Perform an arithmetic operation with a variable shift operand. This requires two instructions and a scratch register on Thumb-2. */ .macro shiftop name, dest, src1, src2, shiftop, shiftreg, tmp @@ -237,12 +240,13 @@ LSYM(Lend_fde): .endm #define do_push stmfd sp!, #define do_pop ldmfd sp!, -#define COND(op1, op2, cond) op1 ## cond ## op2 .macro shiftop name, dest, src1, src2, shiftop, shiftreg, tmp \name \dest, \src1, \src2, \shiftop \shiftreg .endm #endif +#define COND(op1, op2, cond) op1 ## op2 ## cond + #ifdef __ARM_EABI__ .macro ARM_LDIV0 name signed cmp r0, #0 @@ -270,7 +274,7 @@ LSYM(Lend_fde): #ifdef NOT_ISA_TARGET_32BIT push {r0, lr} - mov r0, #0 + movs r0, #0 bl SYM(__aeabi_idiv0) @ We know we are not on armv4t, so pop pc is safe. pop {r1, pc} @@ -310,7 +314,7 @@ LSYM(Lend_fde): push { r1, lr } 98: cfi_push 98b - __\name, 0xe, -0x4, 0x8 bl SYM (__div0) - mov r0, #0 @ About as wrong as it could be. + movs r0, #0 @ About as wrong as it could be. #if defined (__INTERWORKING__) pop { r1, r2 } bx r2 @@ -349,7 +353,7 @@ SYM (\name): #define THUMB_FUNC .thumb_func #define THUMB_CODE .force_thumb # if defined(__thumb2__) -#define THUMB_SYNTAX .syntax divided +#define THUMB_SYNTAX # else #define THUMB_SYNTAX # endif @@ -490,7 +494,8 @@ pc .req r15 /* ------------------------------------------------------------------------ */ /* Bodies of the division and modulo routines. */ -/* ------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------ */ + .macro ARM_DIV_BODY dividend, divisor, result, curbit #if defined (__ARM_FEATURE_CLZ) && ! defined (__OPTIMIZE_SIZE__) @@ -725,8 +730,8 @@ pc .req r15 /* ------------------------------------------------------------------------ */ .macro THUMB_DIV_MOD_BODY modulo @ Load the constant 0x10000000 into our work register. - mov work, #1 - lsl work, #28 + movs work, #1 + lsls work, #28 LSYM(Loop1): @ Unless the divisor is very big, shift it up in multiples of @ four bits, since this is the amount of unwinding in the main @@ -736,12 +741,12 @@ LSYM(Loop1): bhs LSYM(Lbignum) cmp divisor, dividend bhs LSYM(Lbignum) - lsl divisor, #4 - lsl curbit, #4 + lsls divisor, #4 + lsls curbit, #4 b LSYM(Loop1) LSYM(Lbignum): @ Set work to 0x80000000 - lsl work, #3 + lsls work, #3 LSYM(Loop2): @ For very big divisors, we must shift it a bit at a time, or @ we will be in danger of overflowing. @@ -749,8 +754,8 @@ LSYM(Loop2): bhs LSYM(Loop3) cmp divisor, dividend bhs LSYM(Loop3) - lsl divisor, #1 - lsl curbit, #1 + lsls divisor, #1 + lsls curbit, #1 b LSYM(Loop2) LSYM(Loop3): @ Test for possible subtractions ... @@ -758,39 +763,39 @@ LSYM(Loop3): @ ... On the final pass, this may subtract too much from the dividend, @ so keep track of which subtractions are done, we can fix them up @ afterwards. - mov overdone, #0 + movs overdone, #0 cmp dividend, divisor blo LSYM(Lover1) - sub dividend, dividend, divisor + subs dividend, dividend, divisor LSYM(Lover1): - lsr work, divisor, #1 + lsrs work, divisor, #1 cmp dividend, work blo LSYM(Lover2) - sub dividend, dividend, work + subs dividend, dividend, work mov ip, curbit - mov work, #1 - ror curbit, work - orr overdone, curbit + movs work, #1 + rors curbit, work + orrs overdone, curbit mov curbit, ip LSYM(Lover2): - lsr work, divisor, #2 + lsrs work, divisor, #2 cmp dividend, work blo LSYM(Lover3) - sub dividend, dividend, work + subs dividend, dividend, work mov ip, curbit - mov work, #2 - ror curbit, work - orr overdone, curbit + movs work, #2 + rors curbit, work + orrs overdone, curbit mov curbit, ip LSYM(Lover3): - lsr work, divisor, #3 + lsrs work, divisor, #3 cmp dividend, work blo LSYM(Lover4) - sub dividend, dividend, work + subs dividend, dividend, work mov ip, curbit - mov work, #3 - ror curbit, work - orr overdone, curbit + movs work, #3 + rors curbit, work + orrs overdone, curbit mov curbit, ip LSYM(Lover4): mov ip, curbit @@ -800,46 +805,46 @@ LSYM(Lover4): @ since the "bit" will have been shifted out at the bottom. cmp dividend, divisor blo LSYM(Lover1) - sub dividend, dividend, divisor - orr result, result, curbit + subs dividend, dividend, divisor + orrs result, result, curbit LSYM(Lover1): - lsr work, divisor, #1 + lsrs work, divisor, #1 cmp dividend, work blo LSYM(Lover2) - sub dividend, dividend, work - lsr work, curbit, #1 - orr result, work + subs dividend, dividend, work + lsrs work, curbit, #1 + orrs result, work LSYM(Lover2): - lsr work, divisor, #2 + lsrs work, divisor, #2 cmp dividend, work blo LSYM(Lover3) - sub dividend, dividend, work - lsr work, curbit, #2 - orr result, work + subs dividend, dividend, work + lsrs work, curbit, #2 + orrs result, work LSYM(Lover3): - lsr work, divisor, #3 + lsrs work, divisor, #3 cmp dividend, work blo LSYM(Lover4) - sub dividend, dividend, work - lsr work, curbit, #3 - orr result, work + subs dividend, dividend, work + lsrs work, curbit, #3 + orrs result, work LSYM(Lover4): .endif cmp dividend, #0 @ Early termination? beq LSYM(Lover5) - lsr curbit, #4 @ No, any more bits to do? + lsrs curbit, #4 @ No, any more bits to do? beq LSYM(Lover5) - lsr divisor, #4 + lsrs divisor, #4 b LSYM(Loop3) LSYM(Lover5): .if \modulo @ Any subtractions that we should not have done will be recorded in @ the top three bits of "overdone". Exactly which were not needed @ are governed by the position of the bit, stored in ip. - mov work, #0xe - lsl work, #28 - and overdone, work + movs work, #0xe + lsls work, #28 + ands overdone, work beq LSYM(Lgot_result) @ If we terminated early, because dividend became zero, then the @@ -849,33 +854,33 @@ LSYM(Lover5): @ the bit in ip could be in the top two bits which might then match @ with one of the smaller RORs. mov curbit, ip - mov work, #0x7 + movs work, #0x7 tst curbit, work beq LSYM(Lgot_result) mov curbit, ip - mov work, #3 - ror curbit, work + movs work, #3 + rors curbit, work tst overdone, curbit beq LSYM(Lover6) - lsr work, divisor, #3 - add dividend, work + lsrs work, divisor, #3 + adds dividend, work LSYM(Lover6): mov curbit, ip - mov work, #2 - ror curbit, work + movs work, #2 + rors curbit, work tst overdone, curbit beq LSYM(Lover7) - lsr work, divisor, #2 - add dividend, work + lsrs work, divisor, #2 + adds dividend, work LSYM(Lover7): mov curbit, ip - mov work, #1 - ror curbit, work + movs work, #1 + rors curbit, work tst overdone, curbit beq LSYM(Lgot_result) - lsr work, divisor, #1 - add dividend, work + lsrs work, divisor, #1 + adds dividend, work .endif LSYM(Lgot_result): .endm @@ -885,7 +890,7 @@ LSYM(Lgot_result): /* Branch to div(n), and jump to label if curbit is lo than divisior. */ .macro BranchToDiv n, label - lsr curbit, dividend, \n + lsrs curbit, dividend, \n cmp curbit, divisor blo \label .endm @@ -893,13 +898,13 @@ LSYM(Lgot_result): /* Body of div(n). Shift the divisor in n bits and compare the divisor and dividend. Update the dividend as the substruction result. */ .macro DoDiv n - lsr curbit, dividend, \n + lsrs curbit, dividend, \n cmp curbit, divisor bcc 1f - lsl curbit, divisor, \n - sub dividend, dividend, curbit + lsls curbit, divisor, \n + subs dividend, dividend, curbit -1: adc result, result +1: adcs result, result .endm /* The body of division with positive divisor. Unless the divisor is very @@ -907,29 +912,29 @@ LSYM(Lgot_result): unwinding in the main division loop. Continue shifting until the divisor is larger than the dividend. */ .macro THUMB1_Div_Positive - mov result, #0 + movs result, #0 BranchToDiv #1, LSYM(Lthumb1_div1) BranchToDiv #4, LSYM(Lthumb1_div4) BranchToDiv #8, LSYM(Lthumb1_div8) BranchToDiv #12, LSYM(Lthumb1_div12) BranchToDiv #16, LSYM(Lthumb1_div16) LSYM(Lthumb1_div_large_positive): - mov result, #0xff - lsl divisor, divisor, #8 + movs result, #0xff + lsls divisor, divisor, #8 rev result, result - lsr curbit, dividend, #16 + lsrs curbit, dividend, #16 cmp curbit, divisor blo 1f - asr result, #8 - lsl divisor, divisor, #8 + asrs result, #8 + lsls divisor, divisor, #8 beq LSYM(Ldivbyzero_waypoint) -1: lsr curbit, dividend, #12 +1: lsrs curbit, dividend, #12 cmp curbit, divisor blo LSYM(Lthumb1_div12) b LSYM(Lthumb1_div16) LSYM(Lthumb1_div_loop): - lsr divisor, divisor, #8 + lsrs divisor, divisor, #8 LSYM(Lthumb1_div16): Dodiv #15 Dodiv #14 @@ -954,11 +959,11 @@ LSYM(Lthumb1_div3): LSYM(Lthumb1_div2): Dodiv #1 LSYM(Lthumb1_div1): - sub divisor, dividend, divisor + subs divisor, dividend, divisor bcs 1f cpy divisor, dividend -1: adc result, result +1: adcs result, result cpy dividend, result RET @@ -970,43 +975,43 @@ LSYM(Ldivbyzero_waypoint): THUMB1_Div_Positive except that the shift steps are in multiples of six bits. */ .macro THUMB1_Div_Negative - lsr result, divisor, #31 + lsrs result, divisor, #31 beq 1f - neg divisor, divisor + negs divisor, divisor -1: asr curbit, dividend, #32 +1: asrs curbit, dividend, #32 bcc 2f - neg dividend, dividend + negs dividend, dividend -2: eor curbit, result - mov result, #0 +2: eors curbit, result + movs result, #0 cpy ip, curbit BranchToDiv #4, LSYM(Lthumb1_div_negative4) BranchToDiv #8, LSYM(Lthumb1_div_negative8) LSYM(Lthumb1_div_large): - mov result, #0xfc - lsl divisor, divisor, #6 + movs result, #0xfc + lsls divisor, divisor, #6 rev result, result - lsr curbit, dividend, #8 + lsrs curbit, dividend, #8 cmp curbit, divisor blo LSYM(Lthumb1_div_negative8) - lsl divisor, divisor, #6 - asr result, result, #6 + lsls divisor, divisor, #6 + asrs result, result, #6 cmp curbit, divisor blo LSYM(Lthumb1_div_negative8) - lsl divisor, divisor, #6 - asr result, result, #6 + lsls divisor, divisor, #6 + asrs result, result, #6 cmp curbit, divisor blo LSYM(Lthumb1_div_negative8) - lsl divisor, divisor, #6 + lsls divisor, divisor, #6 beq LSYM(Ldivbyzero_negative) - asr result, result, #6 + asrs result, result, #6 b LSYM(Lthumb1_div_negative8) LSYM(Lthumb1_div_negative_loop): - lsr divisor, divisor, #6 + lsrs divisor, divisor, #6 LSYM(Lthumb1_div_negative8): DoDiv #7 DoDiv #6 @@ -1017,28 +1022,28 @@ LSYM(Lthumb1_div_negative4): DoDiv #2 bcs LSYM(Lthumb1_div_negative_loop) DoDiv #1 - sub divisor, dividend, divisor + subs divisor, dividend, divisor bcs 1f cpy divisor, dividend 1: cpy curbit, ip - adc result, result - asr curbit, curbit, #1 + adcs result, result + asrs curbit, curbit, #1 cpy dividend, result bcc 2f - neg dividend, dividend + negs dividend, dividend cmp curbit, #0 2: bpl 3f - neg divisor, divisor + negs divisor, divisor 3: RET LSYM(Ldivbyzero_negative): cpy curbit, ip - asr curbit, curbit, #1 + asrs curbit, curbit, #1 bcc LSYM(Ldiv0) - neg dividend, dividend + negs dividend, dividend .endm #endif /* ARM Thumb version. */ @@ -1056,8 +1061,8 @@ LSYM(Ldivbyzero_negative): cmp divisor, #0 beq LSYM(Ldiv0) LSYM(udivsi3_skip_div0_test): - mov curbit, #1 - mov result, #0 + movs curbit, #1 + movs result, #0 push { work } cmp dividend, divisor @@ -1065,7 +1070,7 @@ LSYM(udivsi3_skip_div0_test): THUMB_DIV_MOD_BODY 0 - mov r0, result + movs r0, result pop { work } RET @@ -1132,8 +1137,8 @@ FUNC_START aeabi_uidivmod push {r0, r1, lr} bl LSYM(udivsi3_skip_div0_test) POP {r1, r2, r3} - mul r2, r0 - sub r1, r1, r2 + muls r2, r0 + subs r1, r1, r2 bx r3 # else /* Both the quotient and remainder are calculated simultaneously @@ -1147,7 +1152,7 @@ FUNC_START aeabi_uidivmod ARM_FUNC_START aeabi_uidivmod cmp r1, #0 beq LSYM(Ldiv0) - mov r2, r0 + mov r2, r0 udiv r0, r0, r1 mls r1, r0, r1, r2 RET @@ -1184,7 +1189,7 @@ ARM_FUNC_START aeabi_uidivmod cmp divisor, #0 beq LSYM(Ldiv0) - mov curbit, #1 + movs curbit, #1 cmp dividend, divisor bhs LSYM(Lover10) RET @@ -1231,29 +1236,29 @@ LSYM(Lover10): beq LSYM(Ldiv0) LSYM(divsi3_skip_div0_test): push { work } - mov work, dividend - eor work, divisor @ Save the sign of the result. + movs work, dividend + eors work, divisor @ Save the sign of the result. mov ip, work - mov curbit, #1 - mov result, #0 + movs curbit, #1 + movs result, #0 cmp divisor, #0 bpl LSYM(Lover10) - neg divisor, divisor @ Loops below use unsigned. + negs divisor, divisor @ Loops below use unsigned. LSYM(Lover10): cmp dividend, #0 bpl LSYM(Lover11) - neg dividend, dividend + negs dividend, dividend LSYM(Lover11): cmp dividend, divisor blo LSYM(Lgot_result) THUMB_DIV_MOD_BODY 0 - mov r0, result + movs r0, result mov work, ip cmp work, #0 bpl LSYM(Lover12) - neg r0, r0 + negs r0, r0 LSYM(Lover12): pop { work } RET @@ -1263,7 +1268,7 @@ LSYM(Lover12): #else LSYM(divsi3_skip_div0_test): cpy curbit, dividend - orr curbit, divisor + orrs curbit, divisor bmi LSYM(Lthumb1_div_negative) LSYM(Lthumb1_div_positive): @@ -1344,8 +1349,8 @@ FUNC_START aeabi_idivmod push {r0, r1, lr} bl LSYM(divsi3_skip_div0_test) POP {r1, r2, r3} - mul r2, r0 - sub r1, r1, r2 + muls r2, r0 + subs r1, r1, r2 bx r3 # else /* Both the quotient and remainder are calculated simultaneously @@ -1395,11 +1400,11 @@ ARM_FUNC_START aeabi_idivmod FUNC_START modsi3 - mov curbit, #1 + movs curbit, #1 cmp divisor, #0 beq LSYM(Ldiv0) bpl LSYM(Lover10) - neg divisor, divisor @ Loops below use unsigned. + negs divisor, divisor @ Loops below use unsigned. LSYM(Lover10): push { work } @ Need to save the sign of the dividend, unfortunately, we need @@ -1408,7 +1413,7 @@ LSYM(Lover10): push { dividend } cmp dividend, #0 bpl LSYM(Lover11) - neg dividend, dividend + negs dividend, dividend LSYM(Lover11): cmp dividend, divisor blo LSYM(Lgot_result) @@ -1418,7 +1423,7 @@ LSYM(Lover11): pop { work } cmp work, #0 bpl LSYM(Lover12) - neg dividend, dividend + negs dividend, dividend LSYM(Lover12): pop { work } RET @@ -1540,12 +1545,12 @@ LSYM(Lover12): address, so just clear pc..pc+1. */ #if defined __thumb__ && !defined __thumb2__ push {r7} - mov r7, #0xf - lsl r7, #16 - add r7, #2 + movs r7, #0xf + lsls r7, #16 + adds r7, #2 adr r0, . + 4 - add r1, r0, #1 - mov r2, #0 + adds r1, r0, #1 + movs r2, #0 svc 0 pop {r7} #else @@ -1595,17 +1600,17 @@ LSYM(Lover12): FUNC_ALIAS aeabi_llsr lshrdi3 #ifdef __thumb__ - lsr al, r2 - mov r3, ah - lsr ah, r2 + lsrs al, r2 + movs r3, ah + lsrs ah, r2 mov ip, r3 - sub r2, #32 - lsr r3, r2 - orr al, r3 - neg r2, r2 + subs r2, #32 + lsrs r3, r2 + orrs al, r3 + negs r2, r2 mov r3, ip - lsl r3, r2 - orr al, r3 + lsls r3, r2 + orrs al, r3 RET #else subs r3, r2, #32 @@ -1627,21 +1632,21 @@ LSYM(Lover12): FUNC_ALIAS aeabi_lasr ashrdi3 #ifdef __thumb__ - lsr al, r2 - mov r3, ah - asr ah, r2 - sub r2, #32 + lsrs al, r2 + movs r3, ah + asrs ah, r2 + subs r2, #32 @ If r2 is negative at this point the following step would OR @ the sign bit into all of AL. That's not what we want... bmi 1f mov ip, r3 - asr r3, r2 - orr al, r3 + asrs r3, r2 + orrs al, r3 mov r3, ip 1: - neg r2, r2 - lsl r3, r2 - orr al, r3 + negs r2, r2 + lsls r3, r2 + orrs al, r3 RET #else subs r3, r2, #32 @@ -1664,17 +1669,17 @@ LSYM(Lover12): FUNC_ALIAS aeabi_llsl ashldi3 #ifdef __thumb__ - lsl ah, r2 - mov r3, al - lsl al, r2 + lsls ah, r2 + movs r3, al + lsls al, r2 mov ip, r3 - sub r2, #32 - lsl r3, r2 - orr ah, r3 - neg r2, r2 + subs r2, #32 + lsls r3, r2 + orrs ah, r3 + negs r2, r2 mov r3, ip - lsr r3, r2 - orr ah, r3 + lsrs r3, r2 + orrs ah, r3 RET #else subs r3, r2, #32 @@ -1695,26 +1700,26 @@ LSYM(Lover12): #ifdef L_clzsi2 #ifdef NOT_ISA_TARGET_32BIT FUNC_START clzsi2 - mov r1, #28 - mov r3, #1 - lsl r3, r3, #16 + movs r1, #28 + movs r3, #1 + lsls r3, r3, #16 cmp r0, r3 /* 0x10000 */ bcc 2f - lsr r0, r0, #16 - sub r1, r1, #16 -2: lsr r3, r3, #8 + lsrs r0, r0, #16 + subs r1, r1, #16 +2: lsrs r3, r3, #8 cmp r0, r3 /* #0x100 */ bcc 2f - lsr r0, r0, #8 - sub r1, r1, #8 -2: lsr r3, r3, #4 + lsrs r0, r0, #8 + subs r1, r1, #8 +2: lsrs r3, r3, #4 cmp r0, r3 /* #0x10 */ bcc 2f - lsr r0, r0, #4 - sub r1, r1, #4 + lsrs r0, r0, #4 + subs r1, r1, #4 2: adr r2, 1f ldrb r0, [r2, r0] - add r0, r0, r1 + adds r0, r0, r1 bx lr .align 2 1: @@ -1757,34 +1762,49 @@ ARM_FUNC_START clzsi2 # ifdef NOT_ISA_TARGET_32BIT FUNC_START clzdi2 push {r4, lr} -# else + cmp xxh, #0 + bne 1f +# ifdef __ARMEB__ + movs r0, xxl + bl __clzsi2 + adds r0, r0, #32 + b 2f +1: + bl __clzsi2 +# else + bl __clzsi2 + adds r0, r0, #32 + b 2f +1: + movs r0, xxh + bl __clzsi2 +# endif +2: + pop {r4, pc} +# else /* NOT_ISA_TARGET_32BIT */ ARM_FUNC_START clzdi2 do_push {r4, lr} -# endif cmp xxh, #0 bne 1f -# ifdef __ARMEB__ +# ifdef __ARMEB__ mov r0, xxl bl __clzsi2 add r0, r0, #32 b 2f 1: bl __clzsi2 -# else +# else bl __clzsi2 add r0, r0, #32 b 2f 1: mov r0, xxh bl __clzsi2 -# endif +# endif 2: -# ifdef NOT_ISA_TARGET_32BIT - pop {r4, pc} -# else RETLDM r4 -# endif FUNC_END clzdi2 +# endif /* NOT_ISA_TARGET_32BIT */ #else /* defined (__ARM_FEATURE_CLZ) */ @@ -1803,28 +1823,28 @@ ARM_FUNC_START clzdi2 #ifdef L_ctzsi2 #ifdef NOT_ISA_TARGET_32BIT FUNC_START ctzsi2 - neg r1, r0 - and r0, r0, r1 - mov r1, #28 - mov r3, #1 - lsl r3, r3, #16 + negs r1, r0 + ands r0, r0, r1 + movs r1, #28 + movs r3, #1 + lsls r3, r3, #16 cmp r0, r3 /* 0x10000 */ bcc 2f - lsr r0, r0, #16 - sub r1, r1, #16 -2: lsr r3, r3, #8 + lsrs r0, r0, #16 + subs r1, r1, #16 +2: lsrs r3, r3, #8 cmp r0, r3 /* #0x100 */ bcc 2f - lsr r0, r0, #8 - sub r1, r1, #8 -2: lsr r3, r3, #4 + lsrs r0, r0, #8 + subs r1, r1, #8 +2: lsrs r3, r3, #4 cmp r0, r3 /* #0x10 */ bcc 2f - lsr r0, r0, #4 - sub r1, r1, #4 + lsrs r0, r0, #4 + subs r1, r1, #4 2: adr r2, 1f ldrb r0, [r2, r0] - sub r0, r0, r1 + subs r0, r0, r1 bx lr .align 2 1: diff --git a/libgcc/config/arm/libunwind.S b/libgcc/config/arm/libunwind.S index 176ba5e..08e0fcc 100644 --- a/libgcc/config/arm/libunwind.S +++ b/libgcc/config/arm/libunwind.S @@ -63,28 +63,28 @@ /* r0 points to a 16-word block. Upload these values to the actual core state. */ FUNC_START restore_core_regs - mov r1, r0 - add r1, r1, #52 - ldmia r1!, {r3, r4, r5} - sub r3, r3, #4 - mov ip, r3 - str r5, [r3] - mov lr, r4 + movs r1, r0 + adds r1, r1, #52 + ldmia r1!, {r3, r4, r5} + subs r3, r3, #4 + mov ip, r3 + str r5, [r3] + mov lr, r4 /* Restore r8-r11. */ - mov r1, r0 - add r1, r1, #32 - ldmia r1!, {r2, r3, r4, r5} - mov r8, r2 - mov r9, r3 - mov sl, r4 - mov fp, r5 - mov r1, r0 - add r1, r1, #8 - ldmia r1!, {r2, r3, r4, r5, r6, r7} - ldr r1, [r0, #4] - ldr r0, [r0] - mov sp, ip - pop {pc} + movs r1, r0 + adds r1, r1, #32 + ldmia r1!, {r2, r3, r4, r5} + mov r8, r2 + mov r9, r3 + mov sl, r4 + mov fp, r5 + movs r1, r0 + adds r1, r1, #8 + ldmia r1!, {r2, r3, r4, r5, r6, r7} + ldr r1, [r0, #4] + ldr r0, [r0] + mov sp, ip + pop {pc} FUNC_END restore_core_regs UNPREFIX restore_core_regs @@ -132,38 +132,38 @@ FUNC_START gnu_Unwind_Save_WMMXC FUNC_START \name /* Create a phase2_vrs structure. */ /* Save r0 in the PC slot so we can use it as a scratch register. */ - push {r0} - add r0, sp, #4 - push {r0, lr} /* Push original SP and LR. */ + push {r0} + add r0, sp, #4 + push {r0, lr} /* Push original SP and LR. */ /* Make space for r8-r12. */ - sub sp, sp, #20 + sub sp, sp, #20 /* Save low registers. */ - push {r0, r1, r2, r3, r4, r5, r6, r7} + push {r0, r1, r2, r3, r4, r5, r6, r7} /* Save high registers. */ - add r0, sp, #32 - mov r1, r8 - mov r2, r9 - mov r3, sl - mov r4, fp - mov r5, ip - stmia r0!, {r1, r2, r3, r4, r5} + add r0, sp, #32 + mov r1, r8 + mov r2, r9 + mov r3, sl + mov r4, fp + mov r5, ip + stmia r0!, {r1, r2, r3, r4, r5} /* Restore original low register values. */ - add r0, sp, #4 - ldmia r0!, {r1, r2, r3, r4, r5} + add r0, sp, #4 + ldmia r0!, {r1, r2, r3, r4, r5} /* Restore orginial r0. */ - ldr r0, [sp, #60] - str r0, [sp] + ldr r0, [sp, #60] + str r0, [sp] /* Demand-save flags, plus an extra word for alignment. */ - mov r3, #0 - push {r2, r3} + movs r3, #0 + push {r2, r3} /* Point r1 at the block. Pass r[0..nargs) unchanged. */ - add r\nargs, sp, #4 + add r\nargs, sp, #4 - bl SYM (__gnu\name) + bl SYM (__gnu\name) - ldr r3, [sp, #64] - add sp, sp, #72 - bx r3 + ldr r3, [sp, #64] + add sp, sp, #72 + bx r3 FUNC_END \name UNPREFIX \name diff --git a/libgcc/config/arm/t-arm b/libgcc/config/arm/t-arm index 274bf2a..364f40e 100644 --- a/libgcc/config/arm/t-arm +++ b/libgcc/config/arm/t-arm @@ -3,11 +3,13 @@ LIB1ASMFUNCS = _thumb1_case_sqi _thumb1_case_uqi _thumb1_case_shi \ _thumb1_case_uhi _thumb1_case_si _speculation_barrier HAVE_CMSE:=$(findstring __ARM_FEATURE_CMSE,$(shell $(gcc_compile_bare) -dM -E - </dev/null)) -ifneq ($(shell $(gcc_compile_bare) -E -mcmse - </dev/null 2>/dev/null),) +HAVE_V81M:=$(findstring armv8.1-m.main,$(gcc_compile_bare)) +ifeq ($(shell $(gcc_compile_bare) -E -mcmse - </dev/null >/dev/null 2>/dev/null; echo $?),0) CMSE_OPTS:=-mcmse endif ifdef HAVE_CMSE +ifndef HAVE_V81M libgcc-objects += cmse.o cmse_nonsecure_call.o cmse.o: $(srcdir)/config/arm/cmse.c @@ -15,3 +17,4 @@ cmse.o: $(srcdir)/config/arm/cmse.c cmse_nonsecure_call.o: $(srcdir)/config/arm/cmse_nonsecure_call.S $(gcc_compile) -c $< endif +endif diff --git a/libgcc/config/arm/unwind-arm.h b/libgcc/config/arm/unwind-arm.h index 1c82855..e77b769 100644 --- a/libgcc/config/arm/unwind-arm.h +++ b/libgcc/config/arm/unwind-arm.h @@ -43,19 +43,15 @@ extern "C" { #endif _Unwind_Ptr __attribute__((weak)) __gnu_Unwind_Find_got (_Unwind_Ptr); -static inline _Unwind_Ptr gnu_Unwind_Find_got (_Unwind_Ptr ptr) +static inline _Unwind_Ptr _Unwind_gnu_Find_got (_Unwind_Ptr ptr) { _Unwind_Ptr res; if (__gnu_Unwind_Find_got) - res = __gnu_Unwind_Find_got (ptr); + res = __gnu_Unwind_Find_got (ptr); else - { - asm volatile ("mov %[result], r" XSTR(FDPIC_REGNUM) - : [result]"=r" (res) - : - :); - } + __asm volatile ("mov %[result], r" XSTR(FDPIC_REGNUM) + : [result] "=r" (res)); return res; } @@ -75,7 +71,7 @@ static inline _Unwind_Ptr gnu_Unwind_Find_got (_Unwind_Ptr ptr) #if __FDPIC__ /* For FDPIC, we store the offset of the GOT entry. */ /* So, first get GOT from dynamic linker and then use indirect access. */ - tmp += gnu_Unwind_Find_got (ptr); + tmp += _Unwind_gnu_Find_got (ptr); tmp = *(_Unwind_Word *) tmp; #elif (defined(linux) && !defined(__uClinux__)) || defined(__NetBSD__) \ || defined(__FreeBSD__) || defined(__fuchsia__) diff --git a/libgcc/config/avr/lib1funcs.S b/libgcc/config/avr/lib1funcs.S index 8ebdc01..2ffa209 100644 --- a/libgcc/config/avr/lib1funcs.S +++ b/libgcc/config/avr/lib1funcs.S @@ -169,11 +169,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see .endm ;; Skip next instruction, typically a jump target -#if defined(__AVR_TINY__) -#define skip cpse 0,0 -#else #define skip cpse 16,16 -#endif ;; Negate a 2-byte value held in consecutive registers .macro NEG2 reg diff --git a/libgcc/config/cris/arit.c b/libgcc/config/cris/arit.c index ba1c1e7..3369559 100644 --- a/libgcc/config/cris/arit.c +++ b/libgcc/config/cris/arit.c @@ -128,7 +128,8 @@ do_31div (unsigned long a, unsigned long b) i.e. "a - (b - 1) == (a - b) + 1". */ b--; -#define DS __asm__ ("dstep %2,%0" : "=r" (a) : "0" (a), "r" (b)) +#define DS __asm__ ("dstep %2,%0" : "=r" (a) : "0" (a), "r" (b)); \ + __attribute__ ((__fallthrough__)) switch (quot_digits) { diff --git a/libgcc/config/cris/libgcc-glibc.ver b/libgcc/config/cris/libgcc-glibc.ver deleted file mode 100644 index e35de83..0000000 --- a/libgcc/config/cris/libgcc-glibc.ver +++ /dev/null @@ -1,7 +0,0 @@ -GCC_4.3 { - __Mul - __Div - __Udiv - __Mod - __Umod -} diff --git a/libgcc/config/cris/t-linux b/libgcc/config/cris/t-linux deleted file mode 100644 index 8c7f4d4..0000000 --- a/libgcc/config/cris/t-linux +++ /dev/null @@ -1,2 +0,0 @@ -# Override t-linux default. -SHLIB_MAPFILES = libgcc-std.ver $(srcdir)/config/cris/libgcc-glibc.ver diff --git a/libgcc/config/frv/frvbegin.c b/libgcc/config/frv/frvbegin.c index 8ab1a1b..0f54bf1 100644 --- a/libgcc/config/frv/frvbegin.c +++ b/libgcc/config/frv/frvbegin.c @@ -59,8 +59,8 @@ __asm__ (".section " SECTION "," FLAGS "\n\t" \ /* Beginning of .ctor/.dtor sections that provides a list of constructors and destructors to run. */ -INIT_SECTION_NEG_ONE (".ctors", "\"aw\"", "__CTOR_LIST__"); -INIT_SECTION_NEG_ONE (".dtors", "\"aw\"", "__DTOR_LIST__"); +INIT_SECTION_NEG_ONE (".ctors", "\"a\"", "__CTOR_LIST__"); +INIT_SECTION_NEG_ONE (".dtors", "\"a\"", "__DTOR_LIST__"); /* Beginning of .eh_frame section that provides all of the exception handling tables. */ diff --git a/libgcc/config/frv/frvend.c b/libgcc/config/frv/frvend.c index eb3494c..d2b83b2 100644 --- a/libgcc/config/frv/frvend.c +++ b/libgcc/config/frv/frvend.c @@ -52,8 +52,8 @@ __asm__ (".section " SECTION "," FLAGS "\n\t" \ /* End of .ctor/.dtor sections that provides a list of constructors and destructors to run. */ -FINI_SECTION_ZERO (".ctors", "\"aw\"", "__CTOR_END__"); -FINI_SECTION_ZERO (".dtors", "\"aw\"", "__DTOR_END__"); +FINI_SECTION_ZERO (".ctors", "\"a\"", "__CTOR_END__"); +FINI_SECTION_ZERO (".dtors", "\"a\"", "__DTOR_END__"); /* End of .eh_frame section that provides all of the exception handling tables. */ diff --git a/libgcc/config/gcn/atomic.c b/libgcc/config/gcn/atomic.c new file mode 100644 index 0000000..adceb02 --- /dev/null +++ b/libgcc/config/gcn/atomic.c @@ -0,0 +1,59 @@ +/* AMD GCN atomic operations + Copyright (C) 2020 Free Software Foundation, Inc. + Contributed by Mentor Graphics. + + 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/>. */ + +#include <stdbool.h> + +#define __SYNC_SUBWORD_COMPARE_AND_SWAP(TYPE, SIZE) \ + \ +TYPE \ +__sync_val_compare_and_swap_##SIZE (TYPE *ptr, TYPE oldval, TYPE newval) \ +{ \ + unsigned int *wordptr = (unsigned int *)((__UINTPTR_TYPE__ ) ptr & ~3UL); \ + int shift = ((__UINTPTR_TYPE__ ) ptr & 3UL) * 8; \ + unsigned int valmask = (1 << (SIZE * 8)) - 1; \ + unsigned int wordmask = ~(valmask << shift); \ + unsigned int oldword = *wordptr; \ + for (;;) \ + { \ + TYPE prevval = (oldword >> shift) & valmask; \ + if (__builtin_expect (prevval != oldval, 0)) \ + return prevval; \ + unsigned int newword = oldword & wordmask; \ + newword |= ((unsigned int) newval) << shift; \ + unsigned int prevword \ + = __sync_val_compare_and_swap_4 (wordptr, oldword, newword); \ + if (__builtin_expect (prevword == oldword, 1)) \ + return oldval; \ + oldword = prevword; \ + } \ +} \ + \ +bool \ +__sync_bool_compare_and_swap_##SIZE (TYPE *ptr, TYPE oldval, TYPE newval) \ +{ \ + return __sync_val_compare_and_swap_##SIZE (ptr, oldval, newval) == oldval; \ +} + +__SYNC_SUBWORD_COMPARE_AND_SWAP (unsigned char, 1) +__SYNC_SUBWORD_COMPARE_AND_SWAP (unsigned short, 2) + diff --git a/libgcc/config/gcn/t-amdgcn b/libgcc/config/gcn/t-amdgcn index adbd866..fe7b5fa 100644 --- a/libgcc/config/gcn/t-amdgcn +++ b/libgcc/config/gcn/t-amdgcn @@ -1,4 +1,5 @@ -LIB2ADD += $(srcdir)/config/gcn/lib2-divmod.c \ +LIB2ADD += $(srcdir)/config/gcn/atomic.c \ + $(srcdir)/config/gcn/lib2-divmod.c \ $(srcdir)/config/gcn/lib2-divmod-hi.c \ $(srcdir)/config/gcn/unwind-gcn.c diff --git a/libgcc/config/i386/cpuinfo.c b/libgcc/config/i386/cpuinfo.c index 00322c5..cf5f088 100644 --- a/libgcc/config/i386/cpuinfo.c +++ b/libgcc/config/i386/cpuinfo.c @@ -346,9 +346,13 @@ get_available_features (unsigned int ecx, unsigned int edx, { if (ebx & bit_AVX2) set_feature (FEATURE_AVX2); + if (ecx & bit_VPCLMULQDQ) + set_feature (FEATURE_VPCLMULQDQ); } if (ebx & bit_BMI2) set_feature (FEATURE_BMI2); + if (ecx & bit_GFNI) + set_feature (FEATURE_GFNI); if (avx512_usable) { if (ebx & bit_AVX512F) @@ -371,10 +375,6 @@ get_available_features (unsigned int ecx, unsigned int edx, 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) @@ -385,6 +385,8 @@ get_available_features (unsigned int ecx, unsigned int edx, set_feature (FEATURE_AVX5124VNNIW); if (edx & bit_AVX5124FMAPS) set_feature (FEATURE_AVX5124FMAPS); + if (edx & bit_AVX512VP2INTERSECT) + set_feature (FEATURE_AVX512VP2INTERSECT); __cpuid_count (7, 1, eax, ebx, ecx, edx); if (eax & bit_AVX512BF16) diff --git a/libgcc/config/i386/cpuinfo.h b/libgcc/config/i386/cpuinfo.h index 41c4a49..0f97510 100644 --- a/libgcc/config/i386/cpuinfo.h +++ b/libgcc/config/i386/cpuinfo.h @@ -122,7 +122,8 @@ enum processor_features FEATURE_VPCLMULQDQ, FEATURE_AVX512VNNI, FEATURE_AVX512BITALG, - FEATURE_AVX512BF16 + FEATURE_AVX512BF16, + FEATURE_AVX512VP2INTERSECT }; extern struct __processor_model diff --git a/libgcc/config/i386/sfp-exceptions.c b/libgcc/config/i386/sfp-exceptions.c index c994491..3aed0af 100644 --- a/libgcc/config/i386/sfp-exceptions.c +++ b/libgcc/config/i386/sfp-exceptions.c @@ -39,26 +39,28 @@ struct fenv unsigned int __data_offset; unsigned short int __data_selector; unsigned short int __unused5; -}; +} __attribute__ ((gcc_struct)); + +#ifdef __SSE_MATH__ +# define __math_force_eval_div(x, y) \ + do { asm ("" : "+x" (x)); asm volatile ("" : : "x" (x / y)); } while (0) +#else +# define __math_force_eval_div(x, y) \ + do { asm ("" : "+t" (x)); asm volatile ("" : : "f" (x / y)); } while (0) +#endif void __sfp_handle_exceptions (int _fex) { + struct fenv temp; + if (_fex & FP_EX_INVALID) { float f = 0.0f; -#ifdef __SSE_MATH__ - volatile float r __attribute__ ((unused)); - asm volatile ("%vdivss\t{%0, %d0|%d0, %0}" : "+x" (f)); - r = f; /* Needed to trigger exception. */ -#else - asm volatile ("fdiv\t{%y0, %0|%0, %y0}" : "+t" (f)); - /* No need for fwait, exception is triggered by emitted fstp. */ -#endif + __math_force_eval_div (f, f); } if (_fex & FP_EX_DENORM) { - struct fenv temp; asm volatile ("fnstenv\t%0" : "=m" (temp)); temp.__status_word |= FP_EX_DENORM; asm volatile ("fldenv\t%0" : : "m" (temp)); @@ -67,18 +69,10 @@ __sfp_handle_exceptions (int _fex) if (_fex & FP_EX_DIVZERO) { float f = 1.0f, g = 0.0f; -#ifdef __SSE_MATH__ - volatile float r __attribute__ ((unused)); - asm volatile ("%vdivss\t{%1, %d0|%d0, %1}" : "+x" (f) : "xm" (g)); - r = f; /* Needed to trigger exception. */ -#else - asm volatile ("fdivs\t%1" : "+t" (f) : "m" (g)); - /* No need for fwait, exception is triggered by emitted fstp. */ -#endif + __math_force_eval_div (f, g); } if (_fex & FP_EX_OVERFLOW) { - struct fenv temp; asm volatile ("fnstenv\t%0" : "=m" (temp)); temp.__status_word |= FP_EX_OVERFLOW; asm volatile ("fldenv\t%0" : : "m" (temp)); @@ -86,7 +80,6 @@ __sfp_handle_exceptions (int _fex) } if (_fex & FP_EX_UNDERFLOW) { - struct fenv temp; asm volatile ("fnstenv\t%0" : "=m" (temp)); temp.__status_word |= FP_EX_UNDERFLOW; asm volatile ("fldenv\t%0" : : "m" (temp)); @@ -95,14 +88,7 @@ __sfp_handle_exceptions (int _fex) if (_fex & FP_EX_INEXACT) { float f = 1.0f, g = 3.0f; -#ifdef __SSE_MATH__ - volatile float r __attribute__ ((unused)); - asm volatile ("%vdivss\t{%1, %d0|%d0, %1}" : "+x" (f) : "xm" (g)); - r = f; /* Needed to trigger exception. */ -#else - asm volatile ("fdivs\t%1" : "+t" (f) : "m" (g)); - /* No need for fwait, exception is triggered by emitted fstp. */ -#endif + __math_force_eval_div (f, g); } } #endif diff --git a/libgcc/config/i386/shadow-stack-unwind.h b/libgcc/config/i386/shadow-stack-unwind.h index a0244d2e..201b2153 100644 --- a/libgcc/config/i386/shadow-stack-unwind.h +++ b/libgcc/config/i386/shadow-stack-unwind.h @@ -49,3 +49,46 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see } \ } \ while (0) + +/* Linux CET kernel places a restore token on shadow stack for signal + handler to enhance security. The restore token is 8 byte and aligned + to 8 bytes. It is usually transparent to user programs since kernel + will pop the restore token when signal handler returns. But when an + exception is thrown from a signal handler, now we need to pop the + restore token from shadow stack. For x86-64, we just need to treat + the signal frame as normal frame. For i386, we need to search for + the restore token to check if the original shadow stack is 8 byte + aligned. If the original shadow stack is 8 byte aligned, we just + need to pop 2 slots, one restore token, from shadow stack. Otherwise, + we need to pop 3 slots, one restore token + 4 byte padding, from + shadow stack. */ +#ifndef __x86_64__ +#undef _Unwind_Frames_Increment +#define _Unwind_Frames_Increment(context, frames) \ + if (_Unwind_IsSignalFrame (context)) \ + do \ + { \ + _Unwind_Word ssp, prev_ssp, token; \ + ssp = _get_ssp (); \ + if (ssp != 0) \ + { \ + /* Align shadow stack pointer to the next \ + 8 byte aligned boundary. */ \ + ssp = (ssp + 4) & ~7; \ + do \ + { \ + /* Look for a restore token. */ \ + token = (*(_Unwind_Word *) (ssp - 8)); \ + prev_ssp = token & ~7; \ + if (prev_ssp == ssp) \ + break; \ + ssp += 8; \ + } \ + while (1); \ + frames += (token & 0x4) ? 3 : 2; \ + } \ + } \ + while (0); \ + else \ + frames++; +#endif diff --git a/libgcc/config/ia64/divtf3.c b/libgcc/config/ia64/divtf3.c new file mode 100644 index 0000000..e1afa29 --- /dev/null +++ b/libgcc/config/ia64/divtf3.c @@ -0,0 +1,9 @@ +#ifdef SHARED +#define __divtf3 __divtf3_shared +#endif + +#include "soft-fp/divtf3.c" + +#ifdef SHARED +asm (".symver __divtf3_shared, __divtf3@@GCC_4.4.0"); +#endif diff --git a/libgcc/config/ia64/t-softfp-compat b/libgcc/config/ia64/t-softfp-compat index 00f45d5..38bcea7 100644 --- a/libgcc/config/ia64/t-softfp-compat +++ b/libgcc/config/ia64/t-softfp-compat @@ -5,3 +5,6 @@ libgcc1-tf-functions = __divxf3 _fixtfdi _fixunstfdi _floatditf LIB1ASMFUNCS := $(filter-out $(libgcc1-tf-functions), $(LIB1ASMFUNCS)) libgcc1-tf-compats = $(addsuffix .S, $(libgcc1-tf-functions)) LIB2ADD += $(addprefix $(srcdir)/config/ia64/, $(libgcc1-tf-compats)) +# Wrap divtf3.c to set the default symbol version +softfp_file_list := $(filter-out $(srcdir)/soft-fp/divtf3.c, $(softfp_file_list)) +LIB2ADD += $(srcdir)/config/ia64/divtf3.c diff --git a/libgcc/config/libbid/ChangeLog b/libgcc/config/libbid/ChangeLog index 0920863..a1a9f46 100644 --- a/libgcc/config/libbid/ChangeLog +++ b/libgcc/config/libbid/ChangeLog @@ -1,3 +1,9 @@ +2020-05-05 Martin Liska <mliska@suse.cz> + + PR libgcc/92565 + * bid_internal.h (handle_UF_128_rem): Remove unused variable. + (handle_UF_128): Likewise. + 2020-01-01 Jakub Jelinek <jakub@redhat.com> Update copyright years. diff --git a/libgcc/config/libbid/bid_internal.h b/libgcc/config/libbid/bid_internal.h index cef36a9..9baa098 100644 --- a/libgcc/config/libbid/bid_internal.h +++ b/libgcc/config/libbid/bid_internal.h @@ -1540,8 +1540,6 @@ handle_UF_128_rem (UINT128 * pres, UINT64 sgn, int expon, UINT128 CQ, __shr_128 (CQ, Qh, amount); } - expon = 0; - #ifndef IEEE_ROUND_NEAREST_TIES_AWAY #ifndef IEEE_ROUND_NEAREST if (!(*prounding_mode)) @@ -1676,8 +1674,6 @@ handle_UF_128 (UINT128 * pres, UINT64 sgn, int expon, UINT128 CQ, __shr_128 (CQ, Qh, amount); } - expon = 0; - #ifndef IEEE_ROUND_NEAREST_TIES_AWAY #ifndef IEEE_ROUND_NEAREST if (!(*prounding_mode)) diff --git a/libgcc/config/mips/crti.S b/libgcc/config/mips/crti.S index 3347a78..6705642 100644 --- a/libgcc/config/mips/crti.S +++ b/libgcc/config/mips/crti.S @@ -21,6 +21,9 @@ 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/>. */ +/* An executable stack is *not* required for these functions. */ +#include "gnustack.h" + /* 4 slots for argument spill area. 1 for cpreturn, 1 for stack. Return spill offset of 40 and 20. Aligned to 16 bytes for n32. */ diff --git a/libgcc/config/mips/crtn.S b/libgcc/config/mips/crtn.S index 7f46829..ceede64 100644 --- a/libgcc/config/mips/crtn.S +++ b/libgcc/config/mips/crtn.S @@ -21,6 +21,9 @@ 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/>. */ +/* An executable stack is *not* required for these functions. */ +#include "gnustack.h" + /* 4 slots for argument spill area. 1 for cpreturn, 1 for stack. Return spill offset of 40 and 20. Aligned to 16 bytes for n32. */ diff --git a/libgcc/config/mips/gnustack.h b/libgcc/config/mips/gnustack.h new file mode 100644 index 0000000..561b348 --- /dev/null +++ b/libgcc/config/mips/gnustack.h @@ -0,0 +1,7 @@ +#include "config.h" +#if defined(__ELF__) && defined(__linux__) +#if defined (TARGET_LIBC_GNUSTACK) || defined (__mips_soft_float) + .section .note.GNU-stack,"",%progbits + .previous +#endif +#endif diff --git a/libgcc/config/mips/mips16.S b/libgcc/config/mips/mips16.S index 396285e..5c3678b 100644 --- a/libgcc/config/mips/mips16.S +++ b/libgcc/config/mips/mips16.S @@ -21,6 +21,9 @@ 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/>. */ +/* An executable stack is *not* required for these functions. */ +#include "gnustack.h" + #include "auto-host.h" #if defined(__mips_micromips) || defined(__mips_soft_float) \ diff --git a/libgcc/config/mips/vr4120-div.S b/libgcc/config/mips/vr4120-div.S index 92226b5..2999c77 100644 --- a/libgcc/config/mips/vr4120-div.S +++ b/libgcc/config/mips/vr4120-div.S @@ -22,6 +22,9 @@ 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/>. */ +/* An executable stack is *not* required for these functions. */ +#include "gnustack.h" + /* This file contains functions which implement divsi3 and modsi3 for -mfix-vr4120. div and ddiv do not give the correct result when one of the operands is negative. */ diff --git a/libgcc/config/nios2/elf-lib.h b/libgcc/config/nios2/elf-lib.h new file mode 100644 index 0000000..4d718d9 --- /dev/null +++ b/libgcc/config/nios2/elf-lib.h @@ -0,0 +1,24 @@ +/* Target macros for the Nios II port of GCC. + Copyright (C) 2015-2020 Free Software Foundation, Inc. + +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/>. */ + +#define CRT_GET_RFIB_DATA(dbase) \ + ({ extern void *_gp_got; (dbase) = &_gp_got; }) diff --git a/libgcc/config/riscv/div.S b/libgcc/config/riscv/div.S index 151f8e2..1723432 100644 --- a/libgcc/config/riscv/div.S +++ b/libgcc/config/riscv/div.S @@ -107,10 +107,12 @@ FUNC_END (__umoddi3) /* Handle negative arguments to __divdi3. */ .L10: neg a0, a0 - bgez a1, .L12 /* Compute __udivdi3(-a0, a1), then negate the result. */ + /* Zero is handled as a negative so that the result will not be inverted. */ + bgtz a1, .L12 /* Compute __udivdi3(-a0, a1), then negate the result. */ + neg a1, a1 - j __udivdi3 /* Compute __udivdi3(-a0, -a1). */ -.L11: /* Compute __udivdi3(a0, -a1), then negate the result. */ + j __udivdi3 /* Compute __udivdi3(-a0, -a1). */ +.L11: /* Compute __udivdi3(a0, -a1), then negate the result. */ neg a1, a1 .L12: move t0, ra diff --git a/libgcc/config/rs6000/crtresfpr.S b/libgcc/config/rs6000/crtresfpr.S index 6c0d01b..99e6f08 100644 --- a/libgcc/config/rs6000/crtresfpr.S +++ b/libgcc/config/rs6000/crtresfpr.S @@ -27,6 +27,7 @@ /* Do any initializations needed for the eabi environment */ + .machine ppc .section ".text" #include "ppc-asm.h" diff --git a/libgcc/config/rs6000/crtresxfpr.S b/libgcc/config/rs6000/crtresxfpr.S index 9f01fa5..9931db2 100644 --- a/libgcc/config/rs6000/crtresxfpr.S +++ b/libgcc/config/rs6000/crtresxfpr.S @@ -27,6 +27,7 @@ /* Do any initializations needed for the eabi environment */ + .machine ppc .section ".text" #include "ppc-asm.h" diff --git a/libgcc/config/rs6000/crtsavfpr.S b/libgcc/config/rs6000/crtsavfpr.S index fa043dd..dd8743a 100644 --- a/libgcc/config/rs6000/crtsavfpr.S +++ b/libgcc/config/rs6000/crtsavfpr.S @@ -27,6 +27,7 @@ /* Do any initializations needed for the eabi environment */ + .machine ppc .section ".text" #include "ppc-asm.h" diff --git a/libgcc/config/s390/t-tpf b/libgcc/config/s390/t-tpf new file mode 100644 index 0000000..50da223 --- /dev/null +++ b/libgcc/config/s390/t-tpf @@ -0,0 +1,7 @@ +DFP_ENABLE = true + +# Override t-slibgcc-elf-ver to export some libgcc symbols with +# the symbol versions that glibc used. +SHLIB_MAPFILES = libgcc-std.ver $(srcdir)/config/s390/libgcc-glibc.ver + +HOST_LIBGCC2_CFLAGS += -mlong-double-128 -mtpf-trace-skip diff --git a/libgcc/config/s390/tpf-unwind.h b/libgcc/config/s390/tpf-unwind.h index 2bd5493..fadc06b 100644 --- a/libgcc/config/s390/tpf-unwind.h +++ b/libgcc/config/s390/tpf-unwind.h @@ -32,20 +32,29 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see Description: This function simply checks to see if the address passed to it is in the CP pat code range. */ -#define MIN_PATRANGE 0x10000 -#define MAX_PATRANGE 0x800000 +#define CP_CNF 0x000000000000c18u /* location of BSS CINFC pointer */ +#define cinfc_fast(TAG) (void *) \ + *((unsigned long *) *(unsigned long *) (CP_CNF) + (TAG)) +#define CINFC_CMRESET 187 +#define CINTFC_CMCENBKST 431 +#define CINTFC_CMCENBKED 432 static inline unsigned int __isPATrange (void *addr) { - if (addr > (void *)MIN_PATRANGE && addr < (void *)MAX_PATRANGE) - return 1; - else - return 0; + return !!(addr > cinfc_fast (CINTFC_CMCENBKST) + && addr < cinfc_fast (CINTFC_CMCENBKED)); +} + +static inline unsigned int +__isSkipResetAddr (void *addr) +{ + return !!(addr == cinfc_fast (CINFC_CMRESET)); } /* TPF return address offset from start of stack frame. */ -#define TPFRA_OFFSET 168 +#define ICST_CRET 168 +#define ICST_SRET 320 /* Exceptions macro defined for TPF so that functions without dwarf frame information can be used with exceptions. */ @@ -63,12 +72,12 @@ s390_fallback_frame_state (struct _Unwind_Context *context, (((unsigned long int) context->cfa) - STACK_POINTER_OFFSET)); /* Are we going through special linkage code? */ - if (__isPATrange (context->ra)) + if (__isPATrange (context->ra) || __isSkipResetAddr (context->ra)) { /* Our return register isn't zero for end of stack, so check backward stackpointer to see if it is zero. */ - if (regs == NULL) + if (regs == 0) return _URC_END_OF_STACK; /* No stack frame. */ @@ -83,11 +92,18 @@ s390_fallback_frame_state (struct _Unwind_Context *context, fs->regs.reg[i].loc.reg = i; } - /* ... except for %r14, which is stored at CFA-112 - and used as return address. */ - fs->regs.reg[14].how = REG_SAVED_OFFSET; - fs->regs.reg[14].loc.offset = TPFRA_OFFSET - STACK_POINTER_OFFSET; - fs->retaddr_column = 14; + /* ... except for %r14, which is stored at CFA+offset where offset + is displacment of ICST_CRET or ICST_SRET from CFA */ + if ( __isPATrange(context->ra) ) { + fs->regs.reg[14].how = REG_SAVED_OFFSET; + fs->regs.reg[14].loc.offset = ICST_CRET - STACK_POINTER_OFFSET; + fs->retaddr_column = 14; + } else { + fs->regs.reg[14].how = REG_SAVED_OFFSET; + fs->regs.reg[14].loc.offset = ICST_SRET - STACK_POINTER_OFFSET; + fs->retaddr_column = 14; + + } return _URC_NO_REASON; } @@ -140,6 +156,9 @@ s390_fallback_frame_state (struct _Unwind_Context *context, #define TPFAREA_SIZE STACK_POINTER_OFFSET-TPFAREA_OFFSET #define INVALID_RETURN 0 +#define LOWCORE_PAGE3_ADDR 4032 +#define PG3_SKIPPING_OFFSET 18 + void * __tpf_eh_return (void *target, void *origRA); void * @@ -148,30 +167,29 @@ __tpf_eh_return (void *target, void *origRA) Dl_info targetcodeInfo, currentcodeInfo; int retval; void *current, *stackptr, *destination_frame; + unsigned char *skipFlagAddress; unsigned long int shifter; - bool is_a_stub, frameDepth2, firstIteration; + bool is_a_stub; is_a_stub = false; - frameDepth2 = false; - firstIteration = true; /* Get code info for target return's address. */ retval = dladdr (target, &targetcodeInfo); - /* Check if original RA is a Pat stub. If so set flag. */ - if (__isPATrange (origRA)) - frameDepth2 = true; - /* Ensure the code info is valid (for target). */ if (retval != INVALID_RETURN) { - /* Get the stack pointer of the first stack frame beyond the - unwinder or if exists the calling C++ runtime function (e.g., - __cxa_throw). */ - if (!frameDepth2) - stackptr = (void *) *((unsigned long int *) (*(PREVIOUS_STACK_PTR()))); - else - stackptr = (void *) *(PREVIOUS_STACK_PTR()); + /* Begin climbing stack searching for target address. */ + stackptr = (void *) *(CURRENT_STACK_PTR()); + + /* Get return address based on our stackptr. */ + current = (void *) *(unsigned long *) (stackptr + RA_OFFSET); + + /* Is current return address our initiating exception stack + frame? If not, climb the stack one more frame. */ + if (current != origRA) { + stackptr = (void *) *(unsigned long *) stackptr; + } /* Begin looping through stack frames. Stop if invalid code information is retrieved or if a match between the @@ -179,27 +197,19 @@ __tpf_eh_return (void *target, void *origRA) matches that of the target, calculated above. */ do { - if (!frameDepth2 || (frameDepth2 && !firstIteration)) - { - /* Get return address based on our stackptr iterator. */ - current = (void *) *((unsigned long int *) - (stackptr + RA_OFFSET)); - - /* Is it a Pat Stub? */ - if (__isPATrange (current)) - { - /* Yes it was, get real return address in TPF stack area. */ - current = (void *) *((unsigned long int *) - (stackptr + TPFRA_OFFSET)) - is_a_stub = true; - } - } - else - { - current = (void *) *((unsigned long int *) - (stackptr + TPFRA_OFFSET)); - is_a_stub = true; - } + /* Get return address based on our stackptr iterator. */ + current = (void *) *(unsigned long *) (stackptr + RA_OFFSET); + + /* Is it a Pat Stub? */ + if (__isPATrange (current) + || (__isSkipResetAddr (current) + && __isPATrange ((void *) *(unsigned long *) (stackptr + + ICST_SRET)))) + { + /* Yes it was, get real return address in TPF stack area. */ + current = (void *) *(unsigned long *) (stackptr + ICST_CRET); + is_a_stub = true; + } /* Get codeinfo on RA so that we can figure out the module address. */ @@ -227,8 +237,8 @@ __tpf_eh_return (void *target, void *origRA) /* Now overlay the real target address into the TPF stack area of the target frame we are jumping to. */ - *((unsigned long int *) (destination_frame + - TPFRA_OFFSET)) = (unsigned long int) target; + *(unsigned long *) (destination_frame + ICST_CRET) = + (unsigned long) target; /* Before returning the desired pat stub address to the exception handling unwinder so that it can @@ -237,10 +247,7 @@ __tpf_eh_return (void *target, void *origRA) This is necessary for CTOA stubs. Otherwise we leap one byte past where we want to go to in the TPF pat stub linkage code. */ - if (!frameDepth2 || (frameDepth2 && !firstIteration)) - shifter = *((unsigned long int *) (stackptr + RA_OFFSET)); - else - shifter = (unsigned long int) origRA; + shifter = *(unsigned long *) (stackptr + RA_OFFSET); shifter &= ~1ul; @@ -252,6 +259,13 @@ __tpf_eh_return (void *target, void *origRA) in linkage. */ shifter = shifter - 4; + /* Reset the Function Trace Skipping Switch to re-enable */ + /* recording Trace entries if it was turned off. */ + skipFlagAddress = + (unsigned char *) *(unsigned long *) LOWCORE_PAGE3_ADDR; + skipFlagAddress += PG3_SKIPPING_OFFSET; + *skipFlagAddress = '\x00'; + return (void *) shifter; } @@ -260,14 +274,18 @@ __tpf_eh_return (void *target, void *origRA) stackptr = (void *) *(unsigned long int *) stackptr; is_a_stub = false; - firstIteration = false; } while (stackptr && retval != INVALID_RETURN && targetcodeInfo.dli_fbase != currentcodeInfo.dli_fbase); } + /* Reset the Function Trace Skipping Switch to re-enable */ + /* recording Trace entries if it was turned off. */ + skipFlagAddress = (unsigned char *) *(unsigned long *) LOWCORE_PAGE3_ADDR; + skipFlagAddress += PG3_SKIPPING_OFFSET; + *skipFlagAddress = '\x00'; + /* No pat stub found, could be a problem? Simply return unmodified target address. */ return target; } - diff --git a/libgcc/config/xtensa/unwind-dw2-xtensa.c b/libgcc/config/xtensa/unwind-dw2-xtensa.c index 056182a..8a6a44a 100644 --- a/libgcc/config/xtensa/unwind-dw2-xtensa.c +++ b/libgcc/config/xtensa/unwind-dw2-xtensa.c @@ -481,37 +481,35 @@ uw_init_context_1 (struct _Unwind_Context *context, void *outer_cfa, /* Install TARGET into CURRENT so that we can return to it. This is a macro because __builtin_eh_return must be invoked in the context of - our caller. */ + our caller, and also because spilling registers of the caller before + the context installation may result in reload of wrong register values + after the context installation due to the change of the stack pointer + in the base save area. This spilling may be caused by an interrupt + handler on baremetal host. */ -#define uw_install_context(CURRENT, TARGET, FRAMES) \ +#define uw_install_context(CURRENT, TARGET, FRAMES) \ do \ { \ - long offset = uw_install_context_1 ((CURRENT), (TARGET)); \ void *handler = __builtin_frob_return_addr ((TARGET)->ra); \ - __builtin_eh_return (offset, handler); \ + long i; \ + \ + /* The eh_return insn assumes a window size of 8, so don't bother \ + copying the save areas for registers a8-a15 since they won't be \ + reloaded. */ \ + for (i = 0; i < 2; ++i) \ + { \ + _Unwind_Word *c = (CURRENT)->reg[i]; \ + _Unwind_Word *t = (TARGET)->reg[i]; \ + int j; \ + \ + if (t && c && t != c) \ + for (j = 0; j < 4; ++j) \ + *c++ = *t++; \ + } \ + __builtin_eh_return (0, handler); \ } \ while (0) -static long -uw_install_context_1 (struct _Unwind_Context *current, - struct _Unwind_Context *target) -{ - long i; - - /* The eh_return insn assumes a window size of 8, so don't bother copying - the save areas for registers a8-a15 since they won't be reloaded. */ - for (i = 0; i < 2; ++i) - { - void *c = current->reg[i]; - void *t = target->reg[i]; - - if (t && c && t != c) - memcpy (c, t, 4 * sizeof (_Unwind_Word)); - } - - return 0; -} - static inline _Unwind_Ptr uw_identify_context (struct _Unwind_Context *context) { diff --git a/libgcc/configure b/libgcc/configure index 97cbad3..284e4db 100755 --- a/libgcc/configure +++ b/libgcc/configure @@ -705,6 +705,7 @@ enable_gcov enable_vtable_verify with_aix_soname enable_version_specific_runtime_libs +with_toolexeclibdir with_slibdir enable_maintainer_mode with_build_libsubdir @@ -1352,7 +1353,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=no] + --enable-cet enable Intel CET in target libraries [default=auto] --enable-explicit-exception-frame-registration register exception tables explicitly at module start, for use e.g. for compatibility with @@ -1369,6 +1370,9 @@ Optional Packages: --with-aix-soname=aix|svr4|both shared library versioning (aka "SONAME") variant to provide on AIX + --with-toolexeclibdir=DIR + install libraries built with a cross compiler within + DIR --with-slibdir=DIR shared libraries in DIR LIBDIR --with-build-libsubdir=DIR Directory where to find libraries for build system --with-system-libunwind use installed libunwind @@ -2464,6 +2468,22 @@ fi $as_echo "$version_specific_libs" >&6; } +# Check whether --with-toolexeclibdir was given. +if test "${with_toolexeclibdir+set}" = set; then : + withval=$with_toolexeclibdir; case ${with_toolexeclibdir} in + /) + ;; + */) + with_toolexeclibdir=`echo $with_toolexeclibdir | sed 's,/$,,'` + ;; +esac +else + with_toolexeclibdir=no +fi + + + + # Check whether --with-slibdir was given. if test "${with_slibdir+set}" = set; then : withval=$with_slibdir; slibdir="$with_slibdir" @@ -2471,7 +2491,14 @@ else if test "${version_specific_libs}" = yes; then slibdir='$(libsubdir)' elif test -n "$with_cross_host" && test x"$with_cross_host" != x"no"; then - slibdir='$(exec_prefix)/$(host_noncanonical)/lib' + case ${with_toolexeclibdir} in + no) + slibdir='$(exec_prefix)/$(host_noncanonical)/lib' + ;; + *) + slibdir=${with_toolexeclibdir} + ;; + esac else slibdir='$(libdir)' fi @@ -2701,7 +2728,14 @@ case ${version_specific_libs} in test x"$with_cross_host" != x"no"; then # Install a library built with a cross compiler in tooldir, not libdir. toolexecdir='$(exec_prefix)/$(target_noncanonical)' - toolexeclibdir='$(toolexecdir)/lib' + case ${with_toolexeclibdir} in + no) + toolexeclibdir='$(toolexecdir)/lib' + ;; + *) + toolexeclibdir=${with_toolexeclibdir} + ;; + esac else toolexecdir='$(libdir)/gcc-lib/$(target_noncanonical)' toolexeclibdir='$(libdir)' @@ -3519,11 +3553,11 @@ done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - +#include <stdio.h> int main () { - +printf ("hello world\n"); ; return 0; } @@ -4866,19 +4900,22 @@ if test "${enable_cet+set}" = set; then : esac else - enable_cet=no + enable_cet=auto fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CET support" >&5 $as_echo_n "checking for CET support... " >&6; } +# NB: Avoid nested save_CFLAGS and save_LDFLAGS. case "$host" in i[34567]86-*-linux* | x86_64-*-linux*) case "$enable_cet" in auto) # Check if target supports multi-byte NOPs # and if assembler supports CET insn. + cet_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fcf-protection" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -4902,6 +4939,7 @@ else enable_cet=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS="$cet_save_CFLAGS" ;; yes) # Check if assembler supports CET. @@ -5292,19 +5330,17 @@ esac # This is after config.host so we can augment tmake_file. case ${host} in xtensa*-*) - cat > conftest.c <<EOF - #ifdef __XTENSA_CALL0_ABI__ - #error - #endif -EOF - if { ac_try='${CC-cc} -E -o conftest.i conftest.c 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 - tmake_file="${tmake_file} xtensa/t-windowed" - fi + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __XTENSA_CALL0_ABI__ + #error + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + tmake_file="${tmake_file} xtensa/t-windowed" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ;; esac @@ -5496,6 +5532,46 @@ $as_echo "#define HAVE_AS_AVX 1" >>confdefs.h ;; esac + + +case "${target}" in +aarch64*-*-*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the assembler supports LSE" >&5 +$as_echo_n "checking if the assembler supports LSE... " >&6; } +if ${libgcc_cv_as_lse+:} false; then : + $as_echo_n "(cached) " >&6 +else + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + asm(".arch armv8-a+lse\n\tcas w0, w1, [x2]"); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + libgcc_cv_as_lse=yes +else + libgcc_cv_as_lse=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgcc_cv_as_lse" >&5 +$as_echo "$libgcc_cv_as_lse" >&6; } + if test x$libgcc_cv_as_lse = xyes; then + +$as_echo "#define HAVE_AS_LSE 1" >>confdefs.h + + fi + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for init priority support" >&5 $as_echo_n "checking for init priority support... " >&6; } if ${libgcc_cv_init_priority+:} false; then : diff --git a/libgcc/configure.ac b/libgcc/configure.ac index 2d22f05..ef0d799 100644 --- a/libgcc/configure.ac +++ b/libgcc/configure.ac @@ -2,6 +2,7 @@ dnl Process this file with autoconf to produce a configure script. sinclude(../config/enable.m4) sinclude(../config/tls.m4) +sinclude(../config/toolexeclibdir.m4) sinclude(../config/acx.m4) sinclude(../config/no-executables.m4) sinclude(../config/lib-ld.m4) @@ -113,16 +114,25 @@ AC_ARG_ENABLE(version-specific-runtime-libs, [version_specific_libs=no]) AC_MSG_RESULT($version_specific_libs) +GCC_WITH_TOOLEXECLIBDIR + AC_ARG_WITH(slibdir, [ --with-slibdir=DIR shared libraries in DIR [LIBDIR]], slibdir="$with_slibdir", -if test "${version_specific_libs}" = yes; then +[if test "${version_specific_libs}" = yes; then slibdir='$(libsubdir)' elif test -n "$with_cross_host" && test x"$with_cross_host" != x"no"; then - slibdir='$(exec_prefix)/$(host_noncanonical)/lib' + case ${with_toolexeclibdir} in + no) + slibdir='$(exec_prefix)/$(host_noncanonical)/lib' + ;; + *) + slibdir=${with_toolexeclibdir} + ;; + esac else slibdir='$(libdir)' -fi) +fi]) AC_SUBST(slibdir) # Command-line options. @@ -168,7 +178,14 @@ case ${version_specific_libs} in test x"$with_cross_host" != x"no"; then # Install a library built with a cross compiler in tooldir, not libdir. toolexecdir='$(exec_prefix)/$(target_noncanonical)' - toolexeclibdir='$(toolexecdir)/lib' + case ${with_toolexeclibdir} in + no) + toolexeclibdir='$(toolexecdir)/lib' + ;; + *) + toolexeclibdir=${with_toolexeclibdir} + ;; + esac else toolexecdir='$(libdir)/gcc-lib/$(target_noncanonical)' toolexeclibdir='$(libdir)' @@ -498,14 +515,12 @@ AC_SUBST(solaris_ld_v2_maps) # This is after config.host so we can augment tmake_file. case ${host} in xtensa*-*) - cat > conftest.c <<EOF - #ifdef __XTENSA_CALL0_ABI__ - #error - #endif -EOF - if AC_TRY_COMMAND(${CC-cc} -E -o conftest.i conftest.c 1>&AS_MESSAGE_LOG_FD); then - tmake_file="${tmake_file} xtensa/t-windowed" - fi + AC_COMPILE_IFELSE([AC_LANG_SOURCE( + [#ifdef __XTENSA_CALL0_ABI__ + #error + #endif + ])], + [tmake_file="${tmake_file} xtensa/t-windowed"]) ;; esac @@ -582,6 +597,25 @@ i[[34567]]86-*-* | x86_64-*-*) esac]) LIBGCC_CHECK_AS_AVX +dnl Check if as supports LSE instructions. +AC_DEFUN([LIBGCC_CHECK_AS_LSE], [ +case "${target}" in +aarch64*-*-*) + AC_CACHE_CHECK([if the assembler supports LSE], libgcc_cv_as_lse, [ + AC_TRY_COMPILE([], +changequote(,)dnl + asm(".arch armv8-a+lse\n\tcas w0, w1, [x2]"); +changequote([,])dnl + , + [libgcc_cv_as_lse=yes], [libgcc_cv_as_lse=no]) + ]) + if test x$libgcc_cv_as_lse = xyes; then + AC_DEFINE(HAVE_AS_LSE, 1, [Define to 1 if the assembler supports LSE.]) + fi + ;; +esac]) +LIBGCC_CHECK_AS_LSE + dnl Check if as supports RTM instructions. AC_CACHE_CHECK(for init priority support, libgcc_cv_init_priority, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM(, diff --git a/libgcc/crtstuff.c b/libgcc/crtstuff.c index 956b843..3f769a1 100644 --- a/libgcc/crtstuff.c +++ b/libgcc/crtstuff.c @@ -382,10 +382,12 @@ __do_global_dtors_aux (void) if (__builtin_expect (completed, 0)) return; +#if DEFAULT_USE_CXA_ATEXIT #ifdef CRTSTUFFS_O if (__cxa_finalize) __cxa_finalize (__dso_handle); #endif +#endif #ifdef FINI_ARRAY_SECTION_ASM_OP /* If we are using .fini_array then destructors will be run via that diff --git a/libgcc/gcov.h b/libgcc/gcov.h index f158191..0e3eed3 100644 --- a/libgcc/gcov.h +++ b/libgcc/gcov.h @@ -33,9 +33,4 @@ extern void __gcov_reset (void); extern void __gcov_dump (void); -/* Write profile information to a file and reset counters to zero. - The function does operations under a mutex. */ - -extern void __gcov_flush (void); - #endif /* GCC_GCOV_H */ diff --git a/libgcc/generic-morestack.c b/libgcc/generic-morestack.c index c26dba1..35764a8 100644 --- a/libgcc/generic-morestack.c +++ b/libgcc/generic-morestack.c @@ -53,6 +53,62 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #include "generic-morestack.h" +/* Some systems use LD_PRELOAD or similar tricks to add hooks to + mmap/munmap. That breaks this code, because when we call mmap + there is enough stack space for the system call but there is not, + in general, enough stack space to run a hook. Try to avoid the + problem by calling syscall directly. We only do this on GNU/Linux + for now, but it should be easy to add support for more systems with + testing. */ + +#if defined(__gnu_linux__) + +#include <sys/syscall.h> + +#if defined(SYS_mmap) || defined(SYS_mmap2) + +#ifdef SYS_mmap2 +#define MORESTACK_MMAP SYS_mmap2 +#define MORESTACK_ADJUST_OFFSET(x) ((x) / 4096ULL) +#else +#define MORESTACK_MMAP SYS_mmap +#define MORESTACK_ADJUST_OFFSET(x) (x) +#endif + +static void * +morestack_mmap (void *addr, size_t length, int prot, int flags, int fd, + off_t offset) +{ + offset = MORESTACK_ADJUST_OFFSET (offset); + +#ifdef __s390__ + long args[6] = { (long) addr, (long) length, (long) prot, (long) flags, + (long) fd, (long) offset }; + return (void *) syscall (MORESTACK_MMAP, args); +#else + return (void *) syscall (MORESTACK_MMAP, addr, length, prot, flags, fd, + offset); +#endif +} + +#define mmap morestack_mmap + +#endif /* defined(SYS_MMAP) || defined(SYS_mmap2) */ + +#if defined(SYS_munmap) + +static int +morestack_munmap (void * addr, size_t length) +{ + return (int) syscall (SYS_munmap, addr, length); +} + +#define munmap morestack_munmap + +#endif /* defined(SYS_munmap) */ + +#endif /* defined(__gnu_linux__) */ + typedef unsigned uintptr_type __attribute__ ((mode (pointer))); /* This file contains subroutines that are used by code compiled with diff --git a/libgcc/libgcov-driver.c b/libgcc/libgcov-driver.c index 1c07761..cbfcae9 100644 --- a/libgcc/libgcov-driver.c +++ b/libgcc/libgcov-driver.c @@ -301,16 +301,18 @@ merge_one_data (const char *filename, if (!merge) continue; - tag = gcov_read_unsigned (); - length = gcov_read_unsigned (); - if (tag != GCOV_TAG_FOR_COUNTER (t_ix) - || length != GCOV_TAG_COUNTER_LENGTH (ci_ptr->num)) - goto read_mismatch; - (*merge) (ci_ptr->values, ci_ptr->num); - ci_ptr++; - } + tag = gcov_read_unsigned (); + length = gcov_read_unsigned (); + if (tag != GCOV_TAG_FOR_COUNTER (t_ix) + || (length != GCOV_TAG_COUNTER_LENGTH (ci_ptr->num) + && t_ix != GCOV_COUNTER_V_TOPN + && t_ix != GCOV_COUNTER_V_INDIR)) + goto read_mismatch; + (*merge) (ci_ptr->values, ci_ptr->num); + ci_ptr++; + } if ((error = gcov_is_error ())) - goto read_error; + goto read_error; } if (tag) @@ -329,6 +331,37 @@ read_error: return -1; } +/* Store all TOP N counters where each has a dynamic length. */ + +static void +write_top_counters (const struct gcov_ctr_info *ci_ptr, + unsigned t_ix, + gcov_unsigned_t n_counts) +{ + unsigned counters = n_counts / GCOV_TOPN_MEM_COUNTERS; + gcc_assert (n_counts % GCOV_TOPN_MEM_COUNTERS == 0); + unsigned pair_total = 0; + for (unsigned i = 0; i < counters; i++) + pair_total += ci_ptr->values[GCOV_TOPN_MEM_COUNTERS * i + 1]; + unsigned disk_size = GCOV_TOPN_DISK_COUNTERS * counters + 2 * pair_total; + gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix), + GCOV_TAG_COUNTER_LENGTH (disk_size)); + + for (unsigned i = 0; i < counters; i++) + { + gcov_type pair_count = ci_ptr->values[GCOV_TOPN_MEM_COUNTERS * i + 1]; + gcov_write_counter (ci_ptr->values[GCOV_TOPN_MEM_COUNTERS * i]); + gcov_write_counter (pair_count); + gcov_type start = ci_ptr->values[GCOV_TOPN_MEM_COUNTERS * i + 2]; + for (struct gcov_kvp *node = (struct gcov_kvp *)(intptr_t)start; + node != NULL; node = node->next) + { + gcov_write_counter (node->value); + gcov_write_counter (node->count); + } + } +} + /* Write counters in GI_PTR and the summary in PRG to a gcda file. In the case of appending to an existing file, SUMMARY_POS will be non-zero. We will write the file starting from SUMMAY_POS. */ @@ -388,11 +421,18 @@ write_one_data (const struct gcov_info *gi_ptr, continue; n_counts = ci_ptr->num; - gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix), - GCOV_TAG_COUNTER_LENGTH (n_counts)); - c_ptr = ci_ptr->values; - while (n_counts--) - gcov_write_counter (*c_ptr++); + + if (gi_ptr->merge[t_ix] == __gcov_merge_topn) + write_top_counters (ci_ptr, t_ix, n_counts); + else + { + gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix), + GCOV_TAG_COUNTER_LENGTH (n_counts)); + c_ptr = ci_ptr->values; + while (n_counts--) + gcov_write_counter (*c_ptr++); + } + ci_ptr++; } if (buffered) @@ -429,7 +469,6 @@ dump_one_gcov (struct gcov_info *gi_ptr, struct gcov_filename *gf, struct gcov_summary summary = {}; int error; gcov_unsigned_t tag; - fn_buffer = 0; error = gcov_exit_open_gcda_file (gi_ptr, gf); diff --git a/libgcc/libgcov-interface.c b/libgcc/libgcov-interface.c index 49b44d5..3a8a5bf 100644 --- a/libgcc/libgcov-interface.c +++ b/libgcc/libgcov-interface.c @@ -28,10 +28,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if defined(inhibit_libc) -#ifdef L_gcov_flush -void __gcov_flush (void) {} -#endif - #ifdef L_gcov_reset void __gcov_reset (void) {} #endif @@ -42,29 +38,19 @@ void __gcov_dump (void) {} #else -/* Some functions we want to bind in this dynamic object, but have an - overridable global alias. Unfortunately not all targets support - aliases, so we just have a forwarding function. That'll be tail - called, so the cost is a single jump instruction.*/ - -#define ALIAS_void_fn(src,dst) \ - void dst (void) \ - { src (); } - -extern __gthread_mutex_t __gcov_flush_mx ATTRIBUTE_HIDDEN; -extern __gthread_mutex_t __gcov_flush_mx ATTRIBUTE_HIDDEN; +extern __gthread_mutex_t __gcov_mx ATTRIBUTE_HIDDEN; -#ifdef L_gcov_flush +#ifdef L_gcov_lock_unlock #ifdef __GTHREAD_MUTEX_INIT -__gthread_mutex_t __gcov_flush_mx = __GTHREAD_MUTEX_INIT; +__gthread_mutex_t __gcov_mx = __GTHREAD_MUTEX_INIT; #define init_mx_once() #else -__gthread_mutex_t __gcov_flush_mx; +__gthread_mutex_t __gcov_mx; static void init_mx (void) { - __GTHREAD_MUTEX_INIT_FUNCTION (&__gcov_flush_mx); + __GTHREAD_MUTEX_INIT_FUNCTION (&__gcov_mx); } static void @@ -75,23 +61,23 @@ init_mx_once (void) } #endif -/* Called before fork or exec - write out profile information gathered so - far and reset it to zero. This avoids duplication or loss of the - profile information gathered so far. */ +/* Lock critical section for __gcov_dump and __gcov_reset functions. */ void -__gcov_flush (void) +__gcov_lock (void) { init_mx_once (); - __gthread_mutex_lock (&__gcov_flush_mx); + __gthread_mutex_lock (&__gcov_mx); +} - __gcov_dump_int (); - __gcov_reset_int (); +/* Unlock critical section for __gcov_dump and __gcov_reset functions. */ - __gthread_mutex_unlock (&__gcov_flush_mx); +void +__gcov_unlock (void) +{ + __gthread_mutex_unlock (&__gcov_mx); } - -#endif /* L_gcov_flush */ +#endif #ifdef L_gcov_reset @@ -144,7 +130,17 @@ __gcov_reset_int (void) } } -ALIAS_void_fn (__gcov_reset_int, __gcov_reset); +/* Exported function __gcov_reset. */ + +void +__gcov_reset (void) +{ + __gcov_lock (); + + __gcov_reset_int (); + + __gcov_unlock (); +} #endif /* L_gcov_reset */ @@ -164,22 +160,35 @@ __gcov_dump_int (void) __gcov_dump_one (root); } -ALIAS_void_fn (__gcov_dump_int, __gcov_dump); +/* Exported function __gcov_dump. */ + +void +__gcov_dump (void) +{ + __gcov_lock (); + + __gcov_dump_int (); + + __gcov_unlock (); +} #endif /* L_gcov_dump */ #ifdef L_gcov_fork -/* A wrapper for the fork function. Flushes the accumulated profiling data, so - that they are not counted twice. */ +/* A wrapper for the fork function. We reset counters in the child + so that they are not counted twice. */ pid_t __gcov_fork (void) { pid_t pid; - __gcov_flush (); pid = fork (); if (pid == 0) - __GTHREAD_MUTEX_INIT_FUNCTION (&__gcov_flush_mx); + { + __GTHREAD_MUTEX_INIT_FUNCTION (&__gcov_mx); + /* We do not need locking as we are the only thread in the child. */ + __gcov_reset_int (); + } return pid; } #endif @@ -195,7 +204,8 @@ __gcov_execl (const char *path, char *arg, ...) unsigned i, length; char **args; - __gcov_flush (); + /* Dump counters only, they will be lost after exec. */ + __gcov_dump (); va_start (ap, arg); va_copy (aq, ap); @@ -211,7 +221,10 @@ __gcov_execl (const char *path, char *arg, ...) args[i] = va_arg (aq, char *); va_end (aq); - return execv (path, args); + int ret = execv (path, args); + /* We reach this code only when execv fails, reset counter then here. */ + __gcov_reset (); + return ret; } #endif @@ -226,7 +239,8 @@ __gcov_execlp (const char *path, char *arg, ...) unsigned i, length; char **args; - __gcov_flush (); + /* Dump counters only, they will be lost after exec. */ + __gcov_dump (); va_start (ap, arg); va_copy (aq, ap); @@ -242,7 +256,10 @@ __gcov_execlp (const char *path, char *arg, ...) args[i] = va_arg (aq, char *); va_end (aq); - return execvp (path, args); + int ret = execvp (path, args); + /* We reach this code only when execv fails, reset counter then here. */ + __gcov_reset (); + return ret; } #endif @@ -258,7 +275,8 @@ __gcov_execle (const char *path, char *arg, ...) char **args; char **envp; - __gcov_flush (); + /* Dump counters only, they will be lost after exec. */ + __gcov_dump (); va_start (ap, arg); va_copy (aq, ap); @@ -275,7 +293,10 @@ __gcov_execle (const char *path, char *arg, ...) envp = va_arg (aq, char **); va_end (aq); - return execve (path, args, envp); + int ret = execve (path, args, envp); + /* We reach this code only when execv fails, reset counter then here. */ + __gcov_reset (); + return ret; } #endif @@ -286,8 +307,12 @@ __gcov_execle (const char *path, char *arg, ...) int __gcov_execv (const char *path, char *const argv[]) { - __gcov_flush (); - return execv (path, argv); + /* Dump counters only, they will be lost after exec. */ + __gcov_dump (); + int ret = execv (path, argv); + /* We reach this code only when execv fails, reset counter then here. */ + __gcov_reset (); + return ret; } #endif @@ -298,8 +323,12 @@ __gcov_execv (const char *path, char *const argv[]) int __gcov_execvp (const char *path, char *const argv[]) { - __gcov_flush (); - return execvp (path, argv); + /* Dump counters only, they will be lost after exec. */ + __gcov_dump (); + int ret = execvp (path, argv); + /* We reach this code only when execv fails, reset counter then here. */ + __gcov_reset (); + return ret; } #endif @@ -310,8 +339,12 @@ __gcov_execvp (const char *path, char *const argv[]) int __gcov_execve (const char *path, char *const argv[], char *const envp[]) { - __gcov_flush (); - return execve (path, argv, envp); + /* Dump counters only, they will be lost after exec. */ + __gcov_dump (); + int ret = execve (path, argv, envp); + /* We reach this code only when execv fails, reset counter then here. */ + __gcov_reset (); + return ret; } #endif #endif /* inhibit_libc */ diff --git a/libgcc/libgcov-merge.c b/libgcc/libgcov-merge.c index b658aec..1acdaa0 100644 --- a/libgcc/libgcov-merge.c +++ b/libgcc/libgcov-merge.c @@ -86,59 +86,6 @@ __gcov_merge_time_profile (gcov_type *counters, unsigned n_counters) #ifdef L_gcov_merge_topn -static void -merge_topn_values_set (gcov_type *counters) -{ - /* First value is number of total executions of the profiler. */ - gcov_type all = gcov_get_counter_ignore_scaling (-1); - counters[0] += all; - ++counters; - - /* Read all part values. */ - gcov_type read_counters[2 * GCOV_TOPN_VALUES]; - - for (unsigned i = 0; i < GCOV_TOPN_VALUES; i++) - { - read_counters[2 * i] = gcov_get_counter_target (); - read_counters[2 * i + 1] = gcov_get_counter_ignore_scaling (-1); - } - - if (read_counters[1] == -1) - { - counters[1] = -1; - return; - } - - for (unsigned i = 0; i < GCOV_TOPN_VALUES; i++) - { - if (read_counters[2 * i + 1] == 0) - return; - - unsigned j; - for (j = 0; j < GCOV_TOPN_VALUES; j++) - { - if (counters[2 * j] == read_counters[2 * i]) - { - counters[2 * j + 1] += read_counters[2 * i + 1]; - break; - } - else if (counters[2 * j + 1] == 0) - { - counters[2 * j] += read_counters[2 * i]; - counters[2 * j + 1] += read_counters[2 * i + 1]; - break; - } - } - - /* We haven't found a slot, bail out. */ - if (j == GCOV_TOPN_VALUES) - { - counters[1] = -1; - return; - } - } -} - /* The profile merging function for choosing the most common value. It is given an array COUNTERS of N_COUNTERS old counters and it reads the same number of counters from the gcov file. The counters @@ -148,13 +95,30 @@ merge_topn_values_set (gcov_type *counters) -- the stored candidate on the most common value of the measured entity -- counter */ + void __gcov_merge_topn (gcov_type *counters, unsigned n_counters) { - gcc_assert (!(n_counters % GCOV_TOPN_VALUES_COUNTERS)); + gcc_assert (!(n_counters % GCOV_TOPN_MEM_COUNTERS)); - for (unsigned i = 0; i < (n_counters / GCOV_TOPN_VALUES_COUNTERS); i++) - merge_topn_values_set (counters + (i * GCOV_TOPN_VALUES_COUNTERS)); + for (unsigned i = 0; i < (n_counters / GCOV_TOPN_MEM_COUNTERS); i++) + { + /* First value is number of total executions of the profiler. */ + gcov_type all = gcov_get_counter_ignore_scaling (-1); + gcov_type n = gcov_get_counter_ignore_scaling (-1); + + counters[GCOV_TOPN_MEM_COUNTERS * i] += all; + + for (unsigned j = 0; j < n; j++) + { + gcov_type value = gcov_get_counter_target (); + gcov_type count = gcov_get_counter_ignore_scaling (-1); + + // TODO: we should use atomic here + gcov_topn_add_value (counters + GCOV_TOPN_MEM_COUNTERS * i, value, + count, 0, 0); + } + } } #endif /* L_gcov_merge_topn */ diff --git a/libgcc/libgcov-profiler.c b/libgcc/libgcov-profiler.c index 9417904..45ab93c 100644 --- a/libgcc/libgcov-profiler.c +++ b/libgcc/libgcov-profiler.c @@ -26,17 +26,6 @@ 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 @@ -105,51 +94,13 @@ __gcov_pow2_profiler_atomic (gcov_type *counters, gcov_type value) } #endif - /* Tries to determine N most commons value among its inputs. */ static inline void __gcov_topn_values_profiler_body (gcov_type *counters, gcov_type value, int use_atomic) { - if (use_atomic) - __atomic_fetch_add (&counters[0], 1, __ATOMIC_RELAXED); - else - counters[0]++; - - ++counters; - - /* We have GCOV_TOPN_VALUES as we can keep multiple values - next to each other. */ - unsigned sindex = 0; - - for (unsigned i = 0; i < GCOV_TOPN_VALUES; i++) - { - if (value == counters[2 * i]) - { - if (use_atomic) - __atomic_fetch_add (&counters[2 * i + 1], 1, __ATOMIC_RELAXED); - else - counters[2 * i + 1]++; - return; - } - else if (counters[2 * i + 1] == 0) - { - /* We found an empty slot. */ - counters[2 * i] = value; - counters[2 * i + 1] = 1; - return; - } - - if (counters[2 * i + 1] < counters[2 * sindex + 1]) - sindex = i; - } - - /* We haven't found an empty slot, then decrement the smallest. */ - if (use_atomic) - __atomic_fetch_sub (&counters[2 * sindex + 1], 1, __ATOMIC_RELAXED); - else - counters[2 * sindex + 1]--; + gcov_topn_add_value (counters, value, 1, use_atomic, 1); } #ifdef L_gcov_topn_values_profiler @@ -199,8 +150,9 @@ struct indirect_call_tuple __gcov_indirect_call; as a pointer to a function. */ /* Tries to determine the most common value among its inputs. */ -void -__gcov_indirect_call_profiler_v4 (gcov_type value, void* cur_func) +static inline void +__gcov_indirect_call_profiler_body (gcov_type value, void *cur_func, + int use_atomic) { /* If the C++ virtual tables contain function descriptors then one function may have multiple descriptors and we need to dereference @@ -208,10 +160,26 @@ __gcov_indirect_call_profiler_v4 (gcov_type value, void* cur_func) if (cur_func == __gcov_indirect_call.callee || (__LIBGCC_VTABLE_USES_DESCRIPTORS__ && *(void **) cur_func == *(void **) __gcov_indirect_call.callee)) - __gcov_topn_values_profiler_body (__gcov_indirect_call.counters, value, 0); + __gcov_topn_values_profiler_body (__gcov_indirect_call.counters, value, + use_atomic); __gcov_indirect_call.callee = NULL; } + +void +__gcov_indirect_call_profiler_v4 (gcov_type value, void *cur_func) +{ + __gcov_indirect_call_profiler_body (value, cur_func, 0); +} + +#if GCOV_SUPPORTS_ATOMIC +void +__gcov_indirect_call_profiler_v4_atomic (gcov_type value, void *cur_func) +{ + __gcov_indirect_call_profiler_body (value, cur_func, 1); +} +#endif + #endif #ifdef L_gcov_time_profiler diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c index 449638b..fff54c6 100644 --- a/libgcc/libgcov-util.c +++ b/libgcc/libgcov-util.c @@ -261,7 +261,7 @@ read_gcda_file (const char *filename) { unsigned tags[4]; unsigned depth = 0; - unsigned magic, version; + unsigned version; struct gcov_info *obj_info; int i; @@ -276,8 +276,7 @@ read_gcda_file (const char *filename) } /* Read magic. */ - magic = gcov_read_unsigned (); - if (magic != GCOV_DATA_MAGIC) + if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC)) { fnotice (stderr, "%s:not a gcov data file\n", filename); gcov_close (); diff --git a/libgcc/libgcov.h b/libgcc/libgcov.h index bc7e308..5d237a4 100644 --- a/libgcc/libgcov.h +++ b/libgcc/libgcov.h @@ -85,6 +85,19 @@ typedef unsigned gcov_type_unsigned __attribute__ ((mode (QI))); #define GCOV_LOCKED 0 #endif +#ifndef GCOV_SUPPORTS_ATOMIC +/* 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 +#endif + /* In libgcov we need these functions to be extern, so prefix them with __gcov. In libgcov they must also be hidden so that the instance in the executable is not also used in a DSO. */ @@ -147,7 +160,7 @@ extern struct gcov_info *gcov_list; /* Poison these, so they don't accidentally slip in. */ #pragma GCC poison gcov_write_string gcov_write_tag gcov_write_length -#pragma GCC poison gcov_time gcov_magic +#pragma GCC poison gcov_time #ifdef HAVE_GAS_HIDDEN #define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden"))) @@ -253,6 +266,12 @@ extern void __gcov_reset_int (void) ATTRIBUTE_HIDDEN; /* User function to enable early write of profile information so far. */ extern void __gcov_dump_int (void) ATTRIBUTE_HIDDEN; +/* Lock critical section for __gcov_dump and __gcov_reset functions. */ +extern void __gcov_lock (void) ATTRIBUTE_HIDDEN; + +/* Unlock critical section for __gcov_dump and __gcov_reset functions. */ +extern void __gcov_unlock (void) ATTRIBUTE_HIDDEN; + /* The merge function that just sums the counters. */ extern void __gcov_merge_add (gcov_type *, unsigned) ATTRIBUTE_HIDDEN; @@ -274,6 +293,7 @@ extern void __gcov_pow2_profiler_atomic (gcov_type *, gcov_type); extern void __gcov_topn_values_profiler (gcov_type *, gcov_type); extern void __gcov_topn_values_profiler_atomic (gcov_type *, gcov_type); extern void __gcov_indirect_call_profiler_v4 (gcov_type, void *); +extern void __gcov_indirect_call_profiler_v4_atomic (gcov_type, void *); extern void __gcov_time_profiler (gcov_type *); extern void __gcov_time_profiler_atomic (gcov_type *); extern void __gcov_average_profiler (gcov_type *, gcov_type); @@ -366,6 +386,103 @@ gcov_get_counter_target (void) #endif } +/* Add VALUE to *COUNTER and make it with atomic operation + if USE_ATOMIC is true. */ + +static inline void +gcov_counter_add (gcov_type *counter, gcov_type value, + int use_atomic ATTRIBUTE_UNUSED) +{ +#if GCOV_SUPPORTS_ATOMIC + if (use_atomic) + __atomic_fetch_add (counter, value, __ATOMIC_RELAXED); + else +#endif + *counter += value; +} + +/* Add key value pair VALUE:COUNT to a top N COUNTERS. When INCREMENT_TOTAL + is true, add COUNT to total of the TOP counter. If USE_ATOMIC is true, + do it in atomic way. */ + +static inline void +gcov_topn_add_value (gcov_type *counters, gcov_type value, gcov_type count, + int use_atomic, int increment_total) +{ + if (increment_total) + gcov_counter_add (&counters[0], 1, use_atomic); + + struct gcov_kvp *prev_node = NULL; + struct gcov_kvp *minimal_node = NULL; + struct gcov_kvp *current_node = (struct gcov_kvp *)(intptr_t)counters[2]; + + while (current_node) + { + if (current_node->value == value) + { + gcov_counter_add (¤t_node->count, count, use_atomic); + return; + } + + if (minimal_node == NULL + || current_node->count < minimal_node->count) + minimal_node = current_node; + + prev_node = current_node; + current_node = current_node->next; + } + + if (counters[1] == GCOV_TOPN_MAXIMUM_TRACKED_VALUES) + { + if (--minimal_node->count < count) + { + minimal_node->value = value; + minimal_node->count = count; + } + } + else + { + struct gcov_kvp *new_node + = (struct gcov_kvp *)xcalloc (1, sizeof (struct gcov_kvp)); + new_node->value = value; + new_node->count = count; + + int success = 0; + if (!counters[2]) + { +#if GCOV_SUPPORTS_ATOMIC + if (use_atomic) + { + struct gcov_kvp **ptr = (struct gcov_kvp **)(intptr_t)&counters[2]; + success = !__sync_val_compare_and_swap (ptr, 0, new_node); + } + else +#endif + { + counters[2] = (intptr_t)new_node; + success = 1; + } + } + else if (prev_node && !prev_node->next) + { +#if GCOV_SUPPORTS_ATOMIC + if (use_atomic) + success = !__sync_val_compare_and_swap (&prev_node->next, 0, + new_node); + else +#endif + { + prev_node->next = new_node; + success = 1; + } + } + + /* Increment number of nodes. */ + if (success) + gcov_counter_add (&counters[1], 1, use_atomic); + } +} + #endif /* !inhibit_libc */ #endif /* GCC_LIBGCOV_H */ diff --git a/libgcc/unwind-arm-common.inc b/libgcc/unwind-arm-common.inc index 3c774b8..31a072b 100644 --- a/libgcc/unwind-arm-common.inc +++ b/libgcc/unwind-arm-common.inc @@ -419,7 +419,7 @@ get_eit_entry (_Unwind_Control_Block *ucbp, _uw return_address) UCB_PR_ADDR (ucbp) = selfrel_offset31 (ucbp->pr_cache.ehtp); #if __FDPIC__ UCB_PR_GOT (ucbp) - = (unsigned int) gnu_Unwind_Find_got ((_Unwind_Ptr) UCB_PR_ADDR (ucbp)); + = (unsigned int) _Unwind_gnu_Find_got ((_Unwind_Ptr) UCB_PR_ADDR (ucbp)); #endif } return _URC_OK; @@ -462,7 +462,7 @@ unwind_phase2 (_Unwind_Control_Block * ucbp, phase2_vrs * vrs) #if __FDPIC__ /* r9 could have been lost due to PLT jump. Restore correct value. */ - vrs->core.r[FDPIC_REGNUM] = gnu_Unwind_Find_got (VRS_PC (vrs)); + vrs->core.r[FDPIC_REGNUM] = _Unwind_gnu_Find_got (VRS_PC (vrs)); #endif uw_restore_core_regs (vrs, &vrs->core); @@ -562,7 +562,7 @@ unwind_phase2_forced (_Unwind_Control_Block *ucbp, phase2_vrs *entry_vrs, #if __FDPIC__ /* r9 could have been lost due to PLT jump. Restore correct value. */ - saved_vrs.core.r[FDPIC_REGNUM] = gnu_Unwind_Find_got (VRS_PC (&saved_vrs)); + saved_vrs.core.r[FDPIC_REGNUM] = _Unwind_gnu_Find_got (VRS_PC (&saved_vrs)); #endif uw_restore_core_regs (&saved_vrs, &saved_vrs.core); @@ -698,7 +698,7 @@ __gnu_Unwind_Resume (_Unwind_Control_Block * ucbp, phase2_vrs * entry_vrs) /* Upload the registers to enter the landing pad. */ #if __FDPIC__ /* r9 could have been lost due to PLT jump. Restore correct value. */ - entry_vrs->core.r[FDPIC_REGNUM] = gnu_Unwind_Find_got (VRS_PC (entry_vrs)); + entry_vrs->core.r[FDPIC_REGNUM] = _Unwind_gnu_Find_got (VRS_PC (entry_vrs)); #endif uw_restore_core_regs (entry_vrs, &entry_vrs->core); diff --git a/libgcc/unwind-dw2-fde-dip.c b/libgcc/unwind-dw2-fde-dip.c index d3a09ce..6e50405 100644 --- a/libgcc/unwind-dw2-fde-dip.c +++ b/libgcc/unwind-dw2-fde-dip.c @@ -329,7 +329,7 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr) return 1; #ifdef CRT_GET_RFIB_DATA -# ifdef __i386__ +# if defined __i386__ || defined __nios2__ data->dbase = NULL; if (p_dynamic) { diff --git a/libgcc/unwind-pe.h b/libgcc/unwind-pe.h index a336127..a6b4bff 100644 --- a/libgcc/unwind-pe.h +++ b/libgcc/unwind-pe.h @@ -267,7 +267,7 @@ read_encoded_value_with_base (unsigned char encoding, _Unwind_Ptr base, into account. */ if ((encoding & DW_EH_PE_pcrel) && (encoding & DW_EH_PE_indirect)) { - result += gnu_Unwind_Find_got ((_Unwind_Ptr) u); + result += _Unwind_gnu_Find_got ((_Unwind_Ptr) u); result = *(_Unwind_Internal_Ptr *) result; } else |