From 3308c88632ebf7d2425e30951e9381c8e5b0b53a Mon Sep 17 00:00:00 2001 From: zyppe <210hcl@gmail.com> Date: Thu, 29 Feb 2024 15:49:09 +0800 Subject: [PATCH] Initialize for gcc --- .gcc.metadata | 2 + .gitignore | 2 + README.First-for.SuSE.packagers | 31 + change_spec | 134 + cpp | 3 + gcc-add-defaultsspec.diff | 51 + gcc.changes | 170 + gcc.spec | 604 +++ gcc10-amdgcn-llvm-as.patch | 31 + ...amdgcn-disable-hot-cold-partitioning.patch | 22 + gcc11-gdwarf-4-default.patch | 29 + gcc12-aarch64-bsc1214052.patch | 3072 +++++++++++++ gcc12-riscv-inline-atomics.patch | 2075 +++++++++ gcc12-riscv-pthread.patch | 21 + gcc12-rpmlintrc | 19 + gcc12-testresults-rpmlintrc | 10 + gcc12-testsuite-fixes.patch | 187 + gcc12.spec | 3817 +++++++++++++++++ gcc41-ppc32-retaddr.patch | 91 + gcc43-no-unwind-tables.diff | 13 + gcc44-rename-info-files.patch | 708 +++ gcc44-textdomain.patch | 115 + gcc48-libstdc++-api-reference.patch | 14 + gcc7-avoid-fixinc-error.diff | 18 + ...ve-Wexpansion-to-defined-from-Wextra.patch | 13 + ...oducible-builds-buildid-for-checksum.patch | 116 + gcc9-reproducible-builds.patch | 15 + tls-no-direct.diff | 20 + 28 files changed, 11403 insertions(+) create mode 100644 .gcc.metadata create mode 100644 .gitignore create mode 100644 README.First-for.SuSE.packagers create mode 100644 change_spec create mode 100644 cpp create mode 100644 gcc-add-defaultsspec.diff create mode 100644 gcc.changes create mode 100644 gcc.spec create mode 100644 gcc10-amdgcn-llvm-as.patch create mode 100644 gcc11-amdgcn-disable-hot-cold-partitioning.patch create mode 100644 gcc11-gdwarf-4-default.patch create mode 100644 gcc12-aarch64-bsc1214052.patch create mode 100644 gcc12-riscv-inline-atomics.patch create mode 100644 gcc12-riscv-pthread.patch create mode 100644 gcc12-rpmlintrc create mode 100644 gcc12-testresults-rpmlintrc create mode 100644 gcc12-testsuite-fixes.patch create mode 100644 gcc12.spec create mode 100644 gcc41-ppc32-retaddr.patch create mode 100644 gcc43-no-unwind-tables.diff create mode 100644 gcc44-rename-info-files.patch create mode 100644 gcc44-textdomain.patch create mode 100644 gcc48-libstdc++-api-reference.patch create mode 100644 gcc7-avoid-fixinc-error.diff create mode 100644 gcc7-remove-Wexpansion-to-defined-from-Wextra.patch create mode 100644 gcc9-reproducible-builds-buildid-for-checksum.patch create mode 100644 gcc9-reproducible-builds.patch create mode 100644 tls-no-direct.diff diff --git a/.gcc.metadata b/.gcc.metadata new file mode 100644 index 0000000..f9bbc72 --- /dev/null +++ b/.gcc.metadata @@ -0,0 +1,2 @@ +1301ded114b9c98541722d27c2daed8870b90bbccfd63582538fedaf1559fa16 gcc-12.3.0+git1204.tar.xz +f5b3ba38c506af026b933c79aaf54500055c506d677e06e009e04c06e03768d2 newlib-4.2.0.20211231.tar.xz diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c165fd3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +gcc-12.3.0+git1204.tar.xz +newlib-4.2.0.20211231.tar.xz diff --git a/README.First-for.SuSE.packagers b/README.First-for.SuSE.packagers new file mode 100644 index 0000000..c1b77f9 --- /dev/null +++ b/README.First-for.SuSE.packagers @@ -0,0 +1,31 @@ +IMPORTANT: Please change gcc.spec.in and then run ./pre_checkin.sh! +Do not change gcc.spec directly! + +Since GCC comes with a testsuite that runs for quite a long time and +that test suite also contains some known failures, we should run the +testsuite of GCC whenever the compiler is changed to ensure a high +quality compiler. + +The package is now split into multiple parts, gcc$VER, +gcc$VER-testresults and libffi$VER (plus various spec files for +cross and icecream cross compilers). The testsuite is run from +gcc$VER-testresults, a dummy package with the testresults, gcc$VER-testresults, +is generated from it which contains testing logfiles and summary. + +Before checking in a new compiler, please do the following steps as QA +measure to check that the new compiler does not introduce any new +failures: + +- Run mbuild for all archs for at least the gcc$VER and the gcc$VER-testresults + subpackages + +- When mbuild is finished, call + /suse/rguenther/bin/compare-testresults.sh mbuild-directory + (for the gcc$VER-testresults build). + The output of that script should not show any failures. If it does, + please fix them or discuss this with the gcc package maintainers. + +- Do not remove this file. + +Thanks, +Your GCC packagers. diff --git a/change_spec b/change_spec new file mode 100644 index 0000000..fd3a57a --- /dev/null +++ b/change_spec @@ -0,0 +1,134 @@ +#!/bin/bash + +do_crosses=1 +do_optional_compiler_languages=0 +rm -f gcc*-testresults.spec gcc*-testresults.changes gcc*.spec cross*.spec cross*.changes + +# Default is to generate the normal gcc package +# unless a parameter is given. In case that it is '-*', +# that parameter will be used as suffix for the package name +# and as suffix for the install path (/opt/gccSUFFIX) +# In case that it is '[0-9]*', that parameter will be used +# as a suffix for a versioned package name. + +if [ $# -lt 1 ]; then + echo No package suffix given + outfile=gcc.spec +else + case $1 in + [0-9]*) + base_ver=$1 + outfile=gcc$1.spec + ;; + *) + echo Invalid package suffix + exit 1 + ;; + esac +fi + + : > $outfile + if test "$do_optional_compiler_languages" = "1"; then + echo '%define build_optional_compiler_languages 1' >> $outfile + fi + sed -e 's%@base_ver@%'$base_ver'%g' \ + gcc.spec.in \ + | sed -n -e '{ +/^# PACKAGE-BEGIN/h +/^# PACKAGE-BEGIN/,/^# PACKAGE-END/H +/^# PACKAGE-BEGIN/,/^# PACKAGE-END/!p +/^# PACKAGE-END/{g +s/@variant@//g +p +g +s/@variant@/-32bit/g +p +g +s/@variant@/-64bit/g +p +} +}' >> $outfile + + echo '%define building_testsuite 1' > gcc$base_ver-testresults.spec + echo '%define run_tests 1' >> gcc$base_ver-testresults.spec + sed -e '/^# GCC-TESTSUITE-DELETE-BEGIN/,/^# GCC-TESTSUITE-DELETE-END/d;s/-n gcc@base_ver@-testresults$//g;s/^Name:[[:space:]]*gcc@base_ver@/Name: gcc@base_ver@-testresults/g' \ + gcc.spec.in \ + | sed -e 's%@base_ver@%'$base_ver'%g' \ +>> gcc$base_ver-testresults.spec + +echo '' > _multibuild +echo ''gcc$base_ver-testresults'' >> _multibuild + +add_cross() { + local pkgname="$1"; shift + local rpmtarget="$1"; shift + local triplet="$1"; shift + + echo "%define pkgname $pkgname" > $pkgname.spec + echo "%define cross_arch $rpmtarget" >> $pkgname.spec + echo "%define gcc_target_arch $triplet" >> $pkgname.spec + echo "$@" >> $pkgname.spec + { sed -n -e '1,/SRC-COMMON-BEGIN/p' cross.spec.in + sed -n -e '/SRC-COMMON-BEGIN/,/SRC-COMMON-END/p' $outfile + sed -n -e '/SRC-COMMON-END/,/BUILD-COMMON-BEGIN/p' cross.spec.in + sed -n -e '/BUILD-COMMON-BEGIN/,/BUILD-COMMON-END/p' $outfile + sed -n -e '/BUILD-COMMON-END/,$p' cross.spec.in; } | + sed -e "s#@base_ver@#$base_ver#" \ + -e "s/^\(ExclusiveArch.*\) $rpmtarget[^ \r]*/\1 /" \ + >> $pkgname.spec + + echo ''$pkgname'' >> _multibuild +} + +add_newlib_cross() { + add_cross $1-bootstrap $2 $3 "%define gcc_target_newlib 1 +%define gcc_libc_bootstrap 1" + add_cross $1 $2 $3 "%define gcc_target_newlib 1" +} + +add_glibc_cross() { + add_cross $1-bootstrap $2 $3 "%define gcc_libc_bootstrap 1" + add_cross $1 $2 $3 "%define gcc_target_glibc 1" +} + +# We now support "proper" cross-compilers to suse targets via a +# cross-glibc package, enable that via for example +# +# add_cross cross-aarch64-gcc$base_ver aarch64 aarch64-suse-linux +# +# For now keep the old way of doing things +if test "$do_crosses" = 1 ; then +add_glibc_cross cross-aarch64-gcc$base_ver aarch64 aarch64-suse-linux +add_glibc_cross cross-riscv64-gcc$base_ver riscv64 riscv64-suse-linux +add_cross cross-arm-gcc$base_ver arm arm-suse-linux-gnueabi %define gcc_icecream 1 +add_cross cross-avr-gcc$base_ver-bootstrap avr avr "%define gcc_libc_bootstrap 1" +add_cross cross-avr-gcc$base_ver avr avr +add_newlib_cross cross-pru-gcc$base_ver pru pru +add_cross cross-x86_64-gcc$base_ver x86_64 x86_64-suse-linux %define gcc_icecream 1 +add_cross cross-s390x-gcc$base_ver s390x s390x-suse-linux %define gcc_icecream 1 +add_cross cross-sparc-gcc$base_ver sparcv9 sparc-suse-linux %define gcc_icecream 1 +add_cross cross-sparc64-gcc$base_ver sparc64 sparc64-suse-linux %define gcc_icecream 1 +add_cross cross-ppc64-gcc$base_ver ppc64 powerpc64-suse-linux %define gcc_icecream 1 +add_cross cross-ppc64le-gcc$base_ver ppc64le powerpc64le-suse-linux %define gcc_icecream 1 +add_cross cross-m68k-gcc$base_ver m68k m68k-suse-linux %define gcc_icecream 1 +add_cross cross-mips-gcc$base_ver mips mips-suse-linux %define gcc_icecream 1 +add_cross cross-hppa-gcc$base_ver-bootstrap hppa hppa-suse-linux %define gcc_libc_bootstrap 1 +add_cross cross-hppa-gcc$base_ver hppa hppa-suse-linux %define gcc_icecream 1 +add_newlib_cross cross-arm-none-gcc$base_ver arm-none arm-none-eabi +add_newlib_cross cross-epiphany-gcc$base_ver epiphany epiphany-elf +#add_newlib_cross cross-nds32le-gcc$base_ver nds32le nds32le-elf +add_newlib_cross cross-riscv64-elf-gcc$base_ver riscv64 riscv64-elf +#add_newlib_cross cross-rl78-gcc$base_ver rl78 rl78-elf +add_newlib_cross cross-rx-gcc$base_ver rx rx-elf +fi +# the nvptx and amdgcn crosses are used for offloading +add_cross cross-nvptx-gcc$base_ver nvptx nvptx-none %define gcc_accel 1 +add_cross cross-amdgcn-gcc$base_ver amdgcn amdgcn-amdhsa %define gcc_accel 1 + +for f in *.spec; do + sed -i -e '/^# .*-\(BEGIN\|END\)$/d' $f +done + +echo '' >> _multibuild + +osc service localrun format_spec_file diff --git a/cpp b/cpp new file mode 100644 index 0000000..83a3685 --- /dev/null +++ b/cpp @@ -0,0 +1,3 @@ +#!/bin/sh +# Traditionally, /lib/cpp only knew about C. +exec /usr/bin/cpp -xc "$@" diff --git a/gcc-add-defaultsspec.diff b/gcc-add-defaultsspec.diff new file mode 100644 index 0000000..08b0ad4 --- /dev/null +++ b/gcc-add-defaultsspec.diff @@ -0,0 +1,51 @@ +Index: gcc/gcc.cc +=================================================================== +--- gcc/gcc.cc.orig 2013-11-26 15:41:59.000000000 +0100 ++++ gcc/gcc.cc 2013-11-26 16:40:35.780548125 +0100 +@@ -258,6 +258,7 @@ static const char *replace_outfile_spec_ + static const char *remove_outfile_spec_function (int, const char **); + static const char *version_compare_spec_function (int, const char **); + static const char *include_spec_function (int, const char **); ++static const char *include_noerr_spec_function (int, const char **); + static const char *find_file_spec_function (int, const char **); + static const char *find_plugindir_spec_function (int, const char **); + static const char *print_asm_header_spec_function (int, const char **); +@@ -1357,6 +1358,7 @@ static const struct spec_function static + { "remove-outfile", remove_outfile_spec_function }, + { "version-compare", version_compare_spec_function }, + { "include", include_spec_function }, ++ { "include_noerr", include_noerr_spec_function }, + { "find-file", find_file_spec_function }, + { "find-plugindir", find_plugindir_spec_function }, + { "print-asm-header", print_asm_header_spec_function }, +@@ -6480,6 +6482,8 @@ main (int argc, char **argv) + if (access (specs_file, R_OK) == 0) + read_specs (specs_file, true, false); + ++ do_self_spec ("%:include_noerr(defaults.spec)%(default_spec)"); ++ + /* Process any configure-time defaults specified for the command line + options, via OPTION_DEFAULT_SPECS. */ + for (i = 0; i < ARRAY_SIZE (option_default_specs); i++) +@@ -8401,6 +8405,21 @@ get_random_number (void) + return ret ^ getpid (); + } + ++static const char * ++include_noerr_spec_function (int argc, const char **argv) ++{ ++ char *file; ++ ++ if (argc != 1) ++ abort (); ++ ++ file = find_a_file (&startfile_prefixes, argv[0], R_OK, 0); ++ if (file) ++ read_specs (file, FALSE, TRUE); ++ ++ return NULL; ++} ++ + /* %:compare-debug-dump-opt spec function. Save the last argument, + expected to be the last -fdump-final-insns option, or generate a + temporary. */ diff --git a/gcc.changes b/gcc.changes new file mode 100644 index 0000000..5dfc38a --- /dev/null +++ b/gcc.changes @@ -0,0 +1,170 @@ +* Fri Jul 9 2021 rguenther@suse.com +- With gcc-PIE add -pie even when -fPIC is specified but we are + not linking a shared library. [boo#1185348] +- Fix postun of gcc-go alternative. +* Wed Jun 13 2018 rguenther@suse.com +- Add gccgo symlink, add go and gofmt as alternatives to support + parallel install of golang. [bnc#1096677] +* Tue Jun 5 2018 rguenther@suse.com +- Fix gcc-PIE spec to properly honor -no-pie at link time. + [bnc#1096008] +* Fri Jun 9 2017 rguenther@suse.com +- Fix gcc-devel guard to use %%sle_version. [bnc#1043590] +* Wed Jun 7 2017 rguenther@suse.com +- Guard gcc-devel so it is only built on Tumbleweed. +- Remove bogus link to versioned g++.info file which doesn't exist. + Instead refer to gcc.info from the g++ info directory entry. + [bnc#922419] +* Tue Jun 6 2017 mliska@suse.cz +- Include gcov-tool and gcov-dump binaries. +* Thu Apr 13 2017 rguenther@suse.com +- Remove README in empty packages only required for SLE11 and older. +- Remove now empty %%build section. +* Tue Apr 4 2017 rguenther@suse.com +- Fix dependencies of libstdc++-devel-{32,64}-bit. +* Thu Mar 23 2017 rguenther@suse.com +- Switch gcc to default 7. +- Remove unrelated README.packaging. +* Fri Feb 10 2017 rguenther@suse.com +- Enable Ada for s390x. +* Mon Jan 23 2017 rguenther@suse.com +- Remove java related packages, those are in a separate gcc-java now. +* Thu Aug 18 2016 rguenther@suse.com +- Add gcc-devel package. +* Wed Apr 27 2016 rguenther@suse.com +- Switch gcc to default 6. +* Thu Apr 14 2016 rguenther@suse.com +- Enable Ada for ppc64le and aarch64. +* Thu May 21 2015 rguenther@suse.com +- Properly query gcc-%%gcc_suffix for paths. +* Tue May 19 2015 rguenther@suse.com +- Fix bogus requires to gcc5-c++-{32,64}bit. +* Fri May 8 2015 rguenther@suse.com +- Adjust for GCC 5 package renames. +* Mon Apr 20 2015 rguenther@suse.com +- Switch gcc to default 5. +- Add gcc-go{,-32bit,-64bit} packages. +* Mon Mar 2 2015 schwab@suse.de +- Add gcc-ada-32bit and gcc-ada-64bit packages only if building Ada +* Wed Feb 25 2015 rguenther@suse.com +- Add gcc-ada-32bit and gcc-ada-64bit packages. +* Wed Feb 4 2015 meissner@suse.com +- add a gcc-PIE subpackage, which enables building PIE binaries + by default using the defaults.spec file. bsc#912298 +* Mon Aug 4 2014 rguenther@suse.com +- Add libstdc++-devel-32bit and libstdc++-devel-64bit packages. + [bnc#890226] +* Fri Mar 21 2014 rguenther@suse.com +- Link to the system compiler LTO plugin from /usr/lib/bfd-plugins. +* Tue Feb 4 2014 rguenther@suse.com +- Remove gcc-z9 wrapper which is obsolete. +* Mon Dec 2 2013 rguenther@suse.com +- Move gcc-ar, gcc-nm and gcc-ranlib to the gcc package instead + of packaging them separately. +* Wed Jun 19 2013 rguenther@suse.com +- Package gcc-ar, gcc-nm and gcc-ranlib wrapping ar, nm and ranlib + in a plugin-aware fashion. +* Mon May 27 2013 rguenther@suse.com +- Switch gcc to default 4.8. +* Mon Jan 7 2013 rguenther@suse.com +- Re-enable Ada for ppc64. +* Thu Dec 13 2012 rguenther@suse.com +- Add BuildRequires to gcc$version, required for cc1 path detection. +* Wed Nov 28 2012 rguenther@suse.com +- Rework gcc-info. + * Install symlinks to the versioned info files and adjust + install_info calls. [bnc#756182] + * Provide uninstall hook that removes the alias entries. +* Thu Oct 4 2012 dmueller@suse.com +- remove gcc-ada subpackage for those architectures that + don't have a gccXX-ada package +* Wed Apr 18 2012 rguenther@suse.com +- Switch gcc to default 4.7. +* Fri Jan 27 2012 rguenther@suse.com +- Change licenses to follow SPDX convention. +* Mon Sep 26 2011 dmueller@suse.de +- use the target gcc binary for finding the right cc1 path +* Wed May 11 2011 rguenther@novell.com +- Switch gcc to default 4.6. +* Thu Feb 10 2011 rguenther@novell.com +- Fix licenses to match those of the system compiler. [bnc#670658] +* Tue Jan 25 2011 rguenther@novell.com +- Fix string quoting. [bnc#666416] +* Wed Jan 12 2011 rguenther@novell.com +- Uglify spec file formatting. +* Fri Dec 10 2010 rguenther@novell.com +- Add info directory aliases for unversioned variants of the + GCC user manuals. [bnc#635355] +* Mon Nov 29 2010 rguenther@novell.com +- Drop libffi packages. +* Fri Feb 26 2010 rguenther@novell.com +- Fix gcc-c++-32bit and gcc-c++-64bit again. +* Thu Feb 25 2010 rguenther@suse.de +- Drop c++_compiler provides from gcc-c++-32bit and gcc-c++-64bit. +* Thu Feb 25 2010 rguenther@suse.de +- Re-add gcc-c++-32bit and gcc-c++-64bit packages. +* Tue Feb 16 2010 coolo@novell.com +- Switch gcc to default 4.5. +* Mon Apr 27 2009 rguenther@suse.de +- Switch gcc default to 4.4. +* Mon Feb 16 2009 rguenther@suse.de +- Enable links for classpath binaries and manpages again. +* Fri Jan 9 2009 rguenther@suse.de +- On ppc64 obsolete gcc-objc-64bit by gcc-objc. +* Thu Dec 4 2008 matz@suse.de +- Add new gcc-z9 package on s390 and s390x to change the + default -march and -mtune settings. +* Wed May 7 2008 rguenther@suse.de +- Make dependencies between the gcc subpackages versioned. [bnc#385305] +* Fri Nov 23 2007 rguenther@suse.de +- Make gcc-gij dependency of gcc-java a recommendation, all java + tools are back to the gcc-java package. Require libgcj-devel + from gcc-java. +- Revert /lib/cpp changes. +* Fri Nov 16 2007 rguenther@suse.de +- For now disable symlinking of binaries and manpages that + conflict with the classpath package. +* Tue Nov 13 2007 rguenther@suse.de +- Make /lib/cpp traditional and avoid GCC and target specific + defines. +* Tue Oct 30 2007 rguenther@suse.de +- Add gcc-gij dependency to gcc-java as it contains many of the + tools formerly packaged in the gcc-java package. +* Mon Sep 24 2007 rguenther@suse.de +- Switch gcc default to 4.3. +* Fri Jul 27 2007 rguenther@suse.de +- Fix typo. +* Tue Jul 24 2007 rguenther@suse.de +- Add 32bit and 64bit variants of gcc-gij. [#293423] +* Fri Jul 6 2007 rguenther@suse.de +- Mark ppc64 as separate bi-32. +* Thu Jun 14 2007 ro@suse.de +- Do not mark README.packaging as NoSource. (again) +* Fri Jun 8 2007 rguenther@suse.de +- Switch gcc default to 4.2. [#275939] +* Tue Apr 24 2007 rguenther@suse.de +- Do not link to grmic and grmiregistry, they conflict with + the classpath package versions. +* Tue Jan 16 2007 rguenther@suse.de +- Do not mark README.packaging as NoSource. +* Thu Nov 9 2006 rguenther@suse.de +- Remove gcc-c++-32bit and gcc-c++-64bit packages. +* Tue Oct 31 2006 dmueller@suse.de +- don't build as root +* Mon Oct 30 2006 rguenther@suse.de +- Make gcc architecture dependent again. [#215971] +* Thu Oct 26 2006 rguenther@suse.de +- Add dependencies to the gcc and non-32/64bit packages. [#215217] +* Tue Sep 19 2006 rguenther@suse.de +- New gcc-gij package. +* Fri Aug 25 2006 rguenther@suse.de +- Add 32bit and 64bit support packages to gcc, gcc-c++, gcc-fortran, + gcc-objc and libffi-devel. +* Thu Aug 24 2006 rguenther@suse.de +- Make gcc require cpp to pull in /lib/cpp. +* Fri Aug 18 2006 rguenther@suse.de +- gcc obsoletes gcc-mudflap which is no longer. +* Mon Aug 7 2006 rguenther@suse.de +- Provide gcc-mudflap, gcc-info and gcc-locale packages [#197515]. +* Fri Jul 14 2006 rguenther@suse.de +- New package. diff --git a/gcc.spec b/gcc.spec new file mode 100644 index 0000000..72d0f3e --- /dev/null +++ b/gcc.spec @@ -0,0 +1,604 @@ +# +# spec file for package gcc +# +# Copyright (c) 2022-2023 ZhuningOS +# + + +Name: gcc +%define separate_bi32 0 +%define separate_bi64 0 +%ifarch ppc +%define separate_bi64 1 +%endif +%ifarch x86_64 s390x ppc64 +%define separate_bi32 1 +%endif +# Ada currently fails to build on a few platforms, enable it only +# on those that work +# Note that AdaCore only supports %ix86, x86_64 and ia64 +%ifarch %ix86 x86_64 ppc ppc64 ppc64le s390 s390x ia64 aarch64 +%define build_ada 1 +%else +# alpha hppa arm +%define build_ada 0 +%endif +Url: http://gcc.gnu.org/ +%define gcc_version 7 +%define gcc_suffix 7 +Version: 7 +Release: 3.9.1 +Summary: The system GNU C Compiler +License: GPL-3.0+ +Group: Development/Languages/C and C++ +Provides: c_compiler +Obsoletes: gcc-ar +Obsoletes: gcc-mudflap +Obsoletes: gcc-nm +Obsoletes: gcc-ranlib +Requires: cpp +Requires: gcc%{gcc_version} +BuildRoot: %{_tmppath}/%{name}-%{version}-build +BuildRequires: gcc%{gcc_version} +Source: cpp + +%description +The system GNU C Compiler. + + + +%package -n gcc-32bit +Summary: The system GNU C Compiler +License: GPL-3.0+ +Group: Development/Languages/C and C++ +Requires: gcc = %{version} +Requires: gcc%{gcc_version}-32bit + +%description -n gcc-32bit +The system GNU C Compiler. + + + +%package -n gcc-64bit +Summary: The system GNU C Compiler +License: GPL-3.0+ +Group: Development/Languages/C and C++ +Requires: gcc = %{version} +Requires: gcc%{gcc_version}-64bit + +%description -n gcc-64bit +The system GNU C Compiler. + + + +%package -n cpp +Summary: The system GNU Preprocessor +License: GPL-3.0+ +Group: Development/Languages/C and C++ +Requires: cpp%{gcc_version} + +%description -n cpp +The system GNU Preprocessor. + + +%package -n gcc-devel +Summary: The system GNU C Compiler Plugin development files +License: GPL-3.0+ +Group: Development/Languages/C and C++ +Requires: gcc = %{version} +Requires: gcc%{gcc_version}-devel + +%description -n gcc-devel +The system GNU C Compiler Plugin development files. + + +%package -n gcc-locale +Summary: The system GNU Compiler locale files +License: GPL-3.0+ +Group: Development/Languages/C and C++ +Requires: gcc%{gcc_version}-locale + +%description -n gcc-locale +The system GNU Compiler locale files. + + + +%package -n gcc-info +Summary: The system GNU Compiler documentation +License: GFDL-1.2 +Group: Development/Languages/C and C++ +PreReq: %{install_info_prereq} +PreReq: gcc%{gcc_version}-info + +%description -n gcc-info +The system GNU Compiler documentation. + +# install / update the entries +%post -n gcc-info +%install_info --info-dir=%{_infodir} --name=cpp --description='The GNU C preprocessor.' %{_infodir}/cpp.info.gz +%install_info --info-dir=%{_infodir} --name=gcc --description='The GNU Compiler Collection.' %{_infodir}/gcc.info.gz +%install_info --info-dir=%{_infodir} --name=g++ --description='The GNU C++ compiler.' %{_infodir}/gcc.info.gz +%install_info --info-dir=%{_infodir} --name=gfortran --description='The GNU Fortran compiler.' %{_infodir}/gfortran.info.gz + +# if we uninstall, clean the entries +%preun -n gcc-info +if [ "$1" -eq "0" ] ; then + %install_info --delete --info-dir=%{_infodir} --name=cpp %{_infodir}/cpp.info.gz + %install_info --delete --info-dir=%{_infodir} --name=gcc %{_infodir}/gcc.info.gz + %install_info --delete --info-dir=%{_infodir} --name=g++ %{_infodir}/gcc.info.gz + %install_info --delete --info-dir=%{_infodir} --name=gfortran %{_infodir}/gfortran.info.gz +fi + +%package -n gcc-c++ +Summary: The system GNU C++ Compiler +License: GPL-3.0+ +Group: Development/Languages/C and C++ +Provides: c++_compiler +Requires: gcc = %{version} +Requires: gcc%{gcc_version}-c++ + +%description -n gcc-c++ +The system GNU C++ Compiler. + + +%package -n gcc-c++-32bit +Summary: The system GNU C++ Compiler +License: GPL-3.0+ +Group: Development/Languages/C and C++ +Requires: gcc%{gcc_version}-c++-32bit +Requires: gcc-32bit = %{version} +Requires: gcc-c++ = %{version} + +%description -n gcc-c++-32bit +The system GNU C++ Compiler 32 bit support. + + +%package -n gcc-c++-64bit +Summary: The system GNU C++ Compiler +License: GPL-3.0+ +Group: Development/Languages/C and C++ +Requires: gcc%{gcc_version}-c++-64bit +Requires: gcc-64bit = %{version} +Requires: gcc-c++ = %{version} + +%description -n gcc-c++-64bit +The system GNU C++ Compiler 64 bit support. + + + +%package -n libstdc++-devel +Summary: The system GNU C++ development files +License: GPL-3.0-with-GCC-exception +Group: System/Libraries +Requires: libstdc++6-devel-gcc%{gcc_version} + +%description -n libstdc++-devel +The system GNU C++ development files. + + +%package -n libstdc++-devel-32bit +Summary: The system GNU C++ 32bit development files +License: GPL-3.0-with-GCC-exception +Group: System/Libraries +Requires: libstdc++-devel +Requires: libstdc++6-devel-gcc%{gcc_version}-32bit + +%description -n libstdc++-devel-32bit +The system GNU C++ 32bit development files. + + +%package -n libstdc++-devel-64bit +Summary: The system GNU C++ 64bit development files +License: GPL-3.0-with-GCC-exception +Group: System/Libraries +Requires: libstdc++-devel +Requires: libstdc++6-devel-gcc%{gcc_version}-64bit + +%description -n libstdc++-devel-64bit +The system GNU C++ 64bit development files. + + + +%package -n gcc-fortran +Summary: The system GNU Fortran Compiler +License: GPL-3.0+ +Group: Development/Languages/Fortran +Requires: gcc = %{version} +Requires: gcc%{gcc_version}-fortran + +%description -n gcc-fortran +The system GNU Fortran Compiler. + + +%package -n gcc-fortran-32bit +Summary: The system GNU Fortran Compiler +License: GPL-3.0+ +Group: Development/Languages/Fortran +Requires: gcc%{gcc_version}-fortran-32bit +Requires: gcc-fortran = %{version} + +%description -n gcc-fortran-32bit +The system GNU Fortran Compiler 32 bit support. + + +%package -n gcc-fortran-64bit +Summary: The system GNU Fortran Compiler +License: GPL-3.0+ +Group: Development/Languages/Fortran +Requires: gcc%{gcc_version}-fortran-64bit +Requires: gcc-fortran = %{version} + +%description -n gcc-fortran-64bit +The system GNU Fortran Compiler 64 bit support. + + + +%package -n gcc-objc +Summary: The system GNU Objective C Compiler +License: GPL-3.0+ +Group: Development/Languages/Other +Requires: gcc = %{version} +Requires: gcc%{gcc_version}-objc +%ifarch ppc64 +Obsoletes: gcc-objc-64bit +%endif + +%description -n gcc-objc +The system GNU Objective C Compiler. + + + +%package -n gcc-objc-32bit +Summary: The system GNU Objective C Compiler +License: GPL-3.0+ +Group: Development/Languages/Other +Requires: gcc%{gcc_version}-objc-32bit +Requires: gcc-objc = %{version} + +%description -n gcc-objc-32bit +The system GNU Objective C Compiler 32 bit support. + + + +%package -n gcc-objc-64bit +Summary: The system GNU Objective C Compiler +License: GPL-3.0+ +Group: Development/Languages/Other +Requires: gcc%{gcc_version}-objc-64bit +Requires: gcc-objc = %{version} + +%description -n gcc-objc-64bit +The system GNU Objective C Compiler 64 bit support. + + + +%package -n gcc-obj-c++ +Summary: The system GNU Objective C++ Compiler +License: GPL-3.0+ +Group: Development/Languages/Other +Requires: gcc%{gcc_version}-obj-c++ +Requires: gcc-objc = %{version} + +%description -n gcc-obj-c++ +The system GNU Objective C++ Compiler. + + + +%package -n gcc-PIE +Summary: A default configuration to build all binaries in PIE mode +License: GPL-3.0+ +Group: Development/Languages/Other +Requires: gcc + +%description -n gcc-PIE +This package contains a configuration file (spec) that changes the +compilers default setting to build all ELF binaries in the Position +Independend Executable (PIE) variant. This enables better address +space randomization (ASLR). + + +%package -n gcc-ada +Summary: The system GNU Ada Compiler +License: GPL-3.0+ +Group: Development/Languages/C and C++ +Requires: gcc = %{version} +Requires: gcc%{gcc_version}-ada + +%description -n gcc-ada +The system GNU Ada Compiler. + +%package -n gcc-ada-32bit +Summary: The system GNU Ada Compiler +License: GPL-3.0+ +Group: Development/Languages/C and C++ +Requires: gcc%{gcc_version}-ada-32bit +Requires: gcc-ada = %{version} + +%description -n gcc-ada-32bit +The system GNU Ada Compiler 32 bit support. + +%package -n gcc-ada-64bit +Summary: The system GNU Ada Compiler +License: GPL-3.0+ +Group: Development/Languages/C and C++ +Requires: gcc%{gcc_version}-ada-64bit +Requires: gcc-ada = %{version} + +%description -n gcc-ada-64bit +The system GNU Ada Compiler 64 bit support. + + +%package -n gcc-go +Summary: The system GNU Go Compiler +License: GPL-3.0+ +Group: Development/Languages/C and C++ +Requires: gcc = %{version} +Requires: gcc%{gcc_version}-go +Requires(post): update-alternatives +Requires(postun): update-alternatives + +%description -n gcc-go +The system GNU Go Compiler. + +%package -n gcc-go-32bit +Summary: The system GNU Go Compiler +License: GPL-3.0+ +Group: Development/Languages/C and C++ +Requires: gcc%{gcc_version}-go-32bit +Requires: gcc-go = %{version} + +%description -n gcc-go-32bit +The system GNU Go Compiler 32bit support. + +%package -n gcc-go-64bit +Summary: The system GNU Go Compiler +License: GPL-3.0+ +Group: Development/Languages/C and C++ +Requires: gcc%{gcc_version}-go-64bit +Requires: gcc-go = %{version} + +%description -n gcc-go-64bit +The system GNU Go Compiler 64bit support. + + +%prep + +%install +mkdir -p $RPM_BUILD_ROOT/lib +mkdir -p $RPM_BUILD_ROOT%{_prefix}/bin +mkdir -p $RPM_BUILD_ROOT%{_mandir}/man1 +mkdir -p $RPM_BUILD_ROOT%{_infodir} +mkdir -p $RPM_BUILD_ROOT%{_prefix}/share/doc/packages/gcc-objc/ +mkdir -p $RPM_BUILD_ROOT%{_prefix}/share/doc/packages/gcc-obj-c++/ +# Link all the binaries +for program in \ + gcc gcov gcov-dump gcov-tool \ + g++ \ + cpp \ + gfortran \ + gccgo \ +%if %{build_ada} + gnat gnatbind gnatbl gnatchop gnatclean gnatfind gnatkr \ + gnatlink gnatls gnatmake gnatname gnatprep gnatxref gprmake \ +%endif + gcc-ar gcc-nm gcc-ranlib \ + ; do + ln -sf $program-%{gcc_suffix} $RPM_BUILD_ROOT%{_prefix}/bin/$program +done +# For go and gofmt use alternatives since they are shared with golang +mkdir -p %{buildroot}%{_sysconfdir}/alternatives +ln -sf %{_sysconfdir}/alternatives/go %{buildroot}%{_bindir}/go +ln -sf %{_sysconfdir}/alternatives/gofmt %{buildroot}%{_bindir}/gofmt +# Link section 1 manpages +for man1 in \ + gcc gcov gcov-dump gcov-tool \ + g++ \ + cpp \ + gfortran \ + gccgo \ + ; do + ln -sf $man1-%{gcc_suffix}.1.gz $RPM_BUILD_ROOT%{_mandir}/man1/$man1.1.gz +done +# Link info pages +for info in cpp gcc gfortran ; do + ln -sf $info-%{gcc_suffix}.info.gz $RPM_BUILD_ROOT%{_infodir}/$info.info.gz +done +# Provide the traditional /lib/cpp that only handles C +cp $RPM_SOURCE_DIR/cpp $RPM_BUILD_ROOT/lib/ +chmod 755 $RPM_BUILD_ROOT/lib/cpp +# Provide extra symlinks +ln -sf g++-%{gcc_suffix} $RPM_BUILD_ROOT%{_prefix}/bin/c++ +ln -sf gcc-%{gcc_suffix} $RPM_BUILD_ROOT%{_prefix}/bin/cc +ln -sf g++-%{gcc_suffix}.1.gz $RPM_BUILD_ROOT%{_mandir}/man1/c++.1.gz +ln -sf gcc-%{gcc_suffix}.1.gz $RPM_BUILD_ROOT%{_mandir}/man1/cc.1.gz +# Install the LTO linker plugin so it is auto-loaded by BFD +mkdir -p $RPM_BUILD_ROOT%{_prefix}/lib/bfd-plugins +ln -s `gcc-%{gcc_suffix} -print-file-name=liblto_plugin.so.0.0.0` $RPM_BUILD_ROOT%{_prefix}/lib/bfd-plugins/liblto_plugin.so.0.0.0 + +dir=`gcc-%{gcc_suffix} -print-prog-name=cc1` +dir=${dir%/cc1} +mkdir -p $RPM_BUILD_ROOT/$dir +cat > $RPM_BUILD_ROOT/$dir/defaults.spec < +Date: Fri, 16 Jun 2023 16:43:41 +0100 +Subject: [PATCH 01/19] aarch64: Use local frame vars in shrink-wrapping code +To: gcc-patches@gcc.gnu.org + +aarch64_layout_frame uses a shorthand for referring to +cfun->machine->frame: + + aarch64_frame &frame = cfun->machine->frame; + +This patch does the same for some other heavy users of the structure. +No functional change intended. + +gcc/ + * config/aarch64/aarch64.cc (aarch64_save_callee_saves): Use + a local shorthand for cfun->machine->frame. + (aarch64_restore_callee_saves, aarch64_get_separate_components): + (aarch64_process_components): Likewise. + (aarch64_allocate_and_probe_stack_space): Likewise. + (aarch64_expand_prologue, aarch64_expand_epilogue): Likewise. + (aarch64_layout_frame): Use existing shorthand for one more case. +--- + gcc/config/aarch64/aarch64.cc | 123 ++++++++++++++++++---------------- + 1 file changed, 64 insertions(+), 59 deletions(-) + +diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc +index 226dc9dffd4..ae42ffdedbe 100644 +--- a/gcc/config/aarch64/aarch64.cc ++++ b/gcc/config/aarch64/aarch64.cc +@@ -8351,7 +8351,7 @@ aarch64_layout_frame (void) + frame.is_scs_enabled + = (!crtl->calls_eh_return + && sanitize_flags_p (SANITIZE_SHADOW_CALL_STACK) +- && known_ge (cfun->machine->frame.reg_offset[LR_REGNUM], 0)); ++ && known_ge (frame.reg_offset[LR_REGNUM], 0)); + + /* When shadow call stack is enabled, the scs_pop in the epilogue will + restore x30, and we don't need to pop x30 again in the traditional +@@ -8763,6 +8763,7 @@ aarch64_save_callee_saves (poly_int64 start_offset, + unsigned start, unsigned limit, bool skip_wb, + bool hard_fp_valid_p) + { ++ aarch64_frame &frame = cfun->machine->frame; + rtx_insn *insn; + unsigned regno; + unsigned regno2; +@@ -8777,8 +8778,8 @@ aarch64_save_callee_saves (poly_int64 start_offset, + bool frame_related_p = aarch64_emit_cfi_for_reg_p (regno); + + if (skip_wb +- && (regno == cfun->machine->frame.wb_push_candidate1 +- || regno == cfun->machine->frame.wb_push_candidate2)) ++ && (regno == frame.wb_push_candidate1 ++ || regno == frame.wb_push_candidate2)) + continue; + + if (cfun->machine->reg_is_wrapped_separately[regno]) +@@ -8786,7 +8787,7 @@ aarch64_save_callee_saves (poly_int64 start_offset, + + machine_mode mode = aarch64_reg_save_mode (regno); + reg = gen_rtx_REG (mode, regno); +- offset = start_offset + cfun->machine->frame.reg_offset[regno]; ++ offset = start_offset + frame.reg_offset[regno]; + rtx base_rtx = stack_pointer_rtx; + poly_int64 sp_offset = offset; + +@@ -8799,7 +8800,7 @@ aarch64_save_callee_saves (poly_int64 start_offset, + { + gcc_assert (known_eq (start_offset, 0)); + poly_int64 fp_offset +- = cfun->machine->frame.below_hard_fp_saved_regs_size; ++ = frame.below_hard_fp_saved_regs_size; + if (hard_fp_valid_p) + base_rtx = hard_frame_pointer_rtx; + else +@@ -8821,8 +8822,7 @@ aarch64_save_callee_saves (poly_int64 start_offset, + && (regno2 = aarch64_next_callee_save (regno + 1, limit)) <= limit + && !cfun->machine->reg_is_wrapped_separately[regno2] + && known_eq (GET_MODE_SIZE (mode), +- cfun->machine->frame.reg_offset[regno2] +- - cfun->machine->frame.reg_offset[regno])) ++ frame.reg_offset[regno2] - frame.reg_offset[regno])) + { + rtx reg2 = gen_rtx_REG (mode, regno2); + rtx mem2; +@@ -8872,6 +8872,7 @@ static void + aarch64_restore_callee_saves (poly_int64 start_offset, unsigned start, + unsigned limit, bool skip_wb, rtx *cfi_ops) + { ++ aarch64_frame &frame = cfun->machine->frame; + unsigned regno; + unsigned regno2; + poly_int64 offset; +@@ -8888,13 +8889,13 @@ aarch64_restore_callee_saves (poly_int64 start_offset, unsigned start, + rtx reg, mem; + + if (skip_wb +- && (regno == cfun->machine->frame.wb_pop_candidate1 +- || regno == cfun->machine->frame.wb_pop_candidate2)) ++ && (regno == frame.wb_pop_candidate1 ++ || regno == frame.wb_pop_candidate2)) + continue; + + machine_mode mode = aarch64_reg_save_mode (regno); + reg = gen_rtx_REG (mode, regno); +- offset = start_offset + cfun->machine->frame.reg_offset[regno]; ++ offset = start_offset + frame.reg_offset[regno]; + rtx base_rtx = stack_pointer_rtx; + if (mode == VNx2DImode && BYTES_BIG_ENDIAN) + aarch64_adjust_sve_callee_save_base (mode, base_rtx, anchor_reg, +@@ -8905,8 +8906,7 @@ aarch64_restore_callee_saves (poly_int64 start_offset, unsigned start, + && (regno2 = aarch64_next_callee_save (regno + 1, limit)) <= limit + && !cfun->machine->reg_is_wrapped_separately[regno2] + && known_eq (GET_MODE_SIZE (mode), +- cfun->machine->frame.reg_offset[regno2] +- - cfun->machine->frame.reg_offset[regno])) ++ frame.reg_offset[regno2] - frame.reg_offset[regno])) + { + rtx reg2 = gen_rtx_REG (mode, regno2); + rtx mem2; +@@ -9011,6 +9011,7 @@ offset_12bit_unsigned_scaled_p (machine_mode mode, poly_int64 offset) + static sbitmap + aarch64_get_separate_components (void) + { ++ aarch64_frame &frame = cfun->machine->frame; + sbitmap components = sbitmap_alloc (LAST_SAVED_REGNUM + 1); + bitmap_clear (components); + +@@ -9027,18 +9028,18 @@ aarch64_get_separate_components (void) + if (mode == VNx2DImode && BYTES_BIG_ENDIAN) + continue; + +- poly_int64 offset = cfun->machine->frame.reg_offset[regno]; ++ poly_int64 offset = frame.reg_offset[regno]; + + /* If the register is saved in the first SVE save slot, we use + it as a stack probe for -fstack-clash-protection. */ + if (flag_stack_clash_protection +- && maybe_ne (cfun->machine->frame.below_hard_fp_saved_regs_size, 0) ++ && maybe_ne (frame.below_hard_fp_saved_regs_size, 0) + && known_eq (offset, 0)) + continue; + + /* Get the offset relative to the register we'll use. */ + if (frame_pointer_needed) +- offset -= cfun->machine->frame.below_hard_fp_saved_regs_size; ++ offset -= frame.below_hard_fp_saved_regs_size; + else + offset += crtl->outgoing_args_size; + +@@ -9057,11 +9058,11 @@ aarch64_get_separate_components (void) + /* If the spare predicate register used by big-endian SVE code + is call-preserved, it must be saved in the main prologue + before any saves that use it. */ +- if (cfun->machine->frame.spare_pred_reg != INVALID_REGNUM) +- bitmap_clear_bit (components, cfun->machine->frame.spare_pred_reg); ++ if (frame.spare_pred_reg != INVALID_REGNUM) ++ bitmap_clear_bit (components, frame.spare_pred_reg); + +- unsigned reg1 = cfun->machine->frame.wb_push_candidate1; +- unsigned reg2 = cfun->machine->frame.wb_push_candidate2; ++ unsigned reg1 = frame.wb_push_candidate1; ++ unsigned reg2 = frame.wb_push_candidate2; + /* If registers have been chosen to be stored/restored with + writeback don't interfere with them to avoid having to output explicit + stack adjustment instructions. */ +@@ -9170,6 +9171,7 @@ aarch64_get_next_set_bit (sbitmap bmp, unsigned int start) + static void + aarch64_process_components (sbitmap components, bool prologue_p) + { ++ aarch64_frame &frame = cfun->machine->frame; + rtx ptr_reg = gen_rtx_REG (Pmode, frame_pointer_needed + ? HARD_FRAME_POINTER_REGNUM + : STACK_POINTER_REGNUM); +@@ -9184,9 +9186,9 @@ aarch64_process_components (sbitmap components, bool prologue_p) + machine_mode mode = aarch64_reg_save_mode (regno); + + rtx reg = gen_rtx_REG (mode, regno); +- poly_int64 offset = cfun->machine->frame.reg_offset[regno]; ++ poly_int64 offset = frame.reg_offset[regno]; + if (frame_pointer_needed) +- offset -= cfun->machine->frame.below_hard_fp_saved_regs_size; ++ offset -= frame.below_hard_fp_saved_regs_size; + else + offset += crtl->outgoing_args_size; + +@@ -9211,14 +9213,14 @@ aarch64_process_components (sbitmap components, bool prologue_p) + break; + } + +- poly_int64 offset2 = cfun->machine->frame.reg_offset[regno2]; ++ poly_int64 offset2 = frame.reg_offset[regno2]; + /* The next register is not of the same class or its offset is not + mergeable with the current one into a pair. */ + if (aarch64_sve_mode_p (mode) + || !satisfies_constraint_Ump (mem) + || GP_REGNUM_P (regno) != GP_REGNUM_P (regno2) + || (crtl->abi->id () == ARM_PCS_SIMD && FP_REGNUM_P (regno)) +- || maybe_ne ((offset2 - cfun->machine->frame.reg_offset[regno]), ++ || maybe_ne ((offset2 - frame.reg_offset[regno]), + GET_MODE_SIZE (mode))) + { + insn = emit_insn (set); +@@ -9240,7 +9242,7 @@ aarch64_process_components (sbitmap components, bool prologue_p) + /* REGNO2 can be saved/restored in a pair with REGNO. */ + rtx reg2 = gen_rtx_REG (mode, regno2); + if (frame_pointer_needed) +- offset2 -= cfun->machine->frame.below_hard_fp_saved_regs_size; ++ offset2 -= frame.below_hard_fp_saved_regs_size; + else + offset2 += crtl->outgoing_args_size; + rtx addr2 = plus_constant (Pmode, ptr_reg, offset2); +@@ -9335,6 +9337,7 @@ aarch64_allocate_and_probe_stack_space (rtx temp1, rtx temp2, + bool frame_related_p, + bool final_adjustment_p) + { ++ aarch64_frame &frame = cfun->machine->frame; + HOST_WIDE_INT guard_size + = 1 << param_stack_clash_protection_guard_size; + HOST_WIDE_INT guard_used_by_caller = STACK_CLASH_CALLER_GUARD; +@@ -9355,25 +9358,25 @@ aarch64_allocate_and_probe_stack_space (rtx temp1, rtx temp2, + register as a probe. We can't assume that LR was saved at position 0 + though, so treat any space below it as unprobed. */ + if (final_adjustment_p +- && known_eq (cfun->machine->frame.below_hard_fp_saved_regs_size, 0)) ++ && known_eq (frame.below_hard_fp_saved_regs_size, 0)) + { +- poly_int64 lr_offset = cfun->machine->frame.reg_offset[LR_REGNUM]; ++ poly_int64 lr_offset = frame.reg_offset[LR_REGNUM]; + if (known_ge (lr_offset, 0)) + min_probe_threshold -= lr_offset.to_constant (); + else + gcc_assert (!flag_stack_clash_protection || known_eq (poly_size, 0)); + } + +- poly_int64 frame_size = cfun->machine->frame.frame_size; ++ poly_int64 frame_size = frame.frame_size; + + /* We should always have a positive probe threshold. */ + gcc_assert (min_probe_threshold > 0); + + if (flag_stack_clash_protection && !final_adjustment_p) + { +- poly_int64 initial_adjust = cfun->machine->frame.initial_adjust; +- poly_int64 sve_callee_adjust = cfun->machine->frame.sve_callee_adjust; +- poly_int64 final_adjust = cfun->machine->frame.final_adjust; ++ poly_int64 initial_adjust = frame.initial_adjust; ++ poly_int64 sve_callee_adjust = frame.sve_callee_adjust; ++ poly_int64 final_adjust = frame.final_adjust; + + if (known_eq (frame_size, 0)) + { +@@ -9662,17 +9665,18 @@ aarch64_epilogue_uses (int regno) + void + aarch64_expand_prologue (void) + { +- poly_int64 frame_size = cfun->machine->frame.frame_size; +- poly_int64 initial_adjust = cfun->machine->frame.initial_adjust; +- HOST_WIDE_INT callee_adjust = cfun->machine->frame.callee_adjust; +- poly_int64 final_adjust = cfun->machine->frame.final_adjust; +- poly_int64 callee_offset = cfun->machine->frame.callee_offset; +- poly_int64 sve_callee_adjust = cfun->machine->frame.sve_callee_adjust; ++ aarch64_frame &frame = cfun->machine->frame; ++ poly_int64 frame_size = frame.frame_size; ++ poly_int64 initial_adjust = frame.initial_adjust; ++ HOST_WIDE_INT callee_adjust = frame.callee_adjust; ++ poly_int64 final_adjust = frame.final_adjust; ++ poly_int64 callee_offset = frame.callee_offset; ++ poly_int64 sve_callee_adjust = frame.sve_callee_adjust; + poly_int64 below_hard_fp_saved_regs_size +- = cfun->machine->frame.below_hard_fp_saved_regs_size; +- unsigned reg1 = cfun->machine->frame.wb_push_candidate1; +- unsigned reg2 = cfun->machine->frame.wb_push_candidate2; +- bool emit_frame_chain = cfun->machine->frame.emit_frame_chain; ++ = frame.below_hard_fp_saved_regs_size; ++ unsigned reg1 = frame.wb_push_candidate1; ++ unsigned reg2 = frame.wb_push_candidate2; ++ bool emit_frame_chain = frame.emit_frame_chain; + rtx_insn *insn; + + if (flag_stack_clash_protection && known_eq (callee_adjust, 0)) +@@ -9703,7 +9707,7 @@ aarch64_expand_prologue (void) + } + + /* Push return address to shadow call stack. */ +- if (cfun->machine->frame.is_scs_enabled) ++ if (frame.is_scs_enabled) + emit_insn (gen_scs_push ()); + + if (flag_stack_usage_info) +@@ -9742,7 +9746,7 @@ aarch64_expand_prologue (void) + + /* The offset of the frame chain record (if any) from the current SP. */ + poly_int64 chain_offset = (initial_adjust + callee_adjust +- - cfun->machine->frame.hard_fp_offset); ++ - frame.hard_fp_offset); + gcc_assert (known_ge (chain_offset, 0)); + + /* The offset of the bottom of the save area from the current SP. */ +@@ -9845,16 +9849,17 @@ aarch64_use_return_insn_p (void) + void + aarch64_expand_epilogue (bool for_sibcall) + { +- poly_int64 initial_adjust = cfun->machine->frame.initial_adjust; +- HOST_WIDE_INT callee_adjust = cfun->machine->frame.callee_adjust; +- poly_int64 final_adjust = cfun->machine->frame.final_adjust; +- poly_int64 callee_offset = cfun->machine->frame.callee_offset; +- poly_int64 sve_callee_adjust = cfun->machine->frame.sve_callee_adjust; ++ aarch64_frame &frame = cfun->machine->frame; ++ poly_int64 initial_adjust = frame.initial_adjust; ++ HOST_WIDE_INT callee_adjust = frame.callee_adjust; ++ poly_int64 final_adjust = frame.final_adjust; ++ poly_int64 callee_offset = frame.callee_offset; ++ poly_int64 sve_callee_adjust = frame.sve_callee_adjust; + poly_int64 below_hard_fp_saved_regs_size +- = cfun->machine->frame.below_hard_fp_saved_regs_size; +- unsigned reg1 = cfun->machine->frame.wb_pop_candidate1; +- unsigned reg2 = cfun->machine->frame.wb_pop_candidate2; +- unsigned int last_gpr = (cfun->machine->frame.is_scs_enabled ++ = frame.below_hard_fp_saved_regs_size; ++ unsigned reg1 = frame.wb_pop_candidate1; ++ unsigned reg2 = frame.wb_pop_candidate2; ++ unsigned int last_gpr = (frame.is_scs_enabled + ? R29_REGNUM : R30_REGNUM); + rtx cfi_ops = NULL; + rtx_insn *insn; +@@ -9888,7 +9893,7 @@ aarch64_expand_epilogue (bool for_sibcall) + /* We need to add memory barrier to prevent read from deallocated stack. */ + bool need_barrier_p + = maybe_ne (get_frame_size () +- + cfun->machine->frame.saved_varargs_size, 0); ++ + frame.saved_varargs_size, 0); + + /* Emit a barrier to prevent loads from a deallocated stack. */ + if (maybe_gt (final_adjust, crtl->outgoing_args_size) +@@ -9969,7 +9974,7 @@ aarch64_expand_epilogue (bool for_sibcall) + } + + /* Pop return address from shadow call stack. */ +- if (cfun->machine->frame.is_scs_enabled) ++ if (frame.is_scs_enabled) + { + machine_mode mode = aarch64_reg_save_mode (R30_REGNUM); + rtx reg = gen_rtx_REG (mode, R30_REGNUM); +@@ -12564,24 +12569,24 @@ aarch64_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to) + poly_int64 + aarch64_initial_elimination_offset (unsigned from, unsigned to) + { ++ aarch64_frame &frame = cfun->machine->frame; ++ + if (to == HARD_FRAME_POINTER_REGNUM) + { + if (from == ARG_POINTER_REGNUM) +- return cfun->machine->frame.hard_fp_offset; ++ return frame.hard_fp_offset; + + if (from == FRAME_POINTER_REGNUM) +- return cfun->machine->frame.hard_fp_offset +- - cfun->machine->frame.locals_offset; ++ return frame.hard_fp_offset - frame.locals_offset; + } + + if (to == STACK_POINTER_REGNUM) + { + if (from == FRAME_POINTER_REGNUM) +- return cfun->machine->frame.frame_size +- - cfun->machine->frame.locals_offset; ++ return frame.frame_size - frame.locals_offset; + } + +- return cfun->machine->frame.frame_size; ++ return frame.frame_size; + } + + +-- +2.25.1 + + +From 7a6a7097534c0023ed11d023a7189282b4177b40 Mon Sep 17 00:00:00 2001 +From: Richard Sandiford +Date: Tue, 27 Jun 2023 11:12:21 +0100 +Subject: [PATCH 02/19] aarch64: Avoid a use of callee_offset +To: gcc-patches@gcc.gnu.org + +When we emit the frame chain, i.e. when we reach Here in this statement +of aarch64_expand_prologue: + + if (emit_frame_chain) + { + // Here + ... + } + +the stack is in one of two states: + +- We've allocated up to the frame chain, but no more. + +- We've allocated the whole frame, and the frame chain is within easy + reach of the new SP. + +The offset of the frame chain from the current SP is available +in aarch64_frame as callee_offset. It is also available as the +chain_offset local variable, where the latter is calculated from other +data. (However, chain_offset is not always equal to callee_offset when +!emit_frame_chain, so chain_offset isn't redundant.) + +In c600df9a4060da3c6121ff4d0b93f179eafd69d1 I switched to using +chain_offset for the initialisation of the hard frame pointer: + + aarch64_add_offset (Pmode, hard_frame_pointer_rtx, +- stack_pointer_rtx, callee_offset, ++ stack_pointer_rtx, chain_offset, + tmp1_rtx, tmp0_rtx, frame_pointer_needed); + +But the later REG_CFA_ADJUST_CFA handling still used callee_offset. + +I think the difference is harmless, but it's more logical for the +CFA note to be in sync, and it's more convenient for later patches +if it uses chain_offset. + +gcc/ + * config/aarch64/aarch64.cc (aarch64_expand_prologue): Use + chain_offset rather than callee_offset. +--- + gcc/config/aarch64/aarch64.cc | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc +index ae42ffdedbe..79253322fd7 100644 +--- a/gcc/config/aarch64/aarch64.cc ++++ b/gcc/config/aarch64/aarch64.cc +@@ -9670,7 +9670,6 @@ aarch64_expand_prologue (void) + poly_int64 initial_adjust = frame.initial_adjust; + HOST_WIDE_INT callee_adjust = frame.callee_adjust; + poly_int64 final_adjust = frame.final_adjust; +- poly_int64 callee_offset = frame.callee_offset; + poly_int64 sve_callee_adjust = frame.sve_callee_adjust; + poly_int64 below_hard_fp_saved_regs_size + = frame.below_hard_fp_saved_regs_size; +@@ -9783,8 +9782,7 @@ aarch64_expand_prologue (void) + implicit. */ + if (!find_reg_note (insn, REG_CFA_ADJUST_CFA, NULL_RTX)) + { +- rtx src = plus_constant (Pmode, stack_pointer_rtx, +- callee_offset); ++ rtx src = plus_constant (Pmode, stack_pointer_rtx, chain_offset); + add_reg_note (insn, REG_CFA_ADJUST_CFA, + gen_rtx_SET (hard_frame_pointer_rtx, src)); + } +-- +2.25.1 + + +From 85ae97bec3bff69559347d3ca29cdcc0f56bba10 Mon Sep 17 00:00:00 2001 +From: Richard Sandiford +Date: Fri, 16 Jun 2023 17:00:51 +0100 +Subject: [PATCH 03/19] aarch64: Explicitly handle frames with no saved + registers +To: gcc-patches@gcc.gnu.org + +If a frame has no saved registers, it can be allocated in one go. +There is no need to treat the areas below and above the saved +registers as separate. + +And if we allocate the frame in one go, it should be allocated +as the initial_adjust rather than the final_adjust. This allows the +frame size to grow to guard_size - guard_used_by_caller before a stack +probe is needed. (A frame with no register saves is necessarily a +leaf frame.) + +This is a no-op as thing stand, since a leaf function will have +no outgoing arguments, and so all the frame will be above where +the saved registers normally go. + +gcc/ + * config/aarch64/aarch64.cc (aarch64_layout_frame): Explicitly + allocate the frame in one go if there are no saved registers. +--- + gcc/config/aarch64/aarch64.cc | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc +index 79253322fd7..e1f21230c15 100644 +--- a/gcc/config/aarch64/aarch64.cc ++++ b/gcc/config/aarch64/aarch64.cc +@@ -8378,9 +8378,11 @@ aarch64_layout_frame (void) + + HOST_WIDE_INT const_size, const_outgoing_args_size, const_fp_offset; + HOST_WIDE_INT const_saved_regs_size; +- if (frame.frame_size.is_constant (&const_size) +- && const_size < max_push_offset +- && known_eq (frame.hard_fp_offset, const_size)) ++ if (known_eq (frame.saved_regs_size, 0)) ++ frame.initial_adjust = frame.frame_size; ++ else if (frame.frame_size.is_constant (&const_size) ++ && const_size < max_push_offset ++ && known_eq (frame.hard_fp_offset, const_size)) + { + /* Simple, small frame with no outgoing arguments: + +-- +2.25.1 + + +From a0481b18ec652743d73b093c51c85862e2132a2f Mon Sep 17 00:00:00 2001 +From: Richard Sandiford +Date: Fri, 16 Jun 2023 16:55:12 +0100 +Subject: [PATCH 04/19] aarch64: Add bytes_below_saved_regs to frame info +To: gcc-patches@gcc.gnu.org + +The frame layout code currently hard-codes the assumption that +the number of bytes below the saved registers is equal to the +size of the outgoing arguments. This patch abstracts that +value into a new field of aarch64_frame. + +gcc/ + * config/aarch64/aarch64.h (aarch64_frame::bytes_below_saved_regs): New + field. + * config/aarch64/aarch64.cc (aarch64_layout_frame): Initialize it, + and use it instead of crtl->outgoing_args_size. + (aarch64_get_separate_components): Use bytes_below_saved_regs instead + of outgoing_args_size. + (aarch64_process_components): Likewise. +--- + gcc/config/aarch64/aarch64.cc | 71 ++++++++++++++++++----------------- + gcc/config/aarch64/aarch64.h | 5 +++ + 2 files changed, 41 insertions(+), 35 deletions(-) + +diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc +index e1f21230c15..94e1b686584 100644 +--- a/gcc/config/aarch64/aarch64.cc ++++ b/gcc/config/aarch64/aarch64.cc +@@ -8217,6 +8217,8 @@ aarch64_layout_frame (void) + gcc_assert (crtl->is_leaf + || maybe_ne (frame.reg_offset[R30_REGNUM], SLOT_NOT_REQUIRED)); + ++ frame.bytes_below_saved_regs = crtl->outgoing_args_size; ++ + /* Now assign stack slots for the registers. Start with the predicate + registers, since predicate LDR and STR have a relatively small + offset range. These saves happen below the hard frame pointer. */ +@@ -8321,18 +8323,18 @@ aarch64_layout_frame (void) + + poly_int64 varargs_and_saved_regs_size = offset + frame.saved_varargs_size; + +- poly_int64 above_outgoing_args ++ poly_int64 saved_regs_and_above + = aligned_upper_bound (varargs_and_saved_regs_size + + get_frame_size (), + STACK_BOUNDARY / BITS_PER_UNIT); + + frame.hard_fp_offset +- = above_outgoing_args - frame.below_hard_fp_saved_regs_size; ++ = saved_regs_and_above - frame.below_hard_fp_saved_regs_size; + + /* Both these values are already aligned. */ +- gcc_assert (multiple_p (crtl->outgoing_args_size, ++ gcc_assert (multiple_p (frame.bytes_below_saved_regs, + STACK_BOUNDARY / BITS_PER_UNIT)); +- frame.frame_size = above_outgoing_args + crtl->outgoing_args_size; ++ frame.frame_size = saved_regs_and_above + frame.bytes_below_saved_regs; + + frame.locals_offset = frame.saved_varargs_size; + +@@ -8376,7 +8378,7 @@ aarch64_layout_frame (void) + else if (frame.wb_pop_candidate1 != INVALID_REGNUM) + max_push_offset = 256; + +- HOST_WIDE_INT const_size, const_outgoing_args_size, const_fp_offset; ++ HOST_WIDE_INT const_size, const_below_saved_regs, const_fp_offset; + HOST_WIDE_INT const_saved_regs_size; + if (known_eq (frame.saved_regs_size, 0)) + frame.initial_adjust = frame.frame_size; +@@ -8384,31 +8386,31 @@ aarch64_layout_frame (void) + && const_size < max_push_offset + && known_eq (frame.hard_fp_offset, const_size)) + { +- /* Simple, small frame with no outgoing arguments: ++ /* Simple, small frame with no data below the saved registers. + + stp reg1, reg2, [sp, -frame_size]! + stp reg3, reg4, [sp, 16] */ + frame.callee_adjust = const_size; + } +- else if (crtl->outgoing_args_size.is_constant (&const_outgoing_args_size) ++ else if (frame.bytes_below_saved_regs.is_constant (&const_below_saved_regs) + && frame.saved_regs_size.is_constant (&const_saved_regs_size) +- && const_outgoing_args_size + const_saved_regs_size < 512 +- /* We could handle this case even with outgoing args, provided +- that the number of args left us with valid offsets for all +- predicate and vector save slots. It's such a rare case that +- it hardly seems worth the effort though. */ +- && (!saves_below_hard_fp_p || const_outgoing_args_size == 0) ++ && const_below_saved_regs + const_saved_regs_size < 512 ++ /* We could handle this case even with data below the saved ++ registers, provided that that data left us with valid offsets ++ for all predicate and vector save slots. It's such a rare ++ case that it hardly seems worth the effort though. */ ++ && (!saves_below_hard_fp_p || const_below_saved_regs == 0) + && !(cfun->calls_alloca + && frame.hard_fp_offset.is_constant (&const_fp_offset) + && const_fp_offset < max_push_offset)) + { +- /* Frame with small outgoing arguments: ++ /* Frame with small area below the saved registers: + + sub sp, sp, frame_size +- stp reg1, reg2, [sp, outgoing_args_size] +- stp reg3, reg4, [sp, outgoing_args_size + 16] */ ++ stp reg1, reg2, [sp, bytes_below_saved_regs] ++ stp reg3, reg4, [sp, bytes_below_saved_regs + 16] */ + frame.initial_adjust = frame.frame_size; +- frame.callee_offset = const_outgoing_args_size; ++ frame.callee_offset = const_below_saved_regs; + } + else if (saves_below_hard_fp_p + && known_eq (frame.saved_regs_size, +@@ -8418,30 +8420,29 @@ aarch64_layout_frame (void) + + sub sp, sp, hard_fp_offset + below_hard_fp_saved_regs_size + save SVE registers relative to SP +- sub sp, sp, outgoing_args_size */ ++ sub sp, sp, bytes_below_saved_regs */ + frame.initial_adjust = (frame.hard_fp_offset + + frame.below_hard_fp_saved_regs_size); +- frame.final_adjust = crtl->outgoing_args_size; ++ frame.final_adjust = frame.bytes_below_saved_regs; + } + else if (frame.hard_fp_offset.is_constant (&const_fp_offset) + && const_fp_offset < max_push_offset) + { +- /* Frame with large outgoing arguments or SVE saves, but with +- a small local area: ++ /* Frame with large area below the saved registers, or with SVE saves, ++ but with a small area above: + + stp reg1, reg2, [sp, -hard_fp_offset]! + stp reg3, reg4, [sp, 16] + [sub sp, sp, below_hard_fp_saved_regs_size] + [save SVE registers relative to SP] +- sub sp, sp, outgoing_args_size */ ++ sub sp, sp, bytes_below_saved_regs */ + frame.callee_adjust = const_fp_offset; + frame.sve_callee_adjust = frame.below_hard_fp_saved_regs_size; +- frame.final_adjust = crtl->outgoing_args_size; ++ frame.final_adjust = frame.bytes_below_saved_regs; + } + else + { +- /* Frame with large local area and outgoing arguments or SVE saves, +- using frame pointer: ++ /* General case: + + sub sp, sp, hard_fp_offset + stp x29, x30, [sp, 0] +@@ -8449,10 +8450,10 @@ aarch64_layout_frame (void) + stp reg3, reg4, [sp, 16] + [sub sp, sp, below_hard_fp_saved_regs_size] + [save SVE registers relative to SP] +- sub sp, sp, outgoing_args_size */ ++ sub sp, sp, bytes_below_saved_regs */ + frame.initial_adjust = frame.hard_fp_offset; + frame.sve_callee_adjust = frame.below_hard_fp_saved_regs_size; +- frame.final_adjust = crtl->outgoing_args_size; ++ frame.final_adjust = frame.bytes_below_saved_regs; + } + + /* Make sure the individual adjustments add up to the full frame size. */ +@@ -9043,7 +9044,7 @@ aarch64_get_separate_components (void) + if (frame_pointer_needed) + offset -= frame.below_hard_fp_saved_regs_size; + else +- offset += crtl->outgoing_args_size; ++ offset += frame.bytes_below_saved_regs; + + /* Check that we can access the stack slot of the register with one + direct load with no adjustments needed. */ +@@ -9192,7 +9193,7 @@ aarch64_process_components (sbitmap components, bool prologue_p) + if (frame_pointer_needed) + offset -= frame.below_hard_fp_saved_regs_size; + else +- offset += crtl->outgoing_args_size; ++ offset += frame.bytes_below_saved_regs; + + rtx addr = plus_constant (Pmode, ptr_reg, offset); + rtx mem = gen_frame_mem (mode, addr); +@@ -9246,7 +9247,7 @@ aarch64_process_components (sbitmap components, bool prologue_p) + if (frame_pointer_needed) + offset2 -= frame.below_hard_fp_saved_regs_size; + else +- offset2 += crtl->outgoing_args_size; ++ offset2 += frame.bytes_below_saved_regs; + rtx addr2 = plus_constant (Pmode, ptr_reg, offset2); + rtx mem2 = gen_frame_mem (mode, addr2); + rtx set2 = prologue_p ? gen_rtx_SET (mem2, reg2) +@@ -9320,10 +9321,10 @@ aarch64_stack_clash_protection_alloca_probe_range (void) + registers. If POLY_SIZE is not large enough to require a probe this function + will only adjust the stack. When allocating the stack space + FRAME_RELATED_P is then used to indicate if the allocation is frame related. +- FINAL_ADJUSTMENT_P indicates whether we are allocating the outgoing +- arguments. If we are then we ensure that any allocation larger than the ABI +- defined buffer needs a probe so that the invariant of having a 1KB buffer is +- maintained. ++ FINAL_ADJUSTMENT_P indicates whether we are allocating the area below ++ the saved registers. If we are then we ensure that any allocation ++ larger than the ABI defined buffer needs a probe so that the ++ invariant of having a 1KB buffer is maintained. + + We emit barriers after each stack adjustment to prevent optimizations from + breaking the invariant that we never drop the stack more than a page. This +@@ -9532,7 +9533,7 @@ aarch64_allocate_and_probe_stack_space (rtx temp1, rtx temp2, + /* Handle any residuals. Residuals of at least MIN_PROBE_THRESHOLD have to + be probed. This maintains the requirement that each page is probed at + least once. For initial probing we probe only if the allocation is +- more than GUARD_SIZE - buffer, and for the outgoing arguments we probe ++ more than GUARD_SIZE - buffer, and below the saved registers we probe + if the amount is larger than buffer. GUARD_SIZE - buffer + buffer == + GUARD_SIZE. This works that for any allocation that is large enough to + trigger a probe here, we'll have at least one, and if they're not large +diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h +index 6834c3e9922..1e105e12db8 100644 +--- a/gcc/config/aarch64/aarch64.h ++++ b/gcc/config/aarch64/aarch64.h +@@ -871,6 +871,11 @@ struct GTY (()) aarch64_frame + /* The size of the callee-save registers with a slot in REG_OFFSET. */ + poly_int64 saved_regs_size; + ++ /* The number of bytes between the bottom of the static frame (the bottom ++ of the outgoing arguments) and the bottom of the register save area. ++ This value is always a multiple of STACK_BOUNDARY. */ ++ poly_int64 bytes_below_saved_regs; ++ + /* The size of the callee-save registers with a slot in REG_OFFSET that + are saved below the hard frame pointer. */ + poly_int64 below_hard_fp_saved_regs_size; +-- +2.25.1 + + +From e88f4319bb99042fe98488660edffabddbb388ab Mon Sep 17 00:00:00 2001 +From: Richard Sandiford +Date: Tue, 27 Jun 2023 11:17:33 +0100 +Subject: [PATCH 05/19] aarch64: Add bytes_below_hard_fp to frame info +To: gcc-patches@gcc.gnu.org + +Following on from the previous bytes_below_saved_regs patch, this one +records the number of bytes that are below the hard frame pointer. +This eventually replaces below_hard_fp_saved_regs_size. + +If a frame pointer is not needed, the epilogue adds final_adjust +to the stack pointer before restoring registers: + + aarch64_add_sp (tmp1_rtx, tmp0_rtx, final_adjust, true); + +Therefore, if the epilogue needs to restore the stack pointer from +the hard frame pointer, the directly corresponding offset is: + + -bytes_below_hard_fp + final_adjust + +i.e. go from the hard frame pointer to the bottom of the frame, +then add the same amount as if we were using the stack pointer +from the outset. + +gcc/ + * config/aarch64/aarch64.h (aarch64_frame::bytes_below_hard_fp): New + field. + * config/aarch64/aarch64.cc (aarch64_layout_frame): Initialize it. + (aarch64_expand_epilogue): Use it instead of + below_hard_fp_saved_regs_size. +--- + gcc/config/aarch64/aarch64.cc | 6 +++--- + gcc/config/aarch64/aarch64.h | 5 +++++ + 2 files changed, 8 insertions(+), 3 deletions(-) + +diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc +index 94e1b686584..c7d84245fbf 100644 +--- a/gcc/config/aarch64/aarch64.cc ++++ b/gcc/config/aarch64/aarch64.cc +@@ -8269,6 +8269,7 @@ aarch64_layout_frame (void) + of the callee save area. */ + bool saves_below_hard_fp_p = maybe_ne (offset, 0); + frame.below_hard_fp_saved_regs_size = offset; ++ frame.bytes_below_hard_fp = offset + frame.bytes_below_saved_regs; + if (frame.emit_frame_chain) + { + /* FP and LR are placed in the linkage record. */ +@@ -9856,8 +9857,7 @@ aarch64_expand_epilogue (bool for_sibcall) + poly_int64 final_adjust = frame.final_adjust; + poly_int64 callee_offset = frame.callee_offset; + poly_int64 sve_callee_adjust = frame.sve_callee_adjust; +- poly_int64 below_hard_fp_saved_regs_size +- = frame.below_hard_fp_saved_regs_size; ++ poly_int64 bytes_below_hard_fp = frame.bytes_below_hard_fp; + unsigned reg1 = frame.wb_pop_candidate1; + unsigned reg2 = frame.wb_pop_candidate2; + unsigned int last_gpr = (frame.is_scs_enabled +@@ -9915,7 +9915,7 @@ aarch64_expand_epilogue (bool for_sibcall) + is restored on the instruction doing the writeback. */ + aarch64_add_offset (Pmode, stack_pointer_rtx, + hard_frame_pointer_rtx, +- -callee_offset - below_hard_fp_saved_regs_size, ++ -bytes_below_hard_fp + final_adjust, + tmp1_rtx, tmp0_rtx, callee_adjust == 0); + else + /* The case where we need to re-use the register here is very rare, so +diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h +index 1e105e12db8..de68ff7202f 100644 +--- a/gcc/config/aarch64/aarch64.h ++++ b/gcc/config/aarch64/aarch64.h +@@ -880,6 +880,11 @@ struct GTY (()) aarch64_frame + are saved below the hard frame pointer. */ + poly_int64 below_hard_fp_saved_regs_size; + ++ /* The number of bytes between the bottom of the static frame (the bottom ++ of the outgoing arguments) and the hard frame pointer. This value is ++ always a multiple of STACK_BOUNDARY. */ ++ poly_int64 bytes_below_hard_fp; ++ + /* Offset from the base of the frame (incomming SP) to the + top of the locals area. This value is always a multiple of + STACK_BOUNDARY. */ +-- +2.25.1 + + +From e3d2e1cb16683c649530d61e57bd7b37432f8375 Mon Sep 17 00:00:00 2001 +From: Richard Sandiford +Date: Tue, 27 Jun 2023 11:21:41 +0100 +Subject: [PATCH 06/19] aarch64: Tweak aarch64_save/restore_callee_saves +To: gcc-patches@gcc.gnu.org + +aarch64_save_callee_saves and aarch64_restore_callee_saves took +a parameter called start_offset that gives the offset of the +bottom of the saved register area from the current stack pointer. +However, it's more convenient for later patches if we use the +bottom of the entire frame as the reference point, rather than +the bottom of the saved registers. + +Doing that removes the need for the callee_offset field. +Other than that, this is not a win on its own. It only really +makes sense in combination with the follow-on patches. + +gcc/ + * config/aarch64/aarch64.h (aarch64_frame::callee_offset): Delete. + * config/aarch64/aarch64.cc (aarch64_layout_frame): Remove + callee_offset handling. + (aarch64_save_callee_saves): Replace the start_offset parameter + with a bytes_below_sp parameter. + (aarch64_restore_callee_saves): Likewise. + (aarch64_expand_prologue): Update accordingly. + (aarch64_expand_epilogue): Likewise. +--- + gcc/config/aarch64/aarch64.cc | 56 +++++++++++++++++------------------ + gcc/config/aarch64/aarch64.h | 4 --- + 2 files changed, 28 insertions(+), 32 deletions(-) + +diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc +index c7d84245fbf..e79551af41d 100644 +--- a/gcc/config/aarch64/aarch64.cc ++++ b/gcc/config/aarch64/aarch64.cc +@@ -8343,7 +8343,6 @@ aarch64_layout_frame (void) + frame.final_adjust = 0; + frame.callee_adjust = 0; + frame.sve_callee_adjust = 0; +- frame.callee_offset = 0; + + frame.wb_pop_candidate1 = frame.wb_push_candidate1; + frame.wb_pop_candidate2 = frame.wb_push_candidate2; +@@ -8411,7 +8410,6 @@ aarch64_layout_frame (void) + stp reg1, reg2, [sp, bytes_below_saved_regs] + stp reg3, reg4, [sp, bytes_below_saved_regs + 16] */ + frame.initial_adjust = frame.frame_size; +- frame.callee_offset = const_below_saved_regs; + } + else if (saves_below_hard_fp_p + && known_eq (frame.saved_regs_size, +@@ -8758,12 +8756,13 @@ aarch64_add_cfa_expression (rtx_insn *insn, rtx reg, + } + + /* Emit code to save the callee-saved registers from register number START +- to LIMIT to the stack at the location starting at offset START_OFFSET, +- skipping any write-back candidates if SKIP_WB is true. HARD_FP_VALID_P +- is true if the hard frame pointer has been set up. */ ++ to LIMIT to the stack. The stack pointer is currently BYTES_BELOW_SP ++ bytes above the bottom of the static frame. Skip any write-back ++ candidates if SKIP_WB is true. HARD_FP_VALID_P is true if the hard ++ frame pointer has been set up. */ + + static void +-aarch64_save_callee_saves (poly_int64 start_offset, ++aarch64_save_callee_saves (poly_int64 bytes_below_sp, + unsigned start, unsigned limit, bool skip_wb, + bool hard_fp_valid_p) + { +@@ -8791,7 +8790,9 @@ aarch64_save_callee_saves (poly_int64 start_offset, + + machine_mode mode = aarch64_reg_save_mode (regno); + reg = gen_rtx_REG (mode, regno); +- offset = start_offset + frame.reg_offset[regno]; ++ offset = (frame.reg_offset[regno] ++ + frame.bytes_below_saved_regs ++ - bytes_below_sp); + rtx base_rtx = stack_pointer_rtx; + poly_int64 sp_offset = offset; + +@@ -8802,9 +8803,7 @@ aarch64_save_callee_saves (poly_int64 start_offset, + else if (GP_REGNUM_P (regno) + && (!offset.is_constant (&const_offset) || const_offset >= 512)) + { +- gcc_assert (known_eq (start_offset, 0)); +- poly_int64 fp_offset +- = frame.below_hard_fp_saved_regs_size; ++ poly_int64 fp_offset = frame.bytes_below_hard_fp - bytes_below_sp; + if (hard_fp_valid_p) + base_rtx = hard_frame_pointer_rtx; + else +@@ -8868,12 +8867,13 @@ aarch64_save_callee_saves (poly_int64 start_offset, + } + + /* Emit code to restore the callee registers from register number START +- up to and including LIMIT. Restore from the stack offset START_OFFSET, +- skipping any write-back candidates if SKIP_WB is true. Write the +- appropriate REG_CFA_RESTORE notes into CFI_OPS. */ ++ up to and including LIMIT. The stack pointer is currently BYTES_BELOW_SP ++ bytes above the bottom of the static frame. Skip any write-back ++ candidates if SKIP_WB is true. Write the appropriate REG_CFA_RESTORE ++ notes into CFI_OPS. */ + + static void +-aarch64_restore_callee_saves (poly_int64 start_offset, unsigned start, ++aarch64_restore_callee_saves (poly_int64 bytes_below_sp, unsigned start, + unsigned limit, bool skip_wb, rtx *cfi_ops) + { + aarch64_frame &frame = cfun->machine->frame; +@@ -8899,7 +8899,9 @@ aarch64_restore_callee_saves (poly_int64 start_offset, unsigned start, + + machine_mode mode = aarch64_reg_save_mode (regno); + reg = gen_rtx_REG (mode, regno); +- offset = start_offset + frame.reg_offset[regno]; ++ offset = (frame.reg_offset[regno] ++ + frame.bytes_below_saved_regs ++ - bytes_below_sp); + rtx base_rtx = stack_pointer_rtx; + if (mode == VNx2DImode && BYTES_BIG_ENDIAN) + aarch64_adjust_sve_callee_save_base (mode, base_rtx, anchor_reg, +@@ -9675,8 +9677,6 @@ aarch64_expand_prologue (void) + HOST_WIDE_INT callee_adjust = frame.callee_adjust; + poly_int64 final_adjust = frame.final_adjust; + poly_int64 sve_callee_adjust = frame.sve_callee_adjust; +- poly_int64 below_hard_fp_saved_regs_size +- = frame.below_hard_fp_saved_regs_size; + unsigned reg1 = frame.wb_push_candidate1; + unsigned reg2 = frame.wb_push_candidate2; + bool emit_frame_chain = frame.emit_frame_chain; +@@ -9752,8 +9752,8 @@ aarch64_expand_prologue (void) + - frame.hard_fp_offset); + gcc_assert (known_ge (chain_offset, 0)); + +- /* The offset of the bottom of the save area from the current SP. */ +- poly_int64 saved_regs_offset = chain_offset - below_hard_fp_saved_regs_size; ++ /* The offset of the current SP from the bottom of the static frame. */ ++ poly_int64 bytes_below_sp = frame_size - initial_adjust - callee_adjust; + + if (emit_frame_chain) + { +@@ -9761,7 +9761,7 @@ aarch64_expand_prologue (void) + { + reg1 = R29_REGNUM; + reg2 = R30_REGNUM; +- aarch64_save_callee_saves (saved_regs_offset, reg1, reg2, ++ aarch64_save_callee_saves (bytes_below_sp, reg1, reg2, + false, false); + } + else +@@ -9801,7 +9801,7 @@ aarch64_expand_prologue (void) + emit_insn (gen_stack_tie (stack_pointer_rtx, hard_frame_pointer_rtx)); + } + +- aarch64_save_callee_saves (saved_regs_offset, R0_REGNUM, R30_REGNUM, ++ aarch64_save_callee_saves (bytes_below_sp, R0_REGNUM, R30_REGNUM, + callee_adjust != 0 || emit_frame_chain, + emit_frame_chain); + if (maybe_ne (sve_callee_adjust, 0)) +@@ -9811,16 +9811,17 @@ aarch64_expand_prologue (void) + aarch64_allocate_and_probe_stack_space (tmp1_rtx, tmp0_rtx, + sve_callee_adjust, + !frame_pointer_needed, false); +- saved_regs_offset += sve_callee_adjust; ++ bytes_below_sp -= sve_callee_adjust; + } +- aarch64_save_callee_saves (saved_regs_offset, P0_REGNUM, P15_REGNUM, ++ aarch64_save_callee_saves (bytes_below_sp, P0_REGNUM, P15_REGNUM, + false, emit_frame_chain); +- aarch64_save_callee_saves (saved_regs_offset, V0_REGNUM, V31_REGNUM, ++ aarch64_save_callee_saves (bytes_below_sp, V0_REGNUM, V31_REGNUM, + callee_adjust != 0 || emit_frame_chain, + emit_frame_chain); + + /* We may need to probe the final adjustment if it is larger than the guard + that is assumed by the called. */ ++ gcc_assert (known_eq (bytes_below_sp, final_adjust)); + aarch64_allocate_and_probe_stack_space (tmp1_rtx, tmp0_rtx, final_adjust, + !frame_pointer_needed, true); + } +@@ -9855,7 +9856,6 @@ aarch64_expand_epilogue (bool for_sibcall) + poly_int64 initial_adjust = frame.initial_adjust; + HOST_WIDE_INT callee_adjust = frame.callee_adjust; + poly_int64 final_adjust = frame.final_adjust; +- poly_int64 callee_offset = frame.callee_offset; + poly_int64 sve_callee_adjust = frame.sve_callee_adjust; + poly_int64 bytes_below_hard_fp = frame.bytes_below_hard_fp; + unsigned reg1 = frame.wb_pop_candidate1; +@@ -9925,9 +9925,9 @@ aarch64_expand_epilogue (bool for_sibcall) + + /* Restore the vector registers before the predicate registers, + so that we can use P4 as a temporary for big-endian SVE frames. */ +- aarch64_restore_callee_saves (callee_offset, V0_REGNUM, V31_REGNUM, ++ aarch64_restore_callee_saves (final_adjust, V0_REGNUM, V31_REGNUM, + callee_adjust != 0, &cfi_ops); +- aarch64_restore_callee_saves (callee_offset, P0_REGNUM, P15_REGNUM, ++ aarch64_restore_callee_saves (final_adjust, P0_REGNUM, P15_REGNUM, + false, &cfi_ops); + if (maybe_ne (sve_callee_adjust, 0)) + aarch64_add_sp (NULL_RTX, NULL_RTX, sve_callee_adjust, true); +@@ -9935,7 +9935,7 @@ aarch64_expand_epilogue (bool for_sibcall) + /* When shadow call stack is enabled, the scs_pop in the epilogue will + restore x30, we don't need to restore x30 again in the traditional + way. */ +- aarch64_restore_callee_saves (callee_offset - sve_callee_adjust, ++ aarch64_restore_callee_saves (final_adjust + sve_callee_adjust, + R0_REGNUM, last_gpr, + callee_adjust != 0, &cfi_ops); + +diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h +index de68ff7202f..94fca4b9471 100644 +--- a/gcc/config/aarch64/aarch64.h ++++ b/gcc/config/aarch64/aarch64.h +@@ -907,10 +907,6 @@ struct GTY (()) aarch64_frame + It is zero when no push is used. */ + HOST_WIDE_INT callee_adjust; + +- /* The offset from SP to the callee-save registers after initial_adjust. +- It may be non-zero if no push is used (ie. callee_adjust == 0). */ +- poly_int64 callee_offset; +- + /* The size of the stack adjustment before saving or after restoring + SVE registers. */ + poly_int64 sve_callee_adjust; +-- +2.25.1 + + +From 86048f5108891ce1212fcf70581271be51ab5d52 Mon Sep 17 00:00:00 2001 +From: Richard Sandiford +Date: Tue, 27 Jun 2023 11:24:27 +0100 +Subject: [PATCH 07/19] aarch64: Only calculate chain_offset if there is a + chain +To: gcc-patches@gcc.gnu.org + +After previous patches, it is no longer necessary to calculate +a chain_offset in cases where there is no chain record. + +gcc/ + * config/aarch64/aarch64.cc (aarch64_expand_prologue): Move the + calculation of chain_offset into the emit_frame_chain block. +--- + gcc/config/aarch64/aarch64.cc | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc +index e79551af41d..d71a042d611 100644 +--- a/gcc/config/aarch64/aarch64.cc ++++ b/gcc/config/aarch64/aarch64.cc +@@ -9747,16 +9747,16 @@ aarch64_expand_prologue (void) + if (callee_adjust != 0) + aarch64_push_regs (reg1, reg2, callee_adjust); + +- /* The offset of the frame chain record (if any) from the current SP. */ +- poly_int64 chain_offset = (initial_adjust + callee_adjust +- - frame.hard_fp_offset); +- gcc_assert (known_ge (chain_offset, 0)); +- + /* The offset of the current SP from the bottom of the static frame. */ + poly_int64 bytes_below_sp = frame_size - initial_adjust - callee_adjust; + + if (emit_frame_chain) + { ++ /* The offset of the frame chain record (if any) from the current SP. */ ++ poly_int64 chain_offset = (initial_adjust + callee_adjust ++ - frame.hard_fp_offset); ++ gcc_assert (known_ge (chain_offset, 0)); ++ + if (callee_adjust == 0) + { + reg1 = R29_REGNUM; +-- +2.25.1 + + +From 4517a341046e718167474ef8326fa0e13dca015a Mon Sep 17 00:00:00 2001 +From: Richard Sandiford +Date: Tue, 27 Jun 2023 11:25:40 +0100 +Subject: [PATCH 08/19] aarch64: Rename locals_offset to bytes_above_locals +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +To: gcc-patches@gcc.gnu.org + +locals_offset was described as: + + /* Offset from the base of the frame (incomming SP) to the + top of the locals area. This value is always a multiple of + STACK_BOUNDARY. */ + +This is implicitly an “upside down” view of the frame: the incoming +SP is at offset 0, and anything N bytes below the incoming SP is at +offset N (rather than -N). + +However, reg_offset instead uses a “right way up” view; that is, +it views offsets in address terms. Something above X is at a +positive offset from X and something below X is at a negative +offset from X. + +Also, even on FRAME_GROWS_DOWNWARD targets like AArch64, +target-independent code views offsets in address terms too: +locals are allocated at negative offsets to virtual_stack_vars. + +It seems confusing to have *_offset fields of the same structure +using different polarities like this. This patch tries to avoid +that by renaming locals_offset to bytes_above_locals. + +gcc/ + * config/aarch64/aarch64.h (aarch64_frame::locals_offset): Rename to... + (aarch64_frame::bytes_above_locals): ...this. + * config/aarch64/aarch64.cc (aarch64_layout_frame) + (aarch64_initial_elimination_offset): Update accordingly. +--- + gcc/config/aarch64/aarch64.cc | 6 +++--- + gcc/config/aarch64/aarch64.h | 6 +++--- + 2 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc +index d71a042d611..d4ec352ba98 100644 +--- a/gcc/config/aarch64/aarch64.cc ++++ b/gcc/config/aarch64/aarch64.cc +@@ -8337,7 +8337,7 @@ aarch64_layout_frame (void) + STACK_BOUNDARY / BITS_PER_UNIT)); + frame.frame_size = saved_regs_and_above + frame.bytes_below_saved_regs; + +- frame.locals_offset = frame.saved_varargs_size; ++ frame.bytes_above_locals = frame.saved_varargs_size; + + frame.initial_adjust = 0; + frame.final_adjust = 0; +@@ -12578,13 +12578,13 @@ aarch64_initial_elimination_offset (unsigned from, unsigned to) + return frame.hard_fp_offset; + + if (from == FRAME_POINTER_REGNUM) +- return frame.hard_fp_offset - frame.locals_offset; ++ return frame.hard_fp_offset - frame.bytes_above_locals; + } + + if (to == STACK_POINTER_REGNUM) + { + if (from == FRAME_POINTER_REGNUM) +- return frame.frame_size - frame.locals_offset; ++ return frame.frame_size - frame.bytes_above_locals; + } + + return frame.frame_size; +diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h +index 94fca4b9471..bf46e6124aa 100644 +--- a/gcc/config/aarch64/aarch64.h ++++ b/gcc/config/aarch64/aarch64.h +@@ -885,10 +885,10 @@ struct GTY (()) aarch64_frame + always a multiple of STACK_BOUNDARY. */ + poly_int64 bytes_below_hard_fp; + +- /* Offset from the base of the frame (incomming SP) to the +- top of the locals area. This value is always a multiple of ++ /* The number of bytes between the top of the locals area and the top ++ of the frame (the incomming SP). This value is always a multiple of + STACK_BOUNDARY. */ +- poly_int64 locals_offset; ++ poly_int64 bytes_above_locals; + + /* Offset from the base of the frame (incomming SP) to the + hard_frame_pointer. This value is always a multiple of +-- +2.25.1 + + +From 2b827d24ce5c5a4da9993c648d3a6329e38c344a Mon Sep 17 00:00:00 2001 +From: Richard Sandiford +Date: Tue, 27 Jun 2023 11:28:11 +0100 +Subject: [PATCH 09/19] aarch64: Rename hard_fp_offset to bytes_above_hard_fp +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +To: gcc-patches@gcc.gnu.org + +Similarly to the previous locals_offset patch, hard_fp_offset +was described as: + + /* Offset from the base of the frame (incomming SP) to the + hard_frame_pointer. This value is always a multiple of + STACK_BOUNDARY. */ + poly_int64 hard_fp_offset; + +which again took an “upside-down” view: higher offsets meant lower +addresses. This patch renames the field to bytes_above_hard_fp instead. + +gcc/ + * config/aarch64/aarch64.h (aarch64_frame::hard_fp_offset): Rename + to... + (aarch64_frame::bytes_above_hard_fp): ...this. + * config/aarch64/aarch64.cc (aarch64_layout_frame) + (aarch64_expand_prologue): Update accordingly. + (aarch64_initial_elimination_offset): Likewise. +--- + gcc/config/aarch64/aarch64.cc | 26 +++++++++++++------------- + gcc/config/aarch64/aarch64.h | 6 +++--- + 2 files changed, 16 insertions(+), 16 deletions(-) + +diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc +index d4ec352ba98..3c4052740e7 100644 +--- a/gcc/config/aarch64/aarch64.cc ++++ b/gcc/config/aarch64/aarch64.cc +@@ -8329,7 +8329,7 @@ aarch64_layout_frame (void) + + get_frame_size (), + STACK_BOUNDARY / BITS_PER_UNIT); + +- frame.hard_fp_offset ++ frame.bytes_above_hard_fp + = saved_regs_and_above - frame.below_hard_fp_saved_regs_size; + + /* Both these values are already aligned. */ +@@ -8378,13 +8378,13 @@ aarch64_layout_frame (void) + else if (frame.wb_pop_candidate1 != INVALID_REGNUM) + max_push_offset = 256; + +- HOST_WIDE_INT const_size, const_below_saved_regs, const_fp_offset; ++ HOST_WIDE_INT const_size, const_below_saved_regs, const_above_fp; + HOST_WIDE_INT const_saved_regs_size; + if (known_eq (frame.saved_regs_size, 0)) + frame.initial_adjust = frame.frame_size; + else if (frame.frame_size.is_constant (&const_size) + && const_size < max_push_offset +- && known_eq (frame.hard_fp_offset, const_size)) ++ && known_eq (frame.bytes_above_hard_fp, const_size)) + { + /* Simple, small frame with no data below the saved registers. + +@@ -8401,8 +8401,8 @@ aarch64_layout_frame (void) + case that it hardly seems worth the effort though. */ + && (!saves_below_hard_fp_p || const_below_saved_regs == 0) + && !(cfun->calls_alloca +- && frame.hard_fp_offset.is_constant (&const_fp_offset) +- && const_fp_offset < max_push_offset)) ++ && frame.bytes_above_hard_fp.is_constant (&const_above_fp) ++ && const_above_fp < max_push_offset)) + { + /* Frame with small area below the saved registers: + +@@ -8420,12 +8420,12 @@ aarch64_layout_frame (void) + sub sp, sp, hard_fp_offset + below_hard_fp_saved_regs_size + save SVE registers relative to SP + sub sp, sp, bytes_below_saved_regs */ +- frame.initial_adjust = (frame.hard_fp_offset ++ frame.initial_adjust = (frame.bytes_above_hard_fp + + frame.below_hard_fp_saved_regs_size); + frame.final_adjust = frame.bytes_below_saved_regs; + } +- else if (frame.hard_fp_offset.is_constant (&const_fp_offset) +- && const_fp_offset < max_push_offset) ++ else if (frame.bytes_above_hard_fp.is_constant (&const_above_fp) ++ && const_above_fp < max_push_offset) + { + /* Frame with large area below the saved registers, or with SVE saves, + but with a small area above: +@@ -8435,7 +8435,7 @@ aarch64_layout_frame (void) + [sub sp, sp, below_hard_fp_saved_regs_size] + [save SVE registers relative to SP] + sub sp, sp, bytes_below_saved_regs */ +- frame.callee_adjust = const_fp_offset; ++ frame.callee_adjust = const_above_fp; + frame.sve_callee_adjust = frame.below_hard_fp_saved_regs_size; + frame.final_adjust = frame.bytes_below_saved_regs; + } +@@ -8450,7 +8450,7 @@ aarch64_layout_frame (void) + [sub sp, sp, below_hard_fp_saved_regs_size] + [save SVE registers relative to SP] + sub sp, sp, bytes_below_saved_regs */ +- frame.initial_adjust = frame.hard_fp_offset; ++ frame.initial_adjust = frame.bytes_above_hard_fp; + frame.sve_callee_adjust = frame.below_hard_fp_saved_regs_size; + frame.final_adjust = frame.bytes_below_saved_regs; + } +@@ -9754,7 +9754,7 @@ aarch64_expand_prologue (void) + { + /* The offset of the frame chain record (if any) from the current SP. */ + poly_int64 chain_offset = (initial_adjust + callee_adjust +- - frame.hard_fp_offset); ++ - frame.bytes_above_hard_fp); + gcc_assert (known_ge (chain_offset, 0)); + + if (callee_adjust == 0) +@@ -12575,10 +12575,10 @@ aarch64_initial_elimination_offset (unsigned from, unsigned to) + if (to == HARD_FRAME_POINTER_REGNUM) + { + if (from == ARG_POINTER_REGNUM) +- return frame.hard_fp_offset; ++ return frame.bytes_above_hard_fp; + + if (from == FRAME_POINTER_REGNUM) +- return frame.hard_fp_offset - frame.bytes_above_locals; ++ return frame.bytes_above_hard_fp - frame.bytes_above_locals; + } + + if (to == STACK_POINTER_REGNUM) +diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h +index bf46e6124aa..dd1f403f939 100644 +--- a/gcc/config/aarch64/aarch64.h ++++ b/gcc/config/aarch64/aarch64.h +@@ -890,10 +890,10 @@ struct GTY (()) aarch64_frame + STACK_BOUNDARY. */ + poly_int64 bytes_above_locals; + +- /* Offset from the base of the frame (incomming SP) to the +- hard_frame_pointer. This value is always a multiple of ++ /* The number of bytes between the hard_frame_pointer and the top of ++ the frame (the incomming SP). This value is always a multiple of + STACK_BOUNDARY. */ +- poly_int64 hard_fp_offset; ++ poly_int64 bytes_above_hard_fp; + + /* The size of the frame. This value is the offset from base of the + frame (incomming SP) to the stack_pointer. This value is always +-- +2.25.1 + + +From e66dc224e1acf84c08764bdc5aeaff12c5c61d17 Mon Sep 17 00:00:00 2001 +From: Richard Sandiford +Date: Thu, 22 Jun 2023 22:26:30 +0100 +Subject: [PATCH 10/19] aarch64: Tweak frame_size comment +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +To: gcc-patches@gcc.gnu.org + +This patch fixes another case in which a value was described with +an “upside-down” view. + +gcc/ + * config/aarch64/aarch64.h (aarch64_frame::frame_size): Tweak comment. +--- + gcc/config/aarch64/aarch64.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h +index dd1f403f939..700524ae22b 100644 +--- a/gcc/config/aarch64/aarch64.h ++++ b/gcc/config/aarch64/aarch64.h +@@ -895,8 +895,8 @@ struct GTY (()) aarch64_frame + STACK_BOUNDARY. */ + poly_int64 bytes_above_hard_fp; + +- /* The size of the frame. This value is the offset from base of the +- frame (incomming SP) to the stack_pointer. This value is always ++ /* The size of the frame, i.e. the number of bytes between the bottom ++ of the outgoing arguments and the incoming SP. This value is always + a multiple of STACK_BOUNDARY. */ + poly_int64 frame_size; + +-- +2.25.1 + + +From 90b1e92da59ee70f017c84e3bdcd66eaffaac651 Mon Sep 17 00:00:00 2001 +From: Richard Sandiford +Date: Tue, 27 Jun 2023 11:36:08 +0100 +Subject: [PATCH 11/19] aarch64: Measure reg_offset from the bottom of the + frame +To: gcc-patches@gcc.gnu.org + +reg_offset was measured from the bottom of the saved register area. +This made perfect sense with the original layout, since the bottom +of the saved register area was also the hard frame pointer address. +It became slightly less obvious with SVE, since we save SVE +registers below the hard frame pointer, but it still made sense. + +However, if we want to allow different frame layouts, it's more +convenient and obvious to measure reg_offset from the bottom of +the frame. After previous patches, it's also a slight simplification +in its own right. + +gcc/ + * config/aarch64/aarch64.h (aarch64_frame): Add comment above + reg_offset. + * config/aarch64/aarch64.cc (aarch64_layout_frame): Walk offsets + from the bottom of the frame, rather than the bottom of the saved + register area. Measure reg_offset from the bottom of the frame + rather than the bottom of the saved register area. + (aarch64_save_callee_saves): Update accordingly. + (aarch64_restore_callee_saves): Likewise. + (aarch64_get_separate_components): Likewise. + (aarch64_process_components): Likewise. +--- + gcc/config/aarch64/aarch64.cc | 53 ++++++++++++++++------------------- + gcc/config/aarch64/aarch64.h | 3 ++ + 2 files changed, 27 insertions(+), 29 deletions(-) + +diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc +index 3c4052740e7..97dd077844b 100644 +--- a/gcc/config/aarch64/aarch64.cc ++++ b/gcc/config/aarch64/aarch64.cc +@@ -8139,7 +8139,6 @@ aarch64_needs_frame_chain (void) + static void + aarch64_layout_frame (void) + { +- poly_int64 offset = 0; + int regno, last_fp_reg = INVALID_REGNUM; + machine_mode vector_save_mode = aarch64_reg_save_mode (V8_REGNUM); + poly_int64 vector_save_size = GET_MODE_SIZE (vector_save_mode); +@@ -8217,7 +8216,9 @@ aarch64_layout_frame (void) + gcc_assert (crtl->is_leaf + || maybe_ne (frame.reg_offset[R30_REGNUM], SLOT_NOT_REQUIRED)); + +- frame.bytes_below_saved_regs = crtl->outgoing_args_size; ++ poly_int64 offset = crtl->outgoing_args_size; ++ gcc_assert (multiple_p (offset, STACK_BOUNDARY / BITS_PER_UNIT)); ++ frame.bytes_below_saved_regs = offset; + + /* Now assign stack slots for the registers. Start with the predicate + registers, since predicate LDR and STR have a relatively small +@@ -8229,7 +8230,8 @@ aarch64_layout_frame (void) + offset += BYTES_PER_SVE_PRED; + } + +- if (maybe_ne (offset, 0)) ++ poly_int64 saved_prs_size = offset - frame.bytes_below_saved_regs; ++ if (maybe_ne (saved_prs_size, 0)) + { + /* If we have any vector registers to save above the predicate registers, + the offset of the vector register save slots need to be a multiple +@@ -8247,10 +8249,10 @@ aarch64_layout_frame (void) + offset = aligned_upper_bound (offset, STACK_BOUNDARY / BITS_PER_UNIT); + else + { +- if (known_le (offset, vector_save_size)) +- offset = vector_save_size; +- else if (known_le (offset, vector_save_size * 2)) +- offset = vector_save_size * 2; ++ if (known_le (saved_prs_size, vector_save_size)) ++ offset = frame.bytes_below_saved_regs + vector_save_size; ++ else if (known_le (saved_prs_size, vector_save_size * 2)) ++ offset = frame.bytes_below_saved_regs + vector_save_size * 2; + else + gcc_unreachable (); + } +@@ -8267,9 +8269,10 @@ aarch64_layout_frame (void) + + /* OFFSET is now the offset of the hard frame pointer from the bottom + of the callee save area. */ +- bool saves_below_hard_fp_p = maybe_ne (offset, 0); +- frame.below_hard_fp_saved_regs_size = offset; +- frame.bytes_below_hard_fp = offset + frame.bytes_below_saved_regs; ++ frame.below_hard_fp_saved_regs_size = offset - frame.bytes_below_saved_regs; ++ bool saves_below_hard_fp_p ++ = maybe_ne (frame.below_hard_fp_saved_regs_size, 0); ++ frame.bytes_below_hard_fp = offset; + if (frame.emit_frame_chain) + { + /* FP and LR are placed in the linkage record. */ +@@ -8320,9 +8323,10 @@ aarch64_layout_frame (void) + + offset = aligned_upper_bound (offset, STACK_BOUNDARY / BITS_PER_UNIT); + +- frame.saved_regs_size = offset; ++ frame.saved_regs_size = offset - frame.bytes_below_saved_regs; + +- poly_int64 varargs_and_saved_regs_size = offset + frame.saved_varargs_size; ++ poly_int64 varargs_and_saved_regs_size ++ = frame.saved_regs_size + frame.saved_varargs_size; + + poly_int64 saved_regs_and_above + = aligned_upper_bound (varargs_and_saved_regs_size +@@ -8790,9 +8794,7 @@ aarch64_save_callee_saves (poly_int64 bytes_below_sp, + + machine_mode mode = aarch64_reg_save_mode (regno); + reg = gen_rtx_REG (mode, regno); +- offset = (frame.reg_offset[regno] +- + frame.bytes_below_saved_regs +- - bytes_below_sp); ++ offset = frame.reg_offset[regno] - bytes_below_sp; + rtx base_rtx = stack_pointer_rtx; + poly_int64 sp_offset = offset; + +@@ -8899,9 +8901,7 @@ aarch64_restore_callee_saves (poly_int64 bytes_below_sp, unsigned start, + + machine_mode mode = aarch64_reg_save_mode (regno); + reg = gen_rtx_REG (mode, regno); +- offset = (frame.reg_offset[regno] +- + frame.bytes_below_saved_regs +- - bytes_below_sp); ++ offset = frame.reg_offset[regno] - bytes_below_sp; + rtx base_rtx = stack_pointer_rtx; + if (mode == VNx2DImode && BYTES_BIG_ENDIAN) + aarch64_adjust_sve_callee_save_base (mode, base_rtx, anchor_reg, +@@ -9040,14 +9040,12 @@ aarch64_get_separate_components (void) + it as a stack probe for -fstack-clash-protection. */ + if (flag_stack_clash_protection + && maybe_ne (frame.below_hard_fp_saved_regs_size, 0) +- && known_eq (offset, 0)) ++ && known_eq (offset, frame.bytes_below_saved_regs)) + continue; + + /* Get the offset relative to the register we'll use. */ + if (frame_pointer_needed) +- offset -= frame.below_hard_fp_saved_regs_size; +- else +- offset += frame.bytes_below_saved_regs; ++ offset -= frame.bytes_below_hard_fp; + + /* Check that we can access the stack slot of the register with one + direct load with no adjustments needed. */ +@@ -9194,9 +9192,7 @@ aarch64_process_components (sbitmap components, bool prologue_p) + rtx reg = gen_rtx_REG (mode, regno); + poly_int64 offset = frame.reg_offset[regno]; + if (frame_pointer_needed) +- offset -= frame.below_hard_fp_saved_regs_size; +- else +- offset += frame.bytes_below_saved_regs; ++ offset -= frame.bytes_below_hard_fp; + + rtx addr = plus_constant (Pmode, ptr_reg, offset); + rtx mem = gen_frame_mem (mode, addr); +@@ -9248,9 +9244,7 @@ aarch64_process_components (sbitmap components, bool prologue_p) + /* REGNO2 can be saved/restored in a pair with REGNO. */ + rtx reg2 = gen_rtx_REG (mode, regno2); + if (frame_pointer_needed) +- offset2 -= frame.below_hard_fp_saved_regs_size; +- else +- offset2 += frame.bytes_below_saved_regs; ++ offset2 -= frame.bytes_below_hard_fp; + rtx addr2 = plus_constant (Pmode, ptr_reg, offset2); + rtx mem2 = gen_frame_mem (mode, addr2); + rtx set2 = prologue_p ? gen_rtx_SET (mem2, reg2) +@@ -9366,7 +9360,8 @@ aarch64_allocate_and_probe_stack_space (rtx temp1, rtx temp2, + if (final_adjustment_p + && known_eq (frame.below_hard_fp_saved_regs_size, 0)) + { +- poly_int64 lr_offset = frame.reg_offset[LR_REGNUM]; ++ poly_int64 lr_offset = (frame.reg_offset[LR_REGNUM] ++ - frame.bytes_below_saved_regs); + if (known_ge (lr_offset, 0)) + min_probe_threshold -= lr_offset.to_constant (); + else +diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h +index 700524ae22b..b6135837073 100644 +--- a/gcc/config/aarch64/aarch64.h ++++ b/gcc/config/aarch64/aarch64.h +@@ -860,6 +860,9 @@ extern enum aarch64_processor aarch64_tune; + #ifdef HAVE_POLY_INT_H + struct GTY (()) aarch64_frame + { ++ /* The offset from the bottom of the static frame (the bottom of the ++ outgoing arguments) of each register save slot, or -2 if no save is ++ needed. */ + poly_int64 reg_offset[LAST_SAVED_REGNUM + 1]; + + /* The number of extra stack bytes taken up by register varargs. +-- +2.25.1 + + +From e50a9f7cc0214baf1395202418967bc89e3e7ac7 Mon Sep 17 00:00:00 2001 +From: Richard Sandiford +Date: Fri, 16 Jun 2023 17:44:39 +0100 +Subject: [PATCH 12/19] aarch64: Simplify top of frame allocation +To: gcc-patches@gcc.gnu.org + +After previous patches, it no longer really makes sense to allocate +the top of the frame in terms of varargs_and_saved_regs_size and +saved_regs_and_above. + +gcc/ + * config/aarch64/aarch64.cc (aarch64_layout_frame): Simplify + the allocation of the top of the frame. +--- + gcc/config/aarch64/aarch64.cc | 23 ++++++++--------------- + 1 file changed, 8 insertions(+), 15 deletions(-) + +diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc +index 97dd077844b..81935852d5b 100644 +--- a/gcc/config/aarch64/aarch64.cc ++++ b/gcc/config/aarch64/aarch64.cc +@@ -8325,23 +8325,16 @@ aarch64_layout_frame (void) + + frame.saved_regs_size = offset - frame.bytes_below_saved_regs; + +- poly_int64 varargs_and_saved_regs_size +- = frame.saved_regs_size + frame.saved_varargs_size; +- +- poly_int64 saved_regs_and_above +- = aligned_upper_bound (varargs_and_saved_regs_size +- + get_frame_size (), +- STACK_BOUNDARY / BITS_PER_UNIT); +- +- frame.bytes_above_hard_fp +- = saved_regs_and_above - frame.below_hard_fp_saved_regs_size; ++ offset += get_frame_size (); ++ offset = aligned_upper_bound (offset, STACK_BOUNDARY / BITS_PER_UNIT); ++ auto top_of_locals = offset; + +- /* Both these values are already aligned. */ +- gcc_assert (multiple_p (frame.bytes_below_saved_regs, +- STACK_BOUNDARY / BITS_PER_UNIT)); +- frame.frame_size = saved_regs_and_above + frame.bytes_below_saved_regs; ++ offset += frame.saved_varargs_size; ++ gcc_assert (multiple_p (offset, STACK_BOUNDARY / BITS_PER_UNIT)); ++ frame.frame_size = offset; + +- frame.bytes_above_locals = frame.saved_varargs_size; ++ frame.bytes_above_hard_fp = frame.frame_size - frame.bytes_below_hard_fp; ++ frame.bytes_above_locals = frame.frame_size - top_of_locals; + + frame.initial_adjust = 0; + frame.final_adjust = 0; +-- +2.25.1 + + +From 0653f7c3edd49796d7cdd84bb0f98c8b875a94a2 Mon Sep 17 00:00:00 2001 +From: Richard Sandiford +Date: Thu, 22 Jun 2023 22:18:45 +0100 +Subject: [PATCH 13/19] aarch64: Minor initial adjustment tweak +To: gcc-patches@gcc.gnu.org + +This patch just changes a calculation of initial_adjust +to one that makes it slightly more obvious that the total +adjustment is frame.frame_size. + +gcc/ + * config/aarch64/aarch64.cc (aarch64_layout_frame): Tweak + calculation of initial_adjust for frames in which all saves + are SVE saves. +--- + gcc/config/aarch64/aarch64.cc | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc +index 81935852d5b..4d9fcf3d162 100644 +--- a/gcc/config/aarch64/aarch64.cc ++++ b/gcc/config/aarch64/aarch64.cc +@@ -8414,11 +8414,10 @@ aarch64_layout_frame (void) + { + /* Frame in which all saves are SVE saves: + +- sub sp, sp, hard_fp_offset + below_hard_fp_saved_regs_size ++ sub sp, sp, frame_size - bytes_below_saved_regs + save SVE registers relative to SP + sub sp, sp, bytes_below_saved_regs */ +- frame.initial_adjust = (frame.bytes_above_hard_fp +- + frame.below_hard_fp_saved_regs_size); ++ frame.initial_adjust = frame.frame_size - frame.bytes_below_saved_regs; + frame.final_adjust = frame.bytes_below_saved_regs; + } + else if (frame.bytes_above_hard_fp.is_constant (&const_above_fp) +-- +2.25.1 + + +From fde1c870bc885fa9dc5341e811c5eb9bad1a84b5 Mon Sep 17 00:00:00 2001 +From: Richard Sandiford +Date: Tue, 27 Jun 2023 15:11:44 +0100 +Subject: [PATCH 14/19] aarch64: Tweak stack clash boundary condition +To: gcc-patches@gcc.gnu.org + +The AArch64 ABI says that, when stack clash protection is used, +there can be a maximum of 1KiB of unprobed space at sp on entry +to a function. Therefore, we need to probe when allocating +>= guard_size - 1KiB of data (>= rather than >). This is what +GCC does. + +If an allocation is exactly guard_size bytes, it is enough to allocate +those bytes and probe once at offset 1024. It isn't possible to use a +single probe at any other offset: higher would conmplicate later code, +by leaving more unprobed space than usual, while lower would risk +leaving an entire page unprobed. For simplicity, the code probes all +allocations at offset 1024. + +Some register saves also act as probes. If we need to allocate +more space below the last such register save probe, we need to +probe the allocation if it is > 1KiB. Again, this allocation is +then sometimes (but not always) probed at offset 1024. This sort of +allocation is currently only used for outgoing arguments, which are +rarely this big. + +However, the code also probed if this final outgoing-arguments +allocation was == 1KiB, rather than just > 1KiB. This isn't +necessary, since the register save then probes at offset 1024 +as required. Continuing to probe allocations of exactly 1KiB +would complicate later patches. + +gcc/ + * config/aarch64/aarch64.cc (aarch64_allocate_and_probe_stack_space): + Don't probe final allocations that are exactly 1KiB in size (after + unprobed space above the final allocation has been deducted). + +gcc/testsuite/ + * gcc.target/aarch64/stack-check-prologue-17.c: New test. +--- + gcc/config/aarch64/aarch64.cc | 4 +- + .../aarch64/stack-check-prologue-17.c | 55 +++++++++++++++++++ + 2 files changed, 58 insertions(+), 1 deletion(-) + create mode 100644 gcc/testsuite/gcc.target/aarch64/stack-check-prologue-17.c + +diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc +index 4d9fcf3d162..34c1d8614cd 100644 +--- a/gcc/config/aarch64/aarch64.cc ++++ b/gcc/config/aarch64/aarch64.cc +@@ -9333,9 +9333,11 @@ aarch64_allocate_and_probe_stack_space (rtx temp1, rtx temp2, + HOST_WIDE_INT guard_size + = 1 << param_stack_clash_protection_guard_size; + HOST_WIDE_INT guard_used_by_caller = STACK_CLASH_CALLER_GUARD; ++ HOST_WIDE_INT byte_sp_alignment = STACK_BOUNDARY / BITS_PER_UNIT; ++ gcc_assert (multiple_p (poly_size, byte_sp_alignment)); + HOST_WIDE_INT min_probe_threshold + = (final_adjustment_p +- ? guard_used_by_caller ++ ? guard_used_by_caller + byte_sp_alignment + : guard_size - guard_used_by_caller); + /* When doing the final adjustment for the outgoing arguments, take into + account any unprobed space there is above the current SP. There are +diff --git a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-17.c b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-17.c +new file mode 100644 +index 00000000000..0d8a25d73a2 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-17.c +@@ -0,0 +1,55 @@ ++/* { dg-options "-O2 -fstack-clash-protection -fomit-frame-pointer --param stack-clash-protection-guard-size=12" } */ ++/* { dg-final { check-function-bodies "**" "" } } */ ++ ++void f(int, ...); ++void g(); ++ ++/* ++** test1: ++** ... ++** str x30, \[sp\] ++** sub sp, sp, #1024 ++** cbnz w0, .* ++** bl g ++** ... ++*/ ++int test1(int z) { ++ __uint128_t x = 0; ++ int y[0x400]; ++ if (z) ++ { ++ f(0, 0, 0, 0, 0, 0, 0, &y, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x); ++ } ++ g(); ++ return 1; ++} ++ ++/* ++** test2: ++** ... ++** str x30, \[sp\] ++** sub sp, sp, #1040 ++** str xzr, \[sp\] ++** cbnz w0, .* ++** bl g ++** ... ++*/ ++int test2(int z) { ++ __uint128_t x = 0; ++ int y[0x400]; ++ if (z) ++ { ++ f(0, 0, 0, 0, 0, 0, 0, &y, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x); ++ } ++ g(); ++ return 1; ++} +-- +2.25.1 + + +From dd629bace6cf4f1cdddef6a90d9206e35c19551c Mon Sep 17 00:00:00 2001 +From: Richard Sandiford +Date: Tue, 27 Jun 2023 15:12:55 +0100 +Subject: [PATCH 15/19] aarch64: Put LR save probe in first 16 bytes +To: gcc-patches@gcc.gnu.org + +-fstack-clash-protection uses the save of LR as a probe for the next +allocation. The next allocation could be: + +* another part of the static frame, e.g. when allocating SVE save slots + or outgoing arguments + +* an alloca in the same function + +* an allocation made by a callee function + +However, when -fomit-frame-pointer is used, the LR save slot is placed +above the other GPR save slots. It could therefore be up to 80 bytes +above the base of the GPR save area (which is also the hard fp address). + +aarch64_allocate_and_probe_stack_space took this into account when +deciding how much subsequent space could be allocated without needing +a probe. However, it interacted badly with: + + /* If doing a small final adjustment, we always probe at offset 0. + This is done to avoid issues when LR is not at position 0 or when + the final adjustment is smaller than the probing offset. */ + else if (final_adjustment_p && rounded_size == 0) + residual_probe_offset = 0; + +which forces any allocation that is smaller than the guard page size +to be probed at offset 0 rather than the usual offset 1024. It was +therefore possible to construct cases in which we had: + +* a probe using LR at SP + 80 bytes (or some other value >= 16) +* an allocation of the guard page size - 16 bytes +* a probe at SP + 0 + +which allocates guard page size + 64 consecutive unprobed bytes. + +This patch requires the LR probe to be in the first 16 bytes of the +save area when stack clash protection is active. Doing it +unconditionally would cause code-quality regressions. + +Putting LR before other registers prevents push/pop allocation +when shadow call stacks are enabled, since LR is restored +separately from the other callee-saved registers. + +The new comment doesn't say that the probe register is required +to be LR, since a later patch removes that restriction. + +gcc/ + * config/aarch64/aarch64.cc (aarch64_layout_frame): Ensure that + the LR save slot is in the first 16 bytes of the register save area. + Only form STP/LDP push/pop candidates if both registers are valid. + (aarch64_allocate_and_probe_stack_space): Remove workaround for + when LR was not in the first 16 bytes. + +gcc/testsuite/ + * gcc.target/aarch64/stack-check-prologue-18.c: New test. + * gcc.target/aarch64/stack-check-prologue-19.c: Likewise. + * gcc.target/aarch64/stack-check-prologue-20.c: Likewise. +--- + gcc/config/aarch64/aarch64.cc | 72 ++++++------- + .../aarch64/stack-check-prologue-18.c | 100 ++++++++++++++++++ + .../aarch64/stack-check-prologue-19.c | 100 ++++++++++++++++++ + .../aarch64/stack-check-prologue-20.c | 3 + + 4 files changed, 233 insertions(+), 42 deletions(-) + create mode 100644 gcc/testsuite/gcc.target/aarch64/stack-check-prologue-18.c + create mode 100644 gcc/testsuite/gcc.target/aarch64/stack-check-prologue-19.c + create mode 100644 gcc/testsuite/gcc.target/aarch64/stack-check-prologue-20.c + +diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc +index 34c1d8614cd..16433fb70f4 100644 +--- a/gcc/config/aarch64/aarch64.cc ++++ b/gcc/config/aarch64/aarch64.cc +@@ -8273,26 +8273,34 @@ aarch64_layout_frame (void) + bool saves_below_hard_fp_p + = maybe_ne (frame.below_hard_fp_saved_regs_size, 0); + frame.bytes_below_hard_fp = offset; ++ ++ auto allocate_gpr_slot = [&](unsigned int regno) ++ { ++ frame.reg_offset[regno] = offset; ++ if (frame.wb_push_candidate1 == INVALID_REGNUM) ++ frame.wb_push_candidate1 = regno; ++ else if (frame.wb_push_candidate2 == INVALID_REGNUM) ++ frame.wb_push_candidate2 = regno; ++ offset += UNITS_PER_WORD; ++ }; ++ + if (frame.emit_frame_chain) + { + /* FP and LR are placed in the linkage record. */ +- frame.reg_offset[R29_REGNUM] = offset; +- frame.wb_push_candidate1 = R29_REGNUM; +- frame.reg_offset[R30_REGNUM] = offset + UNITS_PER_WORD; +- frame.wb_push_candidate2 = R30_REGNUM; +- offset += 2 * UNITS_PER_WORD; ++ allocate_gpr_slot (R29_REGNUM); ++ allocate_gpr_slot (R30_REGNUM); + } ++ else if (flag_stack_clash_protection ++ && known_eq (frame.reg_offset[R30_REGNUM], SLOT_REQUIRED)) ++ /* Put the LR save slot first, since it makes a good choice of probe ++ for stack clash purposes. The idea is that the link register usually ++ has to be saved before a call anyway, and so we lose little by ++ stopping it from being individually shrink-wrapped. */ ++ allocate_gpr_slot (R30_REGNUM); + + for (regno = R0_REGNUM; regno <= R30_REGNUM; regno++) + if (known_eq (frame.reg_offset[regno], SLOT_REQUIRED)) +- { +- frame.reg_offset[regno] = offset; +- if (frame.wb_push_candidate1 == INVALID_REGNUM) +- frame.wb_push_candidate1 = regno; +- else if (frame.wb_push_candidate2 == INVALID_REGNUM) +- frame.wb_push_candidate2 = regno; +- offset += UNITS_PER_WORD; +- } ++ allocate_gpr_slot (regno); + + poly_int64 max_int_offset = offset; + offset = aligned_upper_bound (offset, STACK_BOUNDARY / BITS_PER_UNIT); +@@ -8370,10 +8378,13 @@ aarch64_layout_frame (void) + max_push_offset to 0, because no registers are popped at this time, + so callee_adjust cannot be adjusted. */ + HOST_WIDE_INT max_push_offset = 0; +- if (frame.wb_pop_candidate2 != INVALID_REGNUM) +- max_push_offset = 512; +- else if (frame.wb_pop_candidate1 != INVALID_REGNUM) +- max_push_offset = 256; ++ if (frame.wb_pop_candidate1 != INVALID_REGNUM) ++ { ++ if (frame.wb_pop_candidate2 != INVALID_REGNUM) ++ max_push_offset = 512; ++ else ++ max_push_offset = 256; ++ } + + HOST_WIDE_INT const_size, const_below_saved_regs, const_above_fp; + HOST_WIDE_INT const_saved_regs_size; +@@ -9339,29 +9350,6 @@ aarch64_allocate_and_probe_stack_space (rtx temp1, rtx temp2, + = (final_adjustment_p + ? guard_used_by_caller + byte_sp_alignment + : guard_size - guard_used_by_caller); +- /* When doing the final adjustment for the outgoing arguments, take into +- account any unprobed space there is above the current SP. There are +- two cases: +- +- - When saving SVE registers below the hard frame pointer, we force +- the lowest save to take place in the prologue before doing the final +- adjustment (i.e. we don't allow the save to be shrink-wrapped). +- This acts as a probe at SP, so there is no unprobed space. +- +- - When there are no SVE register saves, we use the store of the link +- register as a probe. We can't assume that LR was saved at position 0 +- though, so treat any space below it as unprobed. */ +- if (final_adjustment_p +- && known_eq (frame.below_hard_fp_saved_regs_size, 0)) +- { +- poly_int64 lr_offset = (frame.reg_offset[LR_REGNUM] +- - frame.bytes_below_saved_regs); +- if (known_ge (lr_offset, 0)) +- min_probe_threshold -= lr_offset.to_constant (); +- else +- gcc_assert (!flag_stack_clash_protection || known_eq (poly_size, 0)); +- } +- + poly_int64 frame_size = frame.frame_size; + + /* We should always have a positive probe threshold. */ +@@ -9541,8 +9529,8 @@ aarch64_allocate_and_probe_stack_space (rtx temp1, rtx temp2, + if (final_adjustment_p && rounded_size != 0) + min_probe_threshold = 0; + /* If doing a small final adjustment, we always probe at offset 0. +- This is done to avoid issues when LR is not at position 0 or when +- the final adjustment is smaller than the probing offset. */ ++ This is done to avoid issues when the final adjustment is smaller ++ than the probing offset. */ + else if (final_adjustment_p && rounded_size == 0) + residual_probe_offset = 0; + +diff --git a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-18.c b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-18.c +new file mode 100644 +index 00000000000..82447d20fff +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-18.c +@@ -0,0 +1,100 @@ ++/* { dg-options "-O2 -fstack-clash-protection -fomit-frame-pointer --param stack-clash-protection-guard-size=12" } */ ++/* { dg-final { check-function-bodies "**" "" } } */ ++ ++void f(int, ...); ++void g(); ++ ++/* ++** test1: ++** ... ++** str x30, \[sp\] ++** sub sp, sp, #4064 ++** str xzr, \[sp\] ++** cbnz w0, .* ++** bl g ++** ... ++** str x26, \[sp, #?4128\] ++** ... ++*/ ++int test1(int z) { ++ __uint128_t x = 0; ++ int y[0x400]; ++ if (z) ++ { ++ asm volatile ("" ::: ++ "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26"); ++ f(0, 0, 0, 0, 0, 0, 0, &y, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x); ++ } ++ g(); ++ return 1; ++} ++ ++/* ++** test2: ++** ... ++** str x30, \[sp\] ++** sub sp, sp, #1040 ++** str xzr, \[sp\] ++** cbnz w0, .* ++** bl g ++** ... ++*/ ++int test2(int z) { ++ __uint128_t x = 0; ++ int y[0x400]; ++ if (z) ++ { ++ asm volatile ("" ::: ++ "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26"); ++ f(0, 0, 0, 0, 0, 0, 0, &y, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x); ++ } ++ g(); ++ return 1; ++} ++ ++/* ++** test3: ++** ... ++** str x30, \[sp\] ++** sub sp, sp, #1024 ++** cbnz w0, .* ++** bl g ++** ... ++*/ ++int test3(int z) { ++ __uint128_t x = 0; ++ int y[0x400]; ++ if (z) ++ { ++ asm volatile ("" ::: ++ "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26"); ++ f(0, 0, 0, 0, 0, 0, 0, &y, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x); ++ } ++ g(); ++ return 1; ++} +diff --git a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-19.c b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-19.c +new file mode 100644 +index 00000000000..73ac3e4e4eb +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-19.c +@@ -0,0 +1,100 @@ ++/* { dg-options "-O2 -fstack-clash-protection -fomit-frame-pointer --param stack-clash-protection-guard-size=12 -fsanitize=shadow-call-stack -ffixed-x18" } */ ++/* { dg-final { check-function-bodies "**" "" } } */ ++ ++void f(int, ...); ++void g(); ++ ++/* ++** test1: ++** ... ++** str x30, \[sp\] ++** sub sp, sp, #4064 ++** str xzr, \[sp\] ++** cbnz w0, .* ++** bl g ++** ... ++** str x26, \[sp, #?4128\] ++** ... ++*/ ++int test1(int z) { ++ __uint128_t x = 0; ++ int y[0x400]; ++ if (z) ++ { ++ asm volatile ("" ::: ++ "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26"); ++ f(0, 0, 0, 0, 0, 0, 0, &y, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x); ++ } ++ g(); ++ return 1; ++} ++ ++/* ++** test2: ++** ... ++** str x30, \[sp\] ++** sub sp, sp, #1040 ++** str xzr, \[sp\] ++** cbnz w0, .* ++** bl g ++** ... ++*/ ++int test2(int z) { ++ __uint128_t x = 0; ++ int y[0x400]; ++ if (z) ++ { ++ asm volatile ("" ::: ++ "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26"); ++ f(0, 0, 0, 0, 0, 0, 0, &y, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x); ++ } ++ g(); ++ return 1; ++} ++ ++/* ++** test3: ++** ... ++** str x30, \[sp\] ++** sub sp, sp, #1024 ++** cbnz w0, .* ++** bl g ++** ... ++*/ ++int test3(int z) { ++ __uint128_t x = 0; ++ int y[0x400]; ++ if (z) ++ { ++ asm volatile ("" ::: ++ "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26"); ++ f(0, 0, 0, 0, 0, 0, 0, &y, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, ++ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x); ++ } ++ g(); ++ return 1; ++} +diff --git a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-20.c b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-20.c +new file mode 100644 +index 00000000000..690aae8dfd5 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-20.c +@@ -0,0 +1,3 @@ ++/* { dg-options "-O2 -fstack-protector-all -fstack-clash-protection -fomit-frame-pointer --param stack-clash-protection-guard-size=12 -fsanitize=shadow-call-stack -ffixed-x18" } */ ++ ++#include "stack-check-prologue-19.c" +-- +2.25.1 + + +From 033448f9f2e458eacb7b729c512d5443ec7fd607 Mon Sep 17 00:00:00 2001 +From: Richard Sandiford +Date: Tue, 27 Jun 2023 18:19:59 +0100 +Subject: [PATCH 16/19] aarch64: Simplify probe of final frame allocation +To: gcc-patches@gcc.gnu.org + +Previous patches ensured that the final frame allocation only needs +a probe when the size is strictly greater than 1KiB. It's therefore +safe to use the normal 1024 probe offset in all cases. + +The main motivation for doing this is to simplify the code and +remove the number of special cases. + +gcc/ + * config/aarch64/aarch64.cc (aarch64_allocate_and_probe_stack_space): + Always probe the residual allocation at offset 1024, asserting + that that is in range. + +gcc/testsuite/ + * gcc.target/aarch64/stack-check-prologue-17.c: Expect the probe + to be at offset 1024 rather than offset 0. + * gcc.target/aarch64/stack-check-prologue-18.c: Likewise. + * gcc.target/aarch64/stack-check-prologue-19.c: Likewise. +--- + gcc/config/aarch64/aarch64.cc | 12 ++++-------- + .../gcc.target/aarch64/stack-check-prologue-17.c | 2 +- + .../gcc.target/aarch64/stack-check-prologue-18.c | 4 ++-- + .../gcc.target/aarch64/stack-check-prologue-19.c | 4 ++-- + 4 files changed, 9 insertions(+), 13 deletions(-) + +diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc +index 16433fb70f4..8abf3d7a1e2 100644 +--- a/gcc/config/aarch64/aarch64.cc ++++ b/gcc/config/aarch64/aarch64.cc +@@ -9523,16 +9523,12 @@ aarch64_allocate_and_probe_stack_space (rtx temp1, rtx temp2, + are still safe. */ + if (residual) + { +- HOST_WIDE_INT residual_probe_offset = guard_used_by_caller; ++ gcc_assert (guard_used_by_caller + byte_sp_alignment <= size); ++ + /* If we're doing final adjustments, and we've done any full page + allocations then any residual needs to be probed. */ + if (final_adjustment_p && rounded_size != 0) + min_probe_threshold = 0; +- /* If doing a small final adjustment, we always probe at offset 0. +- This is done to avoid issues when the final adjustment is smaller +- than the probing offset. */ +- else if (final_adjustment_p && rounded_size == 0) +- residual_probe_offset = 0; + + aarch64_sub_sp (temp1, temp2, residual, frame_related_p); + if (residual >= min_probe_threshold) +@@ -9543,8 +9539,8 @@ aarch64_allocate_and_probe_stack_space (rtx temp1, rtx temp2, + HOST_WIDE_INT_PRINT_DEC " bytes, probing will be required." + "\n", residual); + +- emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx, +- residual_probe_offset)); ++ emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx, ++ guard_used_by_caller)); + emit_insn (gen_blockage ()); + } + } +diff --git a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-17.c b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-17.c +index 0d8a25d73a2..f0ec1389771 100644 +--- a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-17.c ++++ b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-17.c +@@ -33,7 +33,7 @@ int test1(int z) { + ** ... + ** str x30, \[sp\] + ** sub sp, sp, #1040 +-** str xzr, \[sp\] ++** str xzr, \[sp, #?1024\] + ** cbnz w0, .* + ** bl g + ** ... +diff --git a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-18.c b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-18.c +index 82447d20fff..6383bec5ebc 100644 +--- a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-18.c ++++ b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-18.c +@@ -9,7 +9,7 @@ void g(); + ** ... + ** str x30, \[sp\] + ** sub sp, sp, #4064 +-** str xzr, \[sp\] ++** str xzr, \[sp, #?1024\] + ** cbnz w0, .* + ** bl g + ** ... +@@ -50,7 +50,7 @@ int test1(int z) { + ** ... + ** str x30, \[sp\] + ** sub sp, sp, #1040 +-** str xzr, \[sp\] ++** str xzr, \[sp, #?1024\] + ** cbnz w0, .* + ** bl g + ** ... +diff --git a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-19.c b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-19.c +index 73ac3e4e4eb..562039b5e9b 100644 +--- a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-19.c ++++ b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-19.c +@@ -9,7 +9,7 @@ void g(); + ** ... + ** str x30, \[sp\] + ** sub sp, sp, #4064 +-** str xzr, \[sp\] ++** str xzr, \[sp, #?1024\] + ** cbnz w0, .* + ** bl g + ** ... +@@ -50,7 +50,7 @@ int test1(int z) { + ** ... + ** str x30, \[sp\] + ** sub sp, sp, #1040 +-** str xzr, \[sp\] ++** str xzr, \[sp, #?1024\] + ** cbnz w0, .* + ** bl g + ** ... +-- +2.25.1 + + +From 1649125ff55c064cb700d359b8b5fbb0b1b7bf41 Mon Sep 17 00:00:00 2001 +From: Richard Sandiford +Date: Tue, 27 Jun 2023 11:50:34 +0100 +Subject: [PATCH 17/19] aarch64: Explicitly record probe registers in frame + info +To: gcc-patches@gcc.gnu.org + +The stack frame is currently divided into three areas: + +A: the area above the hard frame pointer +B: the SVE saves below the hard frame pointer +C: the outgoing arguments + +If the stack frame is allocated in one chunk, the allocation needs a +probe if the frame size is >= guard_size - 1KiB. In addition, if the +function is not a leaf function, it must probe an address no more than +1KiB above the outgoing SP. We ensured the second condition by + +(1) using single-chunk allocations for non-leaf functions only if + the link register save slot is within 512 bytes of the bottom + of the frame; and + +(2) using the link register save as a probe (meaning, for instance, + that it can't be individually shrink wrapped) + +If instead the stack is allocated in multiple chunks, then: + +* an allocation involving only the outgoing arguments (C above) requires + a probe if the allocation size is > 1KiB + +* any other allocation requires a probe if the allocation size + is >= guard_size - 1KiB + +* second and subsequent allocations require the previous allocation + to probe at the bottom of the allocated area, regardless of the size + of that previous allocation + +The final point means that, unlike for single allocations, +it can be necessary to have both a non-SVE register probe and +an SVE register probe. For example: + +* allocate A, probe using a non-SVE register save +* allocate B, probe using an SVE register save +* allocate C + +The non-SVE register used in this case was again the link register. +It was previously used even if the link register save slot was some +bytes above the bottom of the non-SVE register saves, but an earlier +patch avoided that by putting the link register save slot first. + +As a belt-and-braces fix, this patch explicitly records which +probe registers we're using and allows the non-SVE probe to be +whichever register comes first (as for SVE). + +The patch also avoids unnecessary probes in sve/pcs/stack_clash_3.c. + +gcc/ + * config/aarch64/aarch64.h (aarch64_frame::sve_save_and_probe) + (aarch64_frame::hard_fp_save_and_probe): New fields. + * config/aarch64/aarch64.cc (aarch64_layout_frame): Initialize them. + Rather than asserting that a leaf function saves LR, instead assert + that a leaf function saves something. + (aarch64_get_separate_components): Prevent the chosen probe + registers from being individually shrink-wrapped. + (aarch64_allocate_and_probe_stack_space): Remove workaround for + probe registers that aren't at the bottom of the previous allocation. +--- + gcc/config/aarch64/aarch64.cc | 68 +++++++++++++++---- + gcc/config/aarch64/aarch64.h | 8 +++ + .../aarch64/sve/pcs/stack_clash_3.c | 6 +- + 3 files changed, 64 insertions(+), 18 deletions(-) + +diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc +index 8abf3d7a1e2..a8d907df884 100644 +--- a/gcc/config/aarch64/aarch64.cc ++++ b/gcc/config/aarch64/aarch64.cc +@@ -8210,15 +8210,11 @@ aarch64_layout_frame (void) + && !crtl->abi->clobbers_full_reg_p (regno)) + frame.reg_offset[regno] = SLOT_REQUIRED; + +- /* With stack-clash, LR must be saved in non-leaf functions. The saving of +- LR counts as an implicit probe which allows us to maintain the invariant +- described in the comment at expand_prologue. */ +- gcc_assert (crtl->is_leaf +- || maybe_ne (frame.reg_offset[R30_REGNUM], SLOT_NOT_REQUIRED)); + + poly_int64 offset = crtl->outgoing_args_size; + gcc_assert (multiple_p (offset, STACK_BOUNDARY / BITS_PER_UNIT)); + frame.bytes_below_saved_regs = offset; ++ frame.sve_save_and_probe = INVALID_REGNUM; + + /* Now assign stack slots for the registers. Start with the predicate + registers, since predicate LDR and STR have a relatively small +@@ -8226,6 +8222,8 @@ aarch64_layout_frame (void) + for (regno = P0_REGNUM; regno <= P15_REGNUM; regno++) + if (known_eq (frame.reg_offset[regno], SLOT_REQUIRED)) + { ++ if (frame.sve_save_and_probe == INVALID_REGNUM) ++ frame.sve_save_and_probe = regno; + frame.reg_offset[regno] = offset; + offset += BYTES_PER_SVE_PRED; + } +@@ -8263,6 +8261,8 @@ aarch64_layout_frame (void) + for (regno = V0_REGNUM; regno <= V31_REGNUM; regno++) + if (known_eq (frame.reg_offset[regno], SLOT_REQUIRED)) + { ++ if (frame.sve_save_and_probe == INVALID_REGNUM) ++ frame.sve_save_and_probe = regno; + frame.reg_offset[regno] = offset; + offset += vector_save_size; + } +@@ -8272,10 +8272,18 @@ aarch64_layout_frame (void) + frame.below_hard_fp_saved_regs_size = offset - frame.bytes_below_saved_regs; + bool saves_below_hard_fp_p + = maybe_ne (frame.below_hard_fp_saved_regs_size, 0); ++ gcc_assert (!saves_below_hard_fp_p ++ || (frame.sve_save_and_probe != INVALID_REGNUM ++ && known_eq (frame.reg_offset[frame.sve_save_and_probe], ++ frame.bytes_below_saved_regs))); ++ + frame.bytes_below_hard_fp = offset; ++ frame.hard_fp_save_and_probe = INVALID_REGNUM; + + auto allocate_gpr_slot = [&](unsigned int regno) + { ++ if (frame.hard_fp_save_and_probe == INVALID_REGNUM) ++ frame.hard_fp_save_and_probe = regno; + frame.reg_offset[regno] = offset; + if (frame.wb_push_candidate1 == INVALID_REGNUM) + frame.wb_push_candidate1 = regno; +@@ -8309,6 +8317,8 @@ aarch64_layout_frame (void) + for (regno = V0_REGNUM; regno <= V31_REGNUM; regno++) + if (known_eq (frame.reg_offset[regno], SLOT_REQUIRED)) + { ++ if (frame.hard_fp_save_and_probe == INVALID_REGNUM) ++ frame.hard_fp_save_and_probe = regno; + /* If there is an alignment gap between integer and fp callee-saves, + allocate the last fp register to it if possible. */ + if (regno == last_fp_reg +@@ -8332,6 +8342,17 @@ aarch64_layout_frame (void) + offset = aligned_upper_bound (offset, STACK_BOUNDARY / BITS_PER_UNIT); + + frame.saved_regs_size = offset - frame.bytes_below_saved_regs; ++ gcc_assert (known_eq (frame.saved_regs_size, ++ frame.below_hard_fp_saved_regs_size) ++ || (frame.hard_fp_save_and_probe != INVALID_REGNUM ++ && known_eq (frame.reg_offset[frame.hard_fp_save_and_probe], ++ frame.bytes_below_hard_fp))); ++ ++ /* With stack-clash, a register must be saved in non-leaf functions. ++ The saving of the bottommost register counts as an implicit probe, ++ which allows us to maintain the invariant described in the comment ++ at expand_prologue. */ ++ gcc_assert (crtl->is_leaf || maybe_ne (frame.saved_regs_size, 0)); + + offset += get_frame_size (); + offset = aligned_upper_bound (offset, STACK_BOUNDARY / BITS_PER_UNIT); +@@ -8462,6 +8483,25 @@ aarch64_layout_frame (void) + frame.final_adjust = frame.bytes_below_saved_regs; + } + ++ /* The frame is allocated in pieces, with each non-final piece ++ including a register save at offset 0 that acts as a probe for ++ the following piece. In addition, the save of the bottommost register ++ acts as a probe for callees and allocas. Roll back any probes that ++ aren't needed. ++ ++ A probe isn't needed if it is associated with the final allocation ++ (including callees and allocas) that happens before the epilogue is ++ executed. */ ++ if (crtl->is_leaf ++ && !cfun->calls_alloca ++ && known_eq (frame.final_adjust, 0)) ++ { ++ if (maybe_ne (frame.sve_callee_adjust, 0)) ++ frame.sve_save_and_probe = INVALID_REGNUM; ++ else ++ frame.hard_fp_save_and_probe = INVALID_REGNUM; ++ } ++ + /* Make sure the individual adjustments add up to the full frame size. */ + gcc_assert (known_eq (frame.initial_adjust + + frame.callee_adjust +@@ -9039,13 +9079,6 @@ aarch64_get_separate_components (void) + + poly_int64 offset = frame.reg_offset[regno]; + +- /* If the register is saved in the first SVE save slot, we use +- it as a stack probe for -fstack-clash-protection. */ +- if (flag_stack_clash_protection +- && maybe_ne (frame.below_hard_fp_saved_regs_size, 0) +- && known_eq (offset, frame.bytes_below_saved_regs)) +- continue; +- + /* Get the offset relative to the register we'll use. */ + if (frame_pointer_needed) + offset -= frame.bytes_below_hard_fp; +@@ -9080,6 +9113,13 @@ aarch64_get_separate_components (void) + + bitmap_clear_bit (components, LR_REGNUM); + bitmap_clear_bit (components, SP_REGNUM); ++ if (flag_stack_clash_protection) ++ { ++ if (frame.sve_save_and_probe != INVALID_REGNUM) ++ bitmap_clear_bit (components, frame.sve_save_and_probe); ++ if (frame.hard_fp_save_and_probe != INVALID_REGNUM) ++ bitmap_clear_bit (components, frame.hard_fp_save_and_probe); ++ } + + return components; + } +@@ -9616,8 +9656,8 @@ aarch64_epilogue_uses (int regno) + When probing is needed, we emit a probe at the start of the prologue + and every PARAM_STACK_CLASH_PROTECTION_GUARD_SIZE bytes thereafter. + +- We have to track how much space has been allocated and the only stores +- to the stack we track as implicit probes are the FP/LR stores. ++ We can also use register saves as probes. These are stored in ++ sve_save_and_probe and hard_fp_save_and_probe. + + For outgoing arguments we probe if the size is larger than 1KB, such that + the ABI specified buffer is maintained for the next callee. +diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h +index b6135837073..46d4693e206 100644 +--- a/gcc/config/aarch64/aarch64.h ++++ b/gcc/config/aarch64/aarch64.h +@@ -957,6 +957,14 @@ struct GTY (()) aarch64_frame + This is the register they should use. */ + unsigned spare_pred_reg; + ++ /* An SVE register that is saved below the hard frame pointer and that acts ++ as a probe for later allocations, or INVALID_REGNUM if none. */ ++ unsigned sve_save_and_probe; ++ ++ /* A register that is saved at the hard frame pointer and that acts ++ as a probe for later allocations, or INVALID_REGNUM if none. */ ++ unsigned hard_fp_save_and_probe; ++ + bool laid_out; + + /* True if shadow call stack should be enabled for the current function. */ +diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pcs/stack_clash_3.c b/gcc/testsuite/gcc.target/aarch64/sve/pcs/stack_clash_3.c +index 3e01ec36c3a..3530a0d504b 100644 +--- a/gcc/testsuite/gcc.target/aarch64/sve/pcs/stack_clash_3.c ++++ b/gcc/testsuite/gcc.target/aarch64/sve/pcs/stack_clash_3.c +@@ -11,11 +11,10 @@ + ** mov x11, sp + ** ... + ** sub sp, sp, x13 +-** str p4, \[sp\] + ** cbz w0, [^\n]* ++** str p4, \[sp\] + ** ... + ** ptrue p0\.b, all +-** ldr p4, \[sp\] + ** addvl sp, sp, #1 + ** ldr x24, \[sp\], 32 + ** ret +@@ -39,13 +38,12 @@ test_1 (int n) + ** mov x11, sp + ** ... + ** sub sp, sp, x13 +-** str p4, \[sp\] + ** cbz w0, [^\n]* ++** str p4, \[sp\] + ** str p5, \[sp, #1, mul vl\] + ** str p6, \[sp, #2, mul vl\] + ** ... + ** ptrue p0\.b, all +-** ldr p4, \[sp\] + ** addvl sp, sp, #1 + ** ldr x24, \[sp\], 32 + ** ret +-- +2.25.1 + + +From ad433e4cc7b26ee3502fd304f8f2bce3d84c959c Mon Sep 17 00:00:00 2001 +From: Richard Sandiford +Date: Thu, 22 Jun 2023 22:15:39 +0100 +Subject: [PATCH 18/19] aarch64: Remove below_hard_fp_saved_regs_size +To: gcc-patches@gcc.gnu.org + +After previous patches, it's no longer necessary to store +saved_regs_size and below_hard_fp_saved_regs_size in the frame info. +All measurements instead use the top or bottom of the frame as +reference points. + +gcc/ + * config/aarch64/aarch64.h (aarch64_frame::saved_regs_size) + (aarch64_frame::below_hard_fp_saved_regs_size): Delete. + * config/aarch64/aarch64.cc (aarch64_layout_frame): Update accordingly. +--- + gcc/config/aarch64/aarch64.cc | 45 ++++++++++++++++------------------- + gcc/config/aarch64/aarch64.h | 7 ------ + 2 files changed, 21 insertions(+), 31 deletions(-) + +diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc +index a8d907df884..ac3d3b336a3 100644 +--- a/gcc/config/aarch64/aarch64.cc ++++ b/gcc/config/aarch64/aarch64.cc +@@ -8269,9 +8269,8 @@ aarch64_layout_frame (void) + + /* OFFSET is now the offset of the hard frame pointer from the bottom + of the callee save area. */ +- frame.below_hard_fp_saved_regs_size = offset - frame.bytes_below_saved_regs; +- bool saves_below_hard_fp_p +- = maybe_ne (frame.below_hard_fp_saved_regs_size, 0); ++ auto below_hard_fp_saved_regs_size = offset - frame.bytes_below_saved_regs; ++ bool saves_below_hard_fp_p = maybe_ne (below_hard_fp_saved_regs_size, 0); + gcc_assert (!saves_below_hard_fp_p + || (frame.sve_save_and_probe != INVALID_REGNUM + && known_eq (frame.reg_offset[frame.sve_save_and_probe], +@@ -8341,9 +8340,8 @@ aarch64_layout_frame (void) + + offset = aligned_upper_bound (offset, STACK_BOUNDARY / BITS_PER_UNIT); + +- frame.saved_regs_size = offset - frame.bytes_below_saved_regs; +- gcc_assert (known_eq (frame.saved_regs_size, +- frame.below_hard_fp_saved_regs_size) ++ auto saved_regs_size = offset - frame.bytes_below_saved_regs; ++ gcc_assert (known_eq (saved_regs_size, below_hard_fp_saved_regs_size) + || (frame.hard_fp_save_and_probe != INVALID_REGNUM + && known_eq (frame.reg_offset[frame.hard_fp_save_and_probe], + frame.bytes_below_hard_fp))); +@@ -8352,7 +8350,7 @@ aarch64_layout_frame (void) + The saving of the bottommost register counts as an implicit probe, + which allows us to maintain the invariant described in the comment + at expand_prologue. */ +- gcc_assert (crtl->is_leaf || maybe_ne (frame.saved_regs_size, 0)); ++ gcc_assert (crtl->is_leaf || maybe_ne (saved_regs_size, 0)); + + offset += get_frame_size (); + offset = aligned_upper_bound (offset, STACK_BOUNDARY / BITS_PER_UNIT); +@@ -8409,7 +8407,7 @@ aarch64_layout_frame (void) + + HOST_WIDE_INT const_size, const_below_saved_regs, const_above_fp; + HOST_WIDE_INT const_saved_regs_size; +- if (known_eq (frame.saved_regs_size, 0)) ++ if (known_eq (saved_regs_size, 0)) + frame.initial_adjust = frame.frame_size; + else if (frame.frame_size.is_constant (&const_size) + && const_size < max_push_offset +@@ -8422,7 +8420,7 @@ aarch64_layout_frame (void) + frame.callee_adjust = const_size; + } + else if (frame.bytes_below_saved_regs.is_constant (&const_below_saved_regs) +- && frame.saved_regs_size.is_constant (&const_saved_regs_size) ++ && saved_regs_size.is_constant (&const_saved_regs_size) + && const_below_saved_regs + const_saved_regs_size < 512 + /* We could handle this case even with data below the saved + registers, provided that that data left us with valid offsets +@@ -8441,8 +8439,7 @@ aarch64_layout_frame (void) + frame.initial_adjust = frame.frame_size; + } + else if (saves_below_hard_fp_p +- && known_eq (frame.saved_regs_size, +- frame.below_hard_fp_saved_regs_size)) ++ && known_eq (saved_regs_size, below_hard_fp_saved_regs_size)) + { + /* Frame in which all saves are SVE saves: + +@@ -8464,7 +8461,7 @@ aarch64_layout_frame (void) + [save SVE registers relative to SP] + sub sp, sp, bytes_below_saved_regs */ + frame.callee_adjust = const_above_fp; +- frame.sve_callee_adjust = frame.below_hard_fp_saved_regs_size; ++ frame.sve_callee_adjust = below_hard_fp_saved_regs_size; + frame.final_adjust = frame.bytes_below_saved_regs; + } + else +@@ -8479,7 +8476,7 @@ aarch64_layout_frame (void) + [save SVE registers relative to SP] + sub sp, sp, bytes_below_saved_regs */ + frame.initial_adjust = frame.bytes_above_hard_fp; +- frame.sve_callee_adjust = frame.below_hard_fp_saved_regs_size; ++ frame.sve_callee_adjust = below_hard_fp_saved_regs_size; + frame.final_adjust = frame.bytes_below_saved_regs; + } + +@@ -9621,17 +9618,17 @@ aarch64_epilogue_uses (int regno) + | local variables | <-- frame_pointer_rtx + | | + +-------------------------------+ +- | padding | \ +- +-------------------------------+ | +- | callee-saved registers | | frame.saved_regs_size +- +-------------------------------+ | +- | LR' | | +- +-------------------------------+ | +- | FP' | | +- +-------------------------------+ |<- hard_frame_pointer_rtx (aligned) +- | SVE vector registers | | \ +- +-------------------------------+ | | below_hard_fp_saved_regs_size +- | SVE predicate registers | / / ++ | padding | ++ +-------------------------------+ ++ | callee-saved registers | ++ +-------------------------------+ ++ | LR' | ++ +-------------------------------+ ++ | FP' | ++ +-------------------------------+ <-- hard_frame_pointer_rtx (aligned) ++ | SVE vector registers | ++ +-------------------------------+ ++ | SVE predicate registers | + +-------------------------------+ + | dynamic allocation | + +-------------------------------+ +diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h +index 46d4693e206..01f7751bc78 100644 +--- a/gcc/config/aarch64/aarch64.h ++++ b/gcc/config/aarch64/aarch64.h +@@ -871,18 +871,11 @@ struct GTY (()) aarch64_frame + STACK_BOUNDARY. */ + HOST_WIDE_INT saved_varargs_size; + +- /* The size of the callee-save registers with a slot in REG_OFFSET. */ +- poly_int64 saved_regs_size; +- + /* The number of bytes between the bottom of the static frame (the bottom + of the outgoing arguments) and the bottom of the register save area. + This value is always a multiple of STACK_BOUNDARY. */ + poly_int64 bytes_below_saved_regs; + +- /* The size of the callee-save registers with a slot in REG_OFFSET that +- are saved below the hard frame pointer. */ +- poly_int64 below_hard_fp_saved_regs_size; +- + /* The number of bytes between the bottom of the static frame (the bottom + of the outgoing arguments) and the hard frame pointer. This value is + always a multiple of STACK_BOUNDARY. */ +-- +2.25.1 + + +From 499f3ba04805d4f3374ea4476230a8568f51efc8 Mon Sep 17 00:00:00 2001 +From: Richard Sandiford +Date: Thu, 15 Jun 2023 19:16:52 +0100 +Subject: [PATCH 19/19] aarch64: Make stack smash canary protect saved + registers +To: gcc-patches@gcc.gnu.org + +AArch64 normally puts the saved registers near the bottom of the frame, +immediately above any dynamic allocations. But this means that a +stack-smash attack on those dynamic allocations could overwrite the +saved registers without needing to reach as far as the stack smash +canary. + +The same thing could also happen for variable-sized arguments that are +passed by value, since those are allocated before a call and popped on +return. + +This patch avoids that by putting the locals (and thus the canary) below +the saved registers when stack smash protection is active. + +The patch fixes CVE-2023-4039. + +gcc/ + * config/aarch64/aarch64.cc (aarch64_save_regs_above_locals_p): + New function. + (aarch64_layout_frame): Use it to decide whether locals should + go above or below the saved registers. + (aarch64_expand_prologue): Update stack layout comment. + Emit a stack tie after the final adjustment. + +gcc/testsuite/ + * gcc.target/aarch64/stack-protector-8.c: New test. + * gcc.target/aarch64/stack-protector-9.c: Likewise. +--- + gcc/config/aarch64/aarch64.cc | 46 +++++++-- + .../gcc.target/aarch64/stack-protector-8.c | 95 +++++++++++++++++++ + .../gcc.target/aarch64/stack-protector-9.c | 33 +++++++ + 3 files changed, 168 insertions(+), 6 deletions(-) + create mode 100644 gcc/testsuite/gcc.target/aarch64/stack-protector-8.c + create mode 100644 gcc/testsuite/gcc.target/aarch64/stack-protector-9.c + +diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc +index ac3d3b336a3..96c3f48fdc4 100644 +--- a/gcc/config/aarch64/aarch64.cc ++++ b/gcc/config/aarch64/aarch64.cc +@@ -8133,6 +8133,20 @@ aarch64_needs_frame_chain (void) + return aarch64_use_frame_pointer; + } + ++/* Return true if the current function should save registers above ++ the locals area, rather than below it. */ ++ ++static bool ++aarch64_save_regs_above_locals_p () ++{ ++ /* When using stack smash protection, make sure that the canary slot ++ comes between the locals and the saved registers. Otherwise, ++ it would be possible for a carefully sized smash attack to change ++ the saved registers (particularly LR and FP) without reaching the ++ canary. */ ++ return crtl->stack_protect_guard; ++} ++ + /* Mark the registers that need to be saved by the callee and calculate + the size of the callee-saved registers area and frame record (both FP + and LR may be omitted). */ +@@ -8144,6 +8158,7 @@ aarch64_layout_frame (void) + poly_int64 vector_save_size = GET_MODE_SIZE (vector_save_mode); + bool frame_related_fp_reg_p = false; + aarch64_frame &frame = cfun->machine->frame; ++ poly_int64 top_of_locals = -1; + + frame.emit_frame_chain = aarch64_needs_frame_chain (); + +@@ -8210,9 +8225,16 @@ aarch64_layout_frame (void) + && !crtl->abi->clobbers_full_reg_p (regno)) + frame.reg_offset[regno] = SLOT_REQUIRED; + ++ bool regs_at_top_p = aarch64_save_regs_above_locals_p (); + + poly_int64 offset = crtl->outgoing_args_size; + gcc_assert (multiple_p (offset, STACK_BOUNDARY / BITS_PER_UNIT)); ++ if (regs_at_top_p) ++ { ++ offset += get_frame_size (); ++ offset = aligned_upper_bound (offset, STACK_BOUNDARY / BITS_PER_UNIT); ++ top_of_locals = offset; ++ } + frame.bytes_below_saved_regs = offset; + frame.sve_save_and_probe = INVALID_REGNUM; + +@@ -8352,15 +8374,18 @@ aarch64_layout_frame (void) + at expand_prologue. */ + gcc_assert (crtl->is_leaf || maybe_ne (saved_regs_size, 0)); + +- offset += get_frame_size (); +- offset = aligned_upper_bound (offset, STACK_BOUNDARY / BITS_PER_UNIT); +- auto top_of_locals = offset; +- ++ if (!regs_at_top_p) ++ { ++ offset += get_frame_size (); ++ offset = aligned_upper_bound (offset, STACK_BOUNDARY / BITS_PER_UNIT); ++ top_of_locals = offset; ++ } + offset += frame.saved_varargs_size; + gcc_assert (multiple_p (offset, STACK_BOUNDARY / BITS_PER_UNIT)); + frame.frame_size = offset; + + frame.bytes_above_hard_fp = frame.frame_size - frame.bytes_below_hard_fp; ++ gcc_assert (known_ge (top_of_locals, 0)); + frame.bytes_above_locals = frame.frame_size - top_of_locals; + + frame.initial_adjust = 0; +@@ -9615,10 +9640,10 @@ aarch64_epilogue_uses (int regno) + | for register varargs | + | | + +-------------------------------+ +- | local variables | <-- frame_pointer_rtx ++ | local variables (1) | <-- frame_pointer_rtx + | | + +-------------------------------+ +- | padding | ++ | padding (1) | + +-------------------------------+ + | callee-saved registers | + +-------------------------------+ +@@ -9630,6 +9655,10 @@ aarch64_epilogue_uses (int regno) + +-------------------------------+ + | SVE predicate registers | + +-------------------------------+ ++ | local variables (2) | ++ +-------------------------------+ ++ | padding (2) | ++ +-------------------------------+ + | dynamic allocation | + +-------------------------------+ + | padding | +@@ -9639,6 +9668,9 @@ aarch64_epilogue_uses (int regno) + +-------------------------------+ + | | <-- stack_pointer_rtx (aligned) + ++ The regions marked (1) and (2) are mutually exclusive. (2) is used ++ when aarch64_save_regs_above_locals_p is true. ++ + Dynamic stack allocations via alloca() decrease stack_pointer_rtx + but leave frame_pointer_rtx and hard_frame_pointer_rtx + unchanged. +@@ -9834,6 +9866,8 @@ aarch64_expand_prologue (void) + gcc_assert (known_eq (bytes_below_sp, final_adjust)); + aarch64_allocate_and_probe_stack_space (tmp1_rtx, tmp0_rtx, final_adjust, + !frame_pointer_needed, true); ++ if (emit_frame_chain && maybe_ne (final_adjust, 0)) ++ emit_insn (gen_stack_tie (stack_pointer_rtx, hard_frame_pointer_rtx)); + } + + /* Return TRUE if we can use a simple_return insn. +diff --git a/gcc/testsuite/gcc.target/aarch64/stack-protector-8.c b/gcc/testsuite/gcc.target/aarch64/stack-protector-8.c +new file mode 100644 +index 00000000000..e71d820e365 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/stack-protector-8.c +@@ -0,0 +1,95 @@ ++/* { dg-options " -O -fstack-protector-strong -mstack-protector-guard=sysreg -mstack-protector-guard-reg=tpidr2_el0 -mstack-protector-guard-offset=16" } */ ++/* { dg-final { check-function-bodies "**" "" } } */ ++ ++void g(void *); ++__SVBool_t *h(void *); ++ ++/* ++** test1: ++** sub sp, sp, #288 ++** stp x29, x30, \[sp, #?272\] ++** add x29, sp, #?272 ++** mrs (x[0-9]+), tpidr2_el0 ++** ldr (x[0-9]+), \[\1, #?16\] ++** str \2, \[sp, #?264\] ++** mov \2, #?0 ++** add x0, sp, #?8 ++** bl g ++** ... ++** mrs .* ++** ... ++** bne .* ++** ... ++** ldp x29, x30, \[sp, #?272\] ++** add sp, sp, #?288 ++** ret ++** bl __stack_chk_fail ++*/ ++int test1() { ++ int y[0x40]; ++ g(y); ++ return 1; ++} ++ ++/* ++** test2: ++** stp x29, x30, \[sp, #?-16\]! ++** mov x29, sp ++** sub sp, sp, #1040 ++** mrs (x[0-9]+), tpidr2_el0 ++** ldr (x[0-9]+), \[\1, #?16\] ++** str \2, \[sp, #?1032\] ++** mov \2, #?0 ++** add x0, sp, #?8 ++** bl g ++** ... ++** mrs .* ++** ... ++** bne .* ++** ... ++** add sp, sp, #?1040 ++** ldp x29, x30, \[sp\], #?16 ++** ret ++** bl __stack_chk_fail ++*/ ++int test2() { ++ int y[0x100]; ++ g(y); ++ return 1; ++} ++ ++#pragma GCC target "+sve" ++ ++/* ++** test3: ++** stp x29, x30, \[sp, #?-16\]! ++** mov x29, sp ++** addvl sp, sp, #-18 ++** ... ++** str p4, \[sp\] ++** ... ++** sub sp, sp, #272 ++** mrs (x[0-9]+), tpidr2_el0 ++** ldr (x[0-9]+), \[\1, #?16\] ++** str \2, \[sp, #?264\] ++** mov \2, #?0 ++** add x0, sp, #?8 ++** bl h ++** ... ++** mrs .* ++** ... ++** bne .* ++** ... ++** add sp, sp, #?272 ++** ... ++** ldr p4, \[sp\] ++** ... ++** addvl sp, sp, #18 ++** ldp x29, x30, \[sp\], #?16 ++** ret ++** bl __stack_chk_fail ++*/ ++__SVBool_t test3() { ++ int y[0x40]; ++ return *h(y); ++} +diff --git a/gcc/testsuite/gcc.target/aarch64/stack-protector-9.c b/gcc/testsuite/gcc.target/aarch64/stack-protector-9.c +new file mode 100644 +index 00000000000..58f322aa480 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/stack-protector-9.c +@@ -0,0 +1,33 @@ ++/* { dg-options "-O2 -mcpu=neoverse-v1 -fstack-protector-all" } */ ++/* { dg-final { check-function-bodies "**" "" } } */ ++ ++/* ++** main: ++** ... ++** stp x29, x30, \[sp, #?-[0-9]+\]! ++** ... ++** sub sp, sp, #[0-9]+ ++** ... ++** str x[0-9]+, \[x29, #?-8\] ++** ... ++*/ ++int f(const char *); ++void g(void *); ++int main(int argc, char* argv[]) ++{ ++ int a; ++ int b; ++ char c[2+f(argv[1])]; ++ int d[0x100]; ++ char y; ++ ++ y=42; a=4; b=10; ++ c[0] = 'h'; c[1] = '\0'; ++ ++ c[f(argv[2])] = '\0'; ++ ++ __builtin_printf("%d %d\n%s\n", a, b, c); ++ g(d); ++ ++ return 0; ++} +-- +2.25.1 + diff --git a/gcc12-riscv-inline-atomics.patch b/gcc12-riscv-inline-atomics.patch new file mode 100644 index 0000000..471e5be --- /dev/null +++ b/gcc12-riscv-inline-atomics.patch @@ -0,0 +1,2075 @@ +From 3fe7d4e13d05ae1fc3fdd60f8cadcfaea2dcd3f8 Mon Sep 17 00:00:00 2001 +From: Patrick O'Neill +Date: Tue, 19 Apr 2022 10:17:50 -0700 +Subject: [PATCH] RISC-V: Add support for inlining subword atomic operations + +RISC-V has no support for subword atomic operations; code currently +generates libatomic library calls. + +This patch changes the default behavior to inline subword atomic calls +(using the same logic as the existing library call). +Behavior can be specified using the -minline-atomics and +-mno-inline-atomics command line flags. + +gcc/libgcc/config/riscv/atomic.c has the same logic implemented in asm. +This will need to stay for backwards compatibility and the +-mno-inline-atomics flag. + +2022-04-19 Patrick O'Neill + + PR target/104338 + * riscv-protos.h: Add helper function stubs. + * riscv.cc: Add helper functions for subword masking. + * riscv.opt: Add command-line flag. + * sync.md: Add masking logic and inline asm for fetch_and_op, + fetch_and_nand, CAS, and exchange ops. + * invoke.texi: Add blurb regarding command-line flag. + * inline-atomics-1.c: New test. + * inline-atomics-2.c: Likewise. + * inline-atomics-3.c: Likewise. + * inline-atomics-4.c: Likewise. + * inline-atomics-5.c: Likewise. + * inline-atomics-6.c: Likewise. + * inline-atomics-7.c: Likewise. + * inline-atomics-8.c: Likewise. + * atomic.c: Add reference to duplicate logic. + +Signed-off-by: Patrick O'Neill +--- + gcc/config/riscv/riscv-protos.h | 2 + + gcc/config/riscv/riscv.cc | 52 ++ + gcc/config/riscv/riscv.opt | 4 + + gcc/config/riscv/sync.md | 318 ++++++++++ + gcc/doc/invoke.texi | 7 + + .../gcc.target/riscv/inline-atomics-1.c | 18 + + .../gcc.target/riscv/inline-atomics-2.c | 19 + + .../gcc.target/riscv/inline-atomics-3.c | 569 ++++++++++++++++++ + .../gcc.target/riscv/inline-atomics-4.c | 566 +++++++++++++++++ + .../gcc.target/riscv/inline-atomics-5.c | 87 +++ + .../gcc.target/riscv/inline-atomics-6.c | 87 +++ + .../gcc.target/riscv/inline-atomics-7.c | 69 +++ + .../gcc.target/riscv/inline-atomics-8.c | 69 +++ + libgcc/config/riscv/atomic.c | 2 + + 14 files changed, 1869 insertions(+) + create mode 100644 gcc/testsuite/gcc.target/riscv/inline-atomics-1.c + create mode 100644 gcc/testsuite/gcc.target/riscv/inline-atomics-2.c + create mode 100644 gcc/testsuite/gcc.target/riscv/inline-atomics-3.c + create mode 100644 gcc/testsuite/gcc.target/riscv/inline-atomics-4.c + create mode 100644 gcc/testsuite/gcc.target/riscv/inline-atomics-5.c + create mode 100644 gcc/testsuite/gcc.target/riscv/inline-atomics-6.c + create mode 100644 gcc/testsuite/gcc.target/riscv/inline-atomics-7.c + create mode 100644 gcc/testsuite/gcc.target/riscv/inline-atomics-8.c + +diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h +index 20c2381c21a..14f3c8f0d4e 100644 +--- a/gcc/config/riscv/riscv-protos.h ++++ b/gcc/config/riscv/riscv-protos.h +@@ -74,6 +74,8 @@ extern bool riscv_expand_block_move (rtx, rtx, rtx); + extern bool riscv_store_data_bypass_p (rtx_insn *, rtx_insn *); + extern rtx riscv_gen_gpr_save_insn (struct riscv_frame_info *); + extern bool riscv_gpr_save_operation_p (rtx); ++extern void riscv_subword_address (rtx, rtx *, rtx *, rtx *, rtx *); ++extern void riscv_lshift_subword (machine_mode, rtx, rtx, rtx *); + + /* Routines implemented in riscv-c.cc. */ + void riscv_cpu_cpp_builtins (cpp_reader *); +diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc +index ee756aab694..cfd2f7710db 100644 +--- a/gcc/config/riscv/riscv.cc ++++ b/gcc/config/riscv/riscv.cc +@@ -5587,6 +5587,58 @@ riscv_asan_shadow_offset (void) + return TARGET_64BIT ? (HOST_WIDE_INT_1 << 29) : 0; + } + ++/* Helper function for extracting a subword from memory. */ ++ ++void ++riscv_subword_address (rtx mem, rtx *aligned_mem, rtx *shift, rtx *mask, ++ rtx *not_mask) ++{ ++ /* Align the memory addess to a word. */ ++ rtx addr = force_reg (Pmode, XEXP (mem, 0)); ++ ++ rtx aligned_addr = gen_reg_rtx (Pmode); ++ emit_move_insn (aligned_addr, gen_rtx_AND (Pmode, addr, ++ gen_int_mode (-4, Pmode))); ++ ++ *aligned_mem = change_address (mem, SImode, aligned_addr); ++ ++ /* Calculate the shift amount. */ ++ *shift = gen_reg_rtx (SImode); ++ emit_move_insn (*shift, gen_rtx_AND (SImode, gen_lowpart (SImode, addr), ++ gen_int_mode (3, SImode))); ++ emit_move_insn (*shift, gen_rtx_ASHIFT (SImode, *shift, ++ gen_int_mode(3, SImode))); ++ ++ /* Calculate the mask. */ ++ int unshifted_mask; ++ if (GET_MODE (mem) == QImode) ++ unshifted_mask = 0xFF; ++ else ++ unshifted_mask = 0xFFFF; ++ ++ rtx mask_reg = gen_reg_rtx (SImode); ++ emit_move_insn (mask_reg, gen_int_mode(unshifted_mask, SImode)); ++ ++ emit_move_insn (*mask, gen_rtx_ASHIFT(SImode, mask_reg, ++ gen_lowpart (QImode, *shift))); ++ ++ emit_move_insn (*not_mask, gen_rtx_NOT(SImode, *mask)); ++} ++ ++/* Leftshift a subword within an SImode register. */ ++ ++void ++riscv_lshift_subword (machine_mode mode, rtx value, rtx shift, ++ rtx *shifted_value) ++{ ++ rtx value_reg = gen_reg_rtx (SImode); ++ emit_move_insn (value_reg, simplify_gen_subreg (SImode, value, ++ mode, 0)); ++ ++ emit_move_insn(*shifted_value, gen_rtx_ASHIFT(SImode, value_reg, ++ gen_lowpart (QImode, shift))); ++} ++ + /* Initialize the GCC target structure. */ + #undef TARGET_ASM_ALIGNED_HI_OP + #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t" +diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt +index 492aad12324..328d848d698 100644 +--- a/gcc/config/riscv/riscv.opt ++++ b/gcc/config/riscv/riscv.opt +@@ -225,3 +225,7 @@ Enum(isa_spec_class) String(20191213) Value(ISA_SPEC_CLASS_20191213) + misa-spec= + Target RejectNegative Joined Enum(isa_spec_class) Var(riscv_isa_spec) Init(TARGET_DEFAULT_ISA_SPEC) + Set the version of RISC-V ISA spec. ++ ++minline-atomics ++Target Var(TARGET_INLINE_SUBWORD_ATOMIC) Init(1) ++Always inline subword atomic operations. +diff --git a/gcc/config/riscv/sync.md b/gcc/config/riscv/sync.md +index 86b41e6b00a..198ddbed8e9 100644 +--- a/gcc/config/riscv/sync.md ++++ b/gcc/config/riscv/sync.md +@@ -21,8 +21,11 @@ + + (define_c_enum "unspec" [ + UNSPEC_COMPARE_AND_SWAP ++ UNSPEC_COMPARE_AND_SWAP_SUBWORD + UNSPEC_SYNC_OLD_OP ++ UNSPEC_SYNC_OLD_OP_SUBWORD + UNSPEC_SYNC_EXCHANGE ++ UNSPEC_SYNC_EXCHANGE_SUBWORD + UNSPEC_ATOMIC_STORE + UNSPEC_MEMORY_BARRIER + ]) +@@ -92,6 +95,145 @@ + "%F3amo.%A3 %0,%z2,%1" + [(set (attr "length") (const_int 8))]) + ++(define_expand "atomic_fetch_" ++ [(set (match_operand:SHORT 0 "register_operand" "=&r") ;; old value at mem ++ (match_operand:SHORT 1 "memory_operand" "+A")) ;; mem location ++ (set (match_dup 1) ++ (unspec_volatile:SHORT ++ [(any_atomic:SHORT (match_dup 1) ++ (match_operand:SHORT 2 "reg_or_0_operand" "rJ")) ;; value for op ++ (match_operand:SI 3 "const_int_operand")] ;; model ++ UNSPEC_SYNC_OLD_OP_SUBWORD))] ++ "TARGET_ATOMIC && TARGET_INLINE_SUBWORD_ATOMIC" ++{ ++ /* We have no QImode/HImode atomics, so form a mask, then use ++ subword_atomic_fetch_strong_ to implement a LR/SC version of the ++ operation. */ ++ ++ /* Logic duplicated in gcc/libgcc/config/riscv/atomic.c for use when inlining ++ is disabled */ ++ ++ rtx old = gen_reg_rtx (SImode); ++ rtx mem = operands[1]; ++ rtx value = operands[2]; ++ rtx aligned_mem = gen_reg_rtx (SImode); ++ rtx shift = gen_reg_rtx (SImode); ++ rtx mask = gen_reg_rtx (SImode); ++ rtx not_mask = gen_reg_rtx (SImode); ++ ++ riscv_subword_address (mem, &aligned_mem, &shift, &mask, ¬_mask); ++ ++ rtx shifted_value = gen_reg_rtx (SImode); ++ riscv_lshift_subword (mode, value, shift, &shifted_value); ++ ++ emit_insn (gen_subword_atomic_fetch_strong_ (old, aligned_mem, ++ shifted_value, ++ mask, not_mask)); ++ ++ emit_move_insn (old, gen_rtx_ASHIFTRT (SImode, old, ++ gen_lowpart (QImode, shift))); ++ ++ emit_move_insn (operands[0], gen_lowpart (mode, old)); ++ ++ DONE; ++}) ++ ++(define_insn "subword_atomic_fetch_strong_" ++ [(set (match_operand:SI 0 "register_operand" "=&r") ;; old value at mem ++ (match_operand:SI 1 "memory_operand" "+A")) ;; mem location ++ (set (match_dup 1) ++ (unspec_volatile:SI ++ [(any_atomic:SI (match_dup 1) ++ (match_operand:SI 2 "register_operand" "rI")) ;; value for op ++ (match_operand:SI 3 "register_operand" "rI")] ;; mask ++ UNSPEC_SYNC_OLD_OP_SUBWORD)) ++ (match_operand:SI 4 "register_operand" "rI") ;; not_mask ++ (clobber (match_scratch:SI 5 "=&r")) ;; tmp_1 ++ (clobber (match_scratch:SI 6 "=&r"))] ;; tmp_2 ++ "TARGET_ATOMIC && TARGET_INLINE_SUBWORD_ATOMIC" ++ { ++ return ++ "1:\;" ++ "lr.w.aq\t%0, %1\;" ++ "\t%5, %0, %2\;" ++ "and\t%5, %5, %3\;" ++ "and\t%6, %0, %4\;" ++ "or\t%6, %6, %5\;" ++ "sc.w.rl\t%5, %6, %1\;" ++ "bnez\t%5, 1b"; ++ } ++ [(set (attr "length") (const_int 28))]) ++ ++(define_expand "atomic_fetch_nand" ++ [(set (match_operand:SHORT 0 "register_operand" "=&r") ++ (match_operand:SHORT 1 "memory_operand" "+A")) ++ (set (match_dup 1) ++ (unspec_volatile:SHORT ++ [(not:SHORT (and:SHORT (match_dup 1) ++ (match_operand:SHORT 2 "reg_or_0_operand" "rJ"))) ++ (match_operand:SI 3 "const_int_operand")] ;; model ++ UNSPEC_SYNC_OLD_OP_SUBWORD))] ++ "TARGET_ATOMIC && TARGET_INLINE_SUBWORD_ATOMIC" ++{ ++ /* We have no QImode/HImode atomics, so form a mask, then use ++ subword_atomic_fetch_strong_nand to implement a LR/SC version of the ++ operation. */ ++ ++ /* Logic duplicated in gcc/libgcc/config/riscv/atomic.c for use when inlining ++ is disabled */ ++ ++ rtx old = gen_reg_rtx (SImode); ++ rtx mem = operands[1]; ++ rtx value = operands[2]; ++ rtx aligned_mem = gen_reg_rtx (SImode); ++ rtx shift = gen_reg_rtx (SImode); ++ rtx mask = gen_reg_rtx (SImode); ++ rtx not_mask = gen_reg_rtx (SImode); ++ ++ riscv_subword_address (mem, &aligned_mem, &shift, &mask, ¬_mask); ++ ++ rtx shifted_value = gen_reg_rtx (SImode); ++ riscv_lshift_subword (mode, value, shift, &shifted_value); ++ ++ emit_insn (gen_subword_atomic_fetch_strong_nand (old, aligned_mem, ++ shifted_value, ++ mask, not_mask)); ++ ++ emit_move_insn (old, gen_rtx_ASHIFTRT (SImode, old, ++ gen_lowpart (QImode, shift))); ++ ++ emit_move_insn (operands[0], gen_lowpart (mode, old)); ++ ++ DONE; ++}) ++ ++(define_insn "subword_atomic_fetch_strong_nand" ++ [(set (match_operand:SI 0 "register_operand" "=&r") ;; old value at mem ++ (match_operand:SI 1 "memory_operand" "+A")) ;; mem location ++ (set (match_dup 1) ++ (unspec_volatile:SI ++ [(not:SI (and:SI (match_dup 1) ++ (match_operand:SI 2 "register_operand" "rI"))) ;; value for op ++ (match_operand:SI 3 "register_operand" "rI")] ;; mask ++ UNSPEC_SYNC_OLD_OP_SUBWORD)) ++ (match_operand:SI 4 "register_operand" "rI") ;; not_mask ++ (clobber (match_scratch:SI 5 "=&r")) ;; tmp_1 ++ (clobber (match_scratch:SI 6 "=&r"))] ;; tmp_2 ++ "TARGET_ATOMIC && TARGET_INLINE_SUBWORD_ATOMIC" ++ { ++ return ++ "1:\;" ++ "lr.w.aq\t%0, %1\;" ++ "and\t%5, %0, %2\;" ++ "not\t%5, %5\;" ++ "and\t%5, %5, %3\;" ++ "and\t%6, %0, %4\;" ++ "or\t%6, %6, %5\;" ++ "sc.w.rl\t%5, %6, %1\;" ++ "bnez\t%5, 1b"; ++ } ++ [(set (attr "length") (const_int 32))]) ++ + (define_insn "atomic_exchange" + [(set (match_operand:GPR 0 "register_operand" "=&r") + (unspec_volatile:GPR +@@ -104,6 +246,60 @@ + "%F3amoswap.%A3 %0,%z2,%1" + [(set (attr "length") (const_int 8))]) + ++(define_expand "atomic_exchange" ++ [(set (match_operand:SHORT 0 "register_operand" "=&r") ++ (unspec_volatile:SHORT ++ [(match_operand:SHORT 1 "memory_operand" "+A") ++ (match_operand:SI 3 "const_int_operand")] ;; model ++ UNSPEC_SYNC_EXCHANGE_SUBWORD)) ++ (set (match_dup 1) ++ (match_operand:SHORT 2 "register_operand" "0"))] ++ "TARGET_ATOMIC && TARGET_INLINE_SUBWORD_ATOMIC" ++{ ++ rtx old = gen_reg_rtx (SImode); ++ rtx mem = operands[1]; ++ rtx value = operands[2]; ++ rtx aligned_mem = gen_reg_rtx (SImode); ++ rtx shift = gen_reg_rtx (SImode); ++ rtx mask = gen_reg_rtx (SImode); ++ rtx not_mask = gen_reg_rtx (SImode); ++ ++ riscv_subword_address (mem, &aligned_mem, &shift, &mask, ¬_mask); ++ ++ rtx shifted_value = gen_reg_rtx (SImode); ++ riscv_lshift_subword (mode, value, shift, &shifted_value); ++ ++ emit_insn (gen_subword_atomic_exchange_strong (old, aligned_mem, ++ shifted_value, not_mask)); ++ ++ emit_move_insn (old, gen_rtx_ASHIFTRT (SImode, old, ++ gen_lowpart (QImode, shift))); ++ ++ emit_move_insn (operands[0], gen_lowpart (mode, old)); ++ DONE; ++}) ++ ++(define_insn "subword_atomic_exchange_strong" ++ [(set (match_operand:SI 0 "register_operand" "=&r") ;; old value at mem ++ (match_operand:SI 1 "memory_operand" "+A")) ;; mem location ++ (set (match_dup 1) ++ (unspec_volatile:SI ++ [(match_operand:SI 2 "reg_or_0_operand" "rI") ;; value ++ (match_operand:SI 3 "reg_or_0_operand" "rI")] ;; not_mask ++ UNSPEC_SYNC_EXCHANGE_SUBWORD)) ++ (clobber (match_scratch:SI 4 "=&r"))] ;; tmp_1 ++ "TARGET_ATOMIC && TARGET_INLINE_SUBWORD_ATOMIC" ++ { ++ return ++ "1:\;" ++ "lr.w.aq\t%0, %1\;" ++ "and\t%4, %0, %3\;" ++ "or\t%4, %4, %2\;" ++ "sc.w.rl\t%4, %4, %1\;" ++ "bnez\t%4, 1b"; ++ } ++ [(set (attr "length") (const_int 20))]) ++ + (define_insn "atomic_cas_value_strong" + [(set (match_operand:GPR 0 "register_operand" "=&r") + (match_operand:GPR 1 "memory_operand" "+A")) +@@ -152,6 +348,128 @@ + DONE; + }) + ++(define_expand "atomic_compare_and_swap" ++ [(match_operand:SI 0 "register_operand" "") ;; bool output ++ (match_operand:SHORT 1 "register_operand" "") ;; val output ++ (match_operand:SHORT 2 "memory_operand" "") ;; memory ++ (match_operand:SHORT 3 "reg_or_0_operand" "") ;; expected value ++ (match_operand:SHORT 4 "reg_or_0_operand" "") ;; desired value ++ (match_operand:SI 5 "const_int_operand" "") ;; is_weak ++ (match_operand:SI 6 "const_int_operand" "") ;; mod_s ++ (match_operand:SI 7 "const_int_operand" "")] ;; mod_f ++ "TARGET_ATOMIC && TARGET_INLINE_SUBWORD_ATOMIC" ++{ ++ emit_insn (gen_atomic_cas_value_strong (operands[1], operands[2], ++ operands[3], operands[4], ++ operands[6], operands[7])); ++ ++ rtx val = gen_reg_rtx (SImode); ++ if (operands[1] != const0_rtx) ++ emit_insn (gen_rtx_SET (val, gen_rtx_SIGN_EXTEND (SImode, operands[1]))); ++ else ++ emit_insn (gen_rtx_SET (val, const0_rtx)); ++ ++ rtx exp = gen_reg_rtx (SImode); ++ if (operands[3] != const0_rtx) ++ emit_insn (gen_rtx_SET (exp, gen_rtx_SIGN_EXTEND (SImode, operands[3]))); ++ else ++ emit_insn (gen_rtx_SET (exp, const0_rtx)); ++ ++ rtx compare = val; ++ if (exp != const0_rtx) ++ { ++ rtx difference = gen_rtx_MINUS (SImode, val, exp); ++ compare = gen_reg_rtx (SImode); ++ emit_insn (gen_rtx_SET (compare, difference)); ++ } ++ ++ if (word_mode != SImode) ++ { ++ rtx reg = gen_reg_rtx (word_mode); ++ emit_insn (gen_rtx_SET (reg, gen_rtx_SIGN_EXTEND (word_mode, compare))); ++ compare = reg; ++ } ++ ++ emit_insn (gen_rtx_SET (operands[0], gen_rtx_EQ (SImode, compare, const0_rtx))); ++ DONE; ++}) ++ ++(define_expand "atomic_cas_value_strong" ++ [(set (match_operand:SHORT 0 "register_operand" "=&r") ;; val output ++ (match_operand:SHORT 1 "memory_operand" "+A")) ;; memory ++ (set (match_dup 1) ++ (unspec_volatile:SHORT [(match_operand:SHORT 2 "reg_or_0_operand" "rJ") ;; expected val ++ (match_operand:SHORT 3 "reg_or_0_operand" "rJ") ;; desired val ++ (match_operand:SI 4 "const_int_operand") ;; mod_s ++ (match_operand:SI 5 "const_int_operand")] ;; mod_f ++ UNSPEC_COMPARE_AND_SWAP_SUBWORD)) ++ (clobber (match_scratch:SHORT 6 "=&r"))] ++ "TARGET_ATOMIC && TARGET_INLINE_SUBWORD_ATOMIC" ++{ ++ /* We have no QImode/HImode atomics, so form a mask, then use ++ subword_atomic_cas_strong to implement a LR/SC version of the ++ operation. */ ++ ++ /* Logic duplicated in gcc/libgcc/config/riscv/atomic.c for use when inlining ++ is disabled */ ++ ++ rtx old = gen_reg_rtx (SImode); ++ rtx mem = operands[1]; ++ rtx aligned_mem = gen_reg_rtx (SImode); ++ rtx shift = gen_reg_rtx (SImode); ++ rtx mask = gen_reg_rtx (SImode); ++ rtx not_mask = gen_reg_rtx (SImode); ++ ++ riscv_subword_address (mem, &aligned_mem, &shift, &mask, ¬_mask); ++ ++ rtx o = operands[2]; ++ rtx n = operands[3]; ++ rtx shifted_o = gen_reg_rtx (SImode); ++ rtx shifted_n = gen_reg_rtx (SImode); ++ ++ riscv_lshift_subword (mode, o, shift, &shifted_o); ++ riscv_lshift_subword (mode, n, shift, &shifted_n); ++ ++ emit_move_insn (shifted_o, gen_rtx_AND (SImode, shifted_o, mask)); ++ emit_move_insn (shifted_n, gen_rtx_AND (SImode, shifted_n, mask)); ++ ++ emit_insn (gen_subword_atomic_cas_strong (old, aligned_mem, ++ shifted_o, shifted_n, ++ mask, not_mask)); ++ ++ emit_move_insn (old, gen_rtx_ASHIFTRT (SImode, old, ++ gen_lowpart (QImode, shift))); ++ ++ emit_move_insn (operands[0], gen_lowpart(mode, old)); ++ ++ DONE; ++}) ++ ++(define_insn "subword_atomic_cas_strong" ++ [(set (match_operand:SI 0 "register_operand" "=&r") ;; old value at mem ++ (match_operand:SI 1 "memory_operand" "+A")) ;; mem location ++ (set (match_dup 1) ++ (unspec_volatile:SI [(match_operand:SI 2 "reg_or_0_operand" "rJ") ;; o ++ (match_operand:SI 3 "reg_or_0_operand" "rJ")] ;; n ++ UNSPEC_COMPARE_AND_SWAP_SUBWORD)) ++ (match_operand:SI 4 "register_operand" "rI") ;; mask ++ (match_operand:SI 5 "register_operand" "rI") ;; not_mask ++ (clobber (match_scratch:SI 6 "=&r"))] ;; tmp_1 ++ "TARGET_ATOMIC && TARGET_INLINE_SUBWORD_ATOMIC" ++ { ++ return ++ "1:\;" ++ "lr.w.aq\t%0, %1\;" ++ "and\t%6, %0, %4\;" ++ "bne\t%6, %z2, 1f\;" ++ "and\t%6, %0, %5\;" ++ "or\t%6, %6, %3\;" ++ "sc.w.rl\t%6, %6, %1\;" ++ "bnez\t%6, 1b\;" ++ "1:"; ++ } ++ [(set (attr "length") (const_int 28))]) ++ + (define_expand "atomic_test_and_set" + [(match_operand:QI 0 "register_operand" "") ;; bool output + (match_operand:QI 1 "memory_operand" "+A") ;; memory +diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi +index 07b440190c3..44a7f5b47e3 100644 +--- a/gcc/doc/invoke.texi ++++ b/gcc/doc/invoke.texi +@@ -1211,6 +1211,7 @@ See RS/6000 and PowerPC Options. + -mbig-endian -mlittle-endian @gol + -mstack-protector-guard=@var{guard} -mstack-protector-guard-reg=@var{reg} @gol + -mstack-protector-guard-offset=@var{offset}} ++-minline-atomics -mno-inline-atomics @gol + + @emph{RL78 Options} + @gccoptlist{-msim -mmul=none -mmul=g13 -mmul=g14 -mallregs @gol +@@ -28026,6 +28027,12 @@ Do or don't use smaller but slower prologue and epilogue code that uses + library function calls. The default is to use fast inline prologues and + epilogues. + ++@item -minline-atomics ++@itemx -mno-inline-atomics ++@opindex minline-atomics ++Do or don't use smaller but slower subword atomic emulation code that uses ++library function calls. The default is to use fast inline subword atomics. ++ + @item -mshorten-memrefs + @itemx -mno-shorten-memrefs + @opindex mshorten-memrefs +diff --git a/gcc/testsuite/gcc.target/riscv/inline-atomics-1.c b/gcc/testsuite/gcc.target/riscv/inline-atomics-1.c +new file mode 100644 +index 00000000000..5c5623d9b2f +--- /dev/null ++++ b/gcc/testsuite/gcc.target/riscv/inline-atomics-1.c +@@ -0,0 +1,18 @@ ++/* { dg-do compile } */ ++/* { dg-options "-mno-inline-atomics" } */ ++/* { dg-message "note: '__sync_fetch_and_nand' changed semantics in GCC 4.4" "fetch_and_nand" { target *-*-* } 0 } */ ++/* { dg-final { scan-assembler "\tcall\t__sync_fetch_and_add_1" } } */ ++/* { dg-final { scan-assembler "\tcall\t__sync_fetch_and_nand_1" } } */ ++/* { dg-final { scan-assembler "\tcall\t__sync_bool_compare_and_swap_1" } } */ ++ ++char foo; ++char bar; ++char baz; ++ ++int ++main () ++{ ++ __sync_fetch_and_add(&foo, 1); ++ __sync_fetch_and_nand(&bar, 1); ++ __sync_bool_compare_and_swap (&baz, 1, 2); ++} +diff --git a/gcc/testsuite/gcc.target/riscv/inline-atomics-2.c b/gcc/testsuite/gcc.target/riscv/inline-atomics-2.c +new file mode 100644 +index 00000000000..fdce7a5d71f +--- /dev/null ++++ b/gcc/testsuite/gcc.target/riscv/inline-atomics-2.c +@@ -0,0 +1,19 @@ ++/* { dg-do compile } */ ++/* Verify that subword atomics do not generate calls. */ ++/* { dg-options "-minline-atomics" } */ ++/* { dg-message "note: '__sync_fetch_and_nand' changed semantics in GCC 4.4" "fetch_and_nand" { target *-*-* } 0 } */ ++/* { dg-final { scan-assembler-not "\tcall\t__sync_fetch_and_add_1" } } */ ++/* { dg-final { scan-assembler-not "\tcall\t__sync_fetch_and_nand_1" } } */ ++/* { dg-final { scan-assembler-not "\tcall\t__sync_bool_compare_and_swap_1" } } */ ++ ++char foo; ++char bar; ++char baz; ++ ++int ++main () ++{ ++ __sync_fetch_and_add(&foo, 1); ++ __sync_fetch_and_nand(&bar, 1); ++ __sync_bool_compare_and_swap (&baz, 1, 2); ++} +diff --git a/gcc/testsuite/gcc.target/riscv/inline-atomics-3.c b/gcc/testsuite/gcc.target/riscv/inline-atomics-3.c +new file mode 100644 +index 00000000000..709f3734377 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/riscv/inline-atomics-3.c +@@ -0,0 +1,569 @@ ++/* Check all char alignments. */ ++/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-op-1.c */ ++/* Test __atomic routines for existence and proper execution on 1 byte ++ values with each valid memory model. */ ++/* { dg-do run } */ ++/* { dg-options "-minline-atomics -Wno-address-of-packed-member" } */ ++ ++/* Test the execution of the __atomic_*OP builtin routines for a char. */ ++ ++extern void abort(void); ++ ++char count, res; ++const char init = ~0; ++ ++struct A ++{ ++ char a; ++ char b; ++ char c; ++ char d; ++} __attribute__ ((packed)) A; ++ ++/* The fetch_op routines return the original value before the operation. */ ++ ++void ++test_fetch_add (char* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ if (__atomic_fetch_add (v, count, __ATOMIC_RELAXED) != 0) ++ abort (); ++ ++ if (__atomic_fetch_add (v, 1, __ATOMIC_CONSUME) != 1) ++ abort (); ++ ++ if (__atomic_fetch_add (v, count, __ATOMIC_ACQUIRE) != 2) ++ abort (); ++ ++ if (__atomic_fetch_add (v, 1, __ATOMIC_RELEASE) != 3) ++ abort (); ++ ++ if (__atomic_fetch_add (v, count, __ATOMIC_ACQ_REL) != 4) ++ abort (); ++ ++ if (__atomic_fetch_add (v, 1, __ATOMIC_SEQ_CST) != 5) ++ abort (); ++} ++ ++ ++void ++test_fetch_sub (char* v) ++{ ++ *v = res = 20; ++ count = 0; ++ ++ if (__atomic_fetch_sub (v, count + 1, __ATOMIC_RELAXED) != res--) ++ abort (); ++ ++ if (__atomic_fetch_sub (v, 1, __ATOMIC_CONSUME) != res--) ++ abort (); ++ ++ if (__atomic_fetch_sub (v, count + 1, __ATOMIC_ACQUIRE) != res--) ++ abort (); ++ ++ if (__atomic_fetch_sub (v, 1, __ATOMIC_RELEASE) != res--) ++ abort (); ++ ++ if (__atomic_fetch_sub (v, count + 1, __ATOMIC_ACQ_REL) != res--) ++ abort (); ++ ++ if (__atomic_fetch_sub (v, 1, __ATOMIC_SEQ_CST) != res--) ++ abort (); ++} ++ ++void ++test_fetch_and (char* v) ++{ ++ *v = init; ++ ++ if (__atomic_fetch_and (v, 0, __ATOMIC_RELAXED) != init) ++ abort (); ++ ++ if (__atomic_fetch_and (v, init, __ATOMIC_CONSUME) != 0) ++ abort (); ++ ++ if (__atomic_fetch_and (v, 0, __ATOMIC_ACQUIRE) != 0) ++ abort (); ++ ++ *v = ~*v; ++ if (__atomic_fetch_and (v, init, __ATOMIC_RELEASE) != init) ++ abort (); ++ ++ if (__atomic_fetch_and (v, 0, __ATOMIC_ACQ_REL) != init) ++ abort (); ++ ++ if (__atomic_fetch_and (v, 0, __ATOMIC_SEQ_CST) != 0) ++ abort (); ++} ++ ++void ++test_fetch_nand (char* v) ++{ ++ *v = init; ++ ++ if (__atomic_fetch_nand (v, 0, __ATOMIC_RELAXED) != init) ++ abort (); ++ ++ if (__atomic_fetch_nand (v, init, __ATOMIC_CONSUME) != init) ++ abort (); ++ ++ if (__atomic_fetch_nand (v, 0, __ATOMIC_ACQUIRE) != 0 ) ++ abort (); ++ ++ if (__atomic_fetch_nand (v, init, __ATOMIC_RELEASE) != init) ++ abort (); ++ ++ if (__atomic_fetch_nand (v, init, __ATOMIC_ACQ_REL) != 0) ++ abort (); ++ ++ if (__atomic_fetch_nand (v, 0, __ATOMIC_SEQ_CST) != init) ++ abort (); ++} ++ ++void ++test_fetch_xor (char* v) ++{ ++ *v = init; ++ count = 0; ++ ++ if (__atomic_fetch_xor (v, count, __ATOMIC_RELAXED) != init) ++ abort (); ++ ++ if (__atomic_fetch_xor (v, ~count, __ATOMIC_CONSUME) != init) ++ abort (); ++ ++ if (__atomic_fetch_xor (v, 0, __ATOMIC_ACQUIRE) != 0) ++ abort (); ++ ++ if (__atomic_fetch_xor (v, ~count, __ATOMIC_RELEASE) != 0) ++ abort (); ++ ++ if (__atomic_fetch_xor (v, 0, __ATOMIC_ACQ_REL) != init) ++ abort (); ++ ++ if (__atomic_fetch_xor (v, ~count, __ATOMIC_SEQ_CST) != init) ++ abort (); ++} ++ ++void ++test_fetch_or (char* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ if (__atomic_fetch_or (v, count, __ATOMIC_RELAXED) != 0) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_fetch_or (v, 2, __ATOMIC_CONSUME) != 1) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_fetch_or (v, count, __ATOMIC_ACQUIRE) != 3) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_fetch_or (v, 8, __ATOMIC_RELEASE) != 7) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_fetch_or (v, count, __ATOMIC_ACQ_REL) != 15) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_fetch_or (v, count, __ATOMIC_SEQ_CST) != 31) ++ abort (); ++} ++ ++/* The OP_fetch routines return the new value after the operation. */ ++ ++void ++test_add_fetch (char* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ if (__atomic_add_fetch (v, count, __ATOMIC_RELAXED) != 1) ++ abort (); ++ ++ if (__atomic_add_fetch (v, 1, __ATOMIC_CONSUME) != 2) ++ abort (); ++ ++ if (__atomic_add_fetch (v, count, __ATOMIC_ACQUIRE) != 3) ++ abort (); ++ ++ if (__atomic_add_fetch (v, 1, __ATOMIC_RELEASE) != 4) ++ abort (); ++ ++ if (__atomic_add_fetch (v, count, __ATOMIC_ACQ_REL) != 5) ++ abort (); ++ ++ if (__atomic_add_fetch (v, count, __ATOMIC_SEQ_CST) != 6) ++ abort (); ++} ++ ++ ++void ++test_sub_fetch (char* v) ++{ ++ *v = res = 20; ++ count = 0; ++ ++ if (__atomic_sub_fetch (v, count + 1, __ATOMIC_RELAXED) != --res) ++ abort (); ++ ++ if (__atomic_sub_fetch (v, 1, __ATOMIC_CONSUME) != --res) ++ abort (); ++ ++ if (__atomic_sub_fetch (v, count + 1, __ATOMIC_ACQUIRE) != --res) ++ abort (); ++ ++ if (__atomic_sub_fetch (v, 1, __ATOMIC_RELEASE) != --res) ++ abort (); ++ ++ if (__atomic_sub_fetch (v, count + 1, __ATOMIC_ACQ_REL) != --res) ++ abort (); ++ ++ if (__atomic_sub_fetch (v, count + 1, __ATOMIC_SEQ_CST) != --res) ++ abort (); ++} ++ ++void ++test_and_fetch (char* v) ++{ ++ *v = init; ++ ++ if (__atomic_and_fetch (v, 0, __ATOMIC_RELAXED) != 0) ++ abort (); ++ ++ *v = init; ++ if (__atomic_and_fetch (v, init, __ATOMIC_CONSUME) != init) ++ abort (); ++ ++ if (__atomic_and_fetch (v, 0, __ATOMIC_ACQUIRE) != 0) ++ abort (); ++ ++ *v = ~*v; ++ if (__atomic_and_fetch (v, init, __ATOMIC_RELEASE) != init) ++ abort (); ++ ++ if (__atomic_and_fetch (v, 0, __ATOMIC_ACQ_REL) != 0) ++ abort (); ++ ++ *v = ~*v; ++ if (__atomic_and_fetch (v, 0, __ATOMIC_SEQ_CST) != 0) ++ abort (); ++} ++ ++void ++test_nand_fetch (char* v) ++{ ++ *v = init; ++ ++ if (__atomic_nand_fetch (v, 0, __ATOMIC_RELAXED) != init) ++ abort (); ++ ++ if (__atomic_nand_fetch (v, init, __ATOMIC_CONSUME) != 0) ++ abort (); ++ ++ if (__atomic_nand_fetch (v, 0, __ATOMIC_ACQUIRE) != init) ++ abort (); ++ ++ if (__atomic_nand_fetch (v, init, __ATOMIC_RELEASE) != 0) ++ abort (); ++ ++ if (__atomic_nand_fetch (v, init, __ATOMIC_ACQ_REL) != init) ++ abort (); ++ ++ if (__atomic_nand_fetch (v, 0, __ATOMIC_SEQ_CST) != init) ++ abort (); ++} ++ ++ ++ ++void ++test_xor_fetch (char* v) ++{ ++ *v = init; ++ count = 0; ++ ++ if (__atomic_xor_fetch (v, count, __ATOMIC_RELAXED) != init) ++ abort (); ++ ++ if (__atomic_xor_fetch (v, ~count, __ATOMIC_CONSUME) != 0) ++ abort (); ++ ++ if (__atomic_xor_fetch (v, 0, __ATOMIC_ACQUIRE) != 0) ++ abort (); ++ ++ if (__atomic_xor_fetch (v, ~count, __ATOMIC_RELEASE) != init) ++ abort (); ++ ++ if (__atomic_xor_fetch (v, 0, __ATOMIC_ACQ_REL) != init) ++ abort (); ++ ++ if (__atomic_xor_fetch (v, ~count, __ATOMIC_SEQ_CST) != 0) ++ abort (); ++} ++ ++void ++test_or_fetch (char* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ if (__atomic_or_fetch (v, count, __ATOMIC_RELAXED) != 1) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_or_fetch (v, 2, __ATOMIC_CONSUME) != 3) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_or_fetch (v, count, __ATOMIC_ACQUIRE) != 7) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_or_fetch (v, 8, __ATOMIC_RELEASE) != 15) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_or_fetch (v, count, __ATOMIC_ACQ_REL) != 31) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_or_fetch (v, count, __ATOMIC_SEQ_CST) != 63) ++ abort (); ++} ++ ++ ++/* Test the OP routines with a result which isn't used. Use both variations ++ within each function. */ ++ ++void ++test_add (char* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ __atomic_add_fetch (v, count, __ATOMIC_RELAXED); ++ if (*v != 1) ++ abort (); ++ ++ __atomic_fetch_add (v, count, __ATOMIC_CONSUME); ++ if (*v != 2) ++ abort (); ++ ++ __atomic_add_fetch (v, 1 , __ATOMIC_ACQUIRE); ++ if (*v != 3) ++ abort (); ++ ++ __atomic_fetch_add (v, 1, __ATOMIC_RELEASE); ++ if (*v != 4) ++ abort (); ++ ++ __atomic_add_fetch (v, count, __ATOMIC_ACQ_REL); ++ if (*v != 5) ++ abort (); ++ ++ __atomic_fetch_add (v, count, __ATOMIC_SEQ_CST); ++ if (*v != 6) ++ abort (); ++} ++ ++ ++void ++test_sub (char* v) ++{ ++ *v = res = 20; ++ count = 0; ++ ++ __atomic_sub_fetch (v, count + 1, __ATOMIC_RELAXED); ++ if (*v != --res) ++ abort (); ++ ++ __atomic_fetch_sub (v, count + 1, __ATOMIC_CONSUME); ++ if (*v != --res) ++ abort (); ++ ++ __atomic_sub_fetch (v, 1, __ATOMIC_ACQUIRE); ++ if (*v != --res) ++ abort (); ++ ++ __atomic_fetch_sub (v, 1, __ATOMIC_RELEASE); ++ if (*v != --res) ++ abort (); ++ ++ __atomic_sub_fetch (v, count + 1, __ATOMIC_ACQ_REL); ++ if (*v != --res) ++ abort (); ++ ++ __atomic_fetch_sub (v, count + 1, __ATOMIC_SEQ_CST); ++ if (*v != --res) ++ abort (); ++} ++ ++void ++test_and (char* v) ++{ ++ *v = init; ++ ++ __atomic_and_fetch (v, 0, __ATOMIC_RELAXED); ++ if (*v != 0) ++ abort (); ++ ++ *v = init; ++ __atomic_fetch_and (v, init, __ATOMIC_CONSUME); ++ if (*v != init) ++ abort (); ++ ++ __atomic_and_fetch (v, 0, __ATOMIC_ACQUIRE); ++ if (*v != 0) ++ abort (); ++ ++ *v = ~*v; ++ __atomic_fetch_and (v, init, __ATOMIC_RELEASE); ++ if (*v != init) ++ abort (); ++ ++ __atomic_and_fetch (v, 0, __ATOMIC_ACQ_REL); ++ if (*v != 0) ++ abort (); ++ ++ *v = ~*v; ++ __atomic_fetch_and (v, 0, __ATOMIC_SEQ_CST); ++ if (*v != 0) ++ abort (); ++} ++ ++void ++test_nand (char* v) ++{ ++ *v = init; ++ ++ __atomic_fetch_nand (v, 0, __ATOMIC_RELAXED); ++ if (*v != init) ++ abort (); ++ ++ __atomic_fetch_nand (v, init, __ATOMIC_CONSUME); ++ if (*v != 0) ++ abort (); ++ ++ __atomic_nand_fetch (v, 0, __ATOMIC_ACQUIRE); ++ if (*v != init) ++ abort (); ++ ++ __atomic_nand_fetch (v, init, __ATOMIC_RELEASE); ++ if (*v != 0) ++ abort (); ++ ++ __atomic_fetch_nand (v, init, __ATOMIC_ACQ_REL); ++ if (*v != init) ++ abort (); ++ ++ __atomic_nand_fetch (v, 0, __ATOMIC_SEQ_CST); ++ if (*v != init) ++ abort (); ++} ++ ++ ++ ++void ++test_xor (char* v) ++{ ++ *v = init; ++ count = 0; ++ ++ __atomic_xor_fetch (v, count, __ATOMIC_RELAXED); ++ if (*v != init) ++ abort (); ++ ++ __atomic_fetch_xor (v, ~count, __ATOMIC_CONSUME); ++ if (*v != 0) ++ abort (); ++ ++ __atomic_xor_fetch (v, 0, __ATOMIC_ACQUIRE); ++ if (*v != 0) ++ abort (); ++ ++ __atomic_fetch_xor (v, ~count, __ATOMIC_RELEASE); ++ if (*v != init) ++ abort (); ++ ++ __atomic_fetch_xor (v, 0, __ATOMIC_ACQ_REL); ++ if (*v != init) ++ abort (); ++ ++ __atomic_xor_fetch (v, ~count, __ATOMIC_SEQ_CST); ++ if (*v != 0) ++ abort (); ++} ++ ++void ++test_or (char* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ __atomic_or_fetch (v, count, __ATOMIC_RELAXED); ++ if (*v != 1) ++ abort (); ++ ++ count *= 2; ++ __atomic_fetch_or (v, count, __ATOMIC_CONSUME); ++ if (*v != 3) ++ abort (); ++ ++ count *= 2; ++ __atomic_or_fetch (v, 4, __ATOMIC_ACQUIRE); ++ if (*v != 7) ++ abort (); ++ ++ count *= 2; ++ __atomic_fetch_or (v, 8, __ATOMIC_RELEASE); ++ if (*v != 15) ++ abort (); ++ ++ count *= 2; ++ __atomic_or_fetch (v, count, __ATOMIC_ACQ_REL); ++ if (*v != 31) ++ abort (); ++ ++ count *= 2; ++ __atomic_fetch_or (v, count, __ATOMIC_SEQ_CST); ++ if (*v != 63) ++ abort (); ++} ++ ++int ++main () ++{ ++ char* V[] = {&A.a, &A.b, &A.c, &A.d}; ++ ++ for (int i = 0; i < 4; i++) { ++ test_fetch_add (V[i]); ++ test_fetch_sub (V[i]); ++ test_fetch_and (V[i]); ++ test_fetch_nand (V[i]); ++ test_fetch_xor (V[i]); ++ test_fetch_or (V[i]); ++ ++ test_add_fetch (V[i]); ++ test_sub_fetch (V[i]); ++ test_and_fetch (V[i]); ++ test_nand_fetch (V[i]); ++ test_xor_fetch (V[i]); ++ test_or_fetch (V[i]); ++ ++ test_add (V[i]); ++ test_sub (V[i]); ++ test_and (V[i]); ++ test_nand (V[i]); ++ test_xor (V[i]); ++ test_or (V[i]); ++ } ++ ++ return 0; ++} +diff --git a/gcc/testsuite/gcc.target/riscv/inline-atomics-4.c b/gcc/testsuite/gcc.target/riscv/inline-atomics-4.c +new file mode 100644 +index 00000000000..eecfaae5cc6 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/riscv/inline-atomics-4.c +@@ -0,0 +1,566 @@ ++/* Check all short alignments. */ ++/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-op-2.c */ ++/* Test __atomic routines for existence and proper execution on 2 byte ++ values with each valid memory model. */ ++/* { dg-do run } */ ++/* { dg-options "-minline-atomics -Wno-address-of-packed-member" } */ ++ ++/* Test the execution of the __atomic_*OP builtin routines for a short. */ ++ ++extern void abort(void); ++ ++short count, res; ++const short init = ~0; ++ ++struct A ++{ ++ short a; ++ short b; ++} __attribute__ ((packed)) A; ++ ++/* The fetch_op routines return the original value before the operation. */ ++ ++void ++test_fetch_add (short* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ if (__atomic_fetch_add (v, count, __ATOMIC_RELAXED) != 0) ++ abort (); ++ ++ if (__atomic_fetch_add (v, 1, __ATOMIC_CONSUME) != 1) ++ abort (); ++ ++ if (__atomic_fetch_add (v, count, __ATOMIC_ACQUIRE) != 2) ++ abort (); ++ ++ if (__atomic_fetch_add (v, 1, __ATOMIC_RELEASE) != 3) ++ abort (); ++ ++ if (__atomic_fetch_add (v, count, __ATOMIC_ACQ_REL) != 4) ++ abort (); ++ ++ if (__atomic_fetch_add (v, 1, __ATOMIC_SEQ_CST) != 5) ++ abort (); ++} ++ ++ ++void ++test_fetch_sub (short* v) ++{ ++ *v = res = 20; ++ count = 0; ++ ++ if (__atomic_fetch_sub (v, count + 1, __ATOMIC_RELAXED) != res--) ++ abort (); ++ ++ if (__atomic_fetch_sub (v, 1, __ATOMIC_CONSUME) != res--) ++ abort (); ++ ++ if (__atomic_fetch_sub (v, count + 1, __ATOMIC_ACQUIRE) != res--) ++ abort (); ++ ++ if (__atomic_fetch_sub (v, 1, __ATOMIC_RELEASE) != res--) ++ abort (); ++ ++ if (__atomic_fetch_sub (v, count + 1, __ATOMIC_ACQ_REL) != res--) ++ abort (); ++ ++ if (__atomic_fetch_sub (v, 1, __ATOMIC_SEQ_CST) != res--) ++ abort (); ++} ++ ++void ++test_fetch_and (short* v) ++{ ++ *v = init; ++ ++ if (__atomic_fetch_and (v, 0, __ATOMIC_RELAXED) != init) ++ abort (); ++ ++ if (__atomic_fetch_and (v, init, __ATOMIC_CONSUME) != 0) ++ abort (); ++ ++ if (__atomic_fetch_and (v, 0, __ATOMIC_ACQUIRE) != 0) ++ abort (); ++ ++ *v = ~*v; ++ if (__atomic_fetch_and (v, init, __ATOMIC_RELEASE) != init) ++ abort (); ++ ++ if (__atomic_fetch_and (v, 0, __ATOMIC_ACQ_REL) != init) ++ abort (); ++ ++ if (__atomic_fetch_and (v, 0, __ATOMIC_SEQ_CST) != 0) ++ abort (); ++} ++ ++void ++test_fetch_nand (short* v) ++{ ++ *v = init; ++ ++ if (__atomic_fetch_nand (v, 0, __ATOMIC_RELAXED) != init) ++ abort (); ++ ++ if (__atomic_fetch_nand (v, init, __ATOMIC_CONSUME) != init) ++ abort (); ++ ++ if (__atomic_fetch_nand (v, 0, __ATOMIC_ACQUIRE) != 0 ) ++ abort (); ++ ++ if (__atomic_fetch_nand (v, init, __ATOMIC_RELEASE) != init) ++ abort (); ++ ++ if (__atomic_fetch_nand (v, init, __ATOMIC_ACQ_REL) != 0) ++ abort (); ++ ++ if (__atomic_fetch_nand (v, 0, __ATOMIC_SEQ_CST) != init) ++ abort (); ++} ++ ++void ++test_fetch_xor (short* v) ++{ ++ *v = init; ++ count = 0; ++ ++ if (__atomic_fetch_xor (v, count, __ATOMIC_RELAXED) != init) ++ abort (); ++ ++ if (__atomic_fetch_xor (v, ~count, __ATOMIC_CONSUME) != init) ++ abort (); ++ ++ if (__atomic_fetch_xor (v, 0, __ATOMIC_ACQUIRE) != 0) ++ abort (); ++ ++ if (__atomic_fetch_xor (v, ~count, __ATOMIC_RELEASE) != 0) ++ abort (); ++ ++ if (__atomic_fetch_xor (v, 0, __ATOMIC_ACQ_REL) != init) ++ abort (); ++ ++ if (__atomic_fetch_xor (v, ~count, __ATOMIC_SEQ_CST) != init) ++ abort (); ++} ++ ++void ++test_fetch_or (short* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ if (__atomic_fetch_or (v, count, __ATOMIC_RELAXED) != 0) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_fetch_or (v, 2, __ATOMIC_CONSUME) != 1) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_fetch_or (v, count, __ATOMIC_ACQUIRE) != 3) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_fetch_or (v, 8, __ATOMIC_RELEASE) != 7) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_fetch_or (v, count, __ATOMIC_ACQ_REL) != 15) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_fetch_or (v, count, __ATOMIC_SEQ_CST) != 31) ++ abort (); ++} ++ ++/* The OP_fetch routines return the new value after the operation. */ ++ ++void ++test_add_fetch (short* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ if (__atomic_add_fetch (v, count, __ATOMIC_RELAXED) != 1) ++ abort (); ++ ++ if (__atomic_add_fetch (v, 1, __ATOMIC_CONSUME) != 2) ++ abort (); ++ ++ if (__atomic_add_fetch (v, count, __ATOMIC_ACQUIRE) != 3) ++ abort (); ++ ++ if (__atomic_add_fetch (v, 1, __ATOMIC_RELEASE) != 4) ++ abort (); ++ ++ if (__atomic_add_fetch (v, count, __ATOMIC_ACQ_REL) != 5) ++ abort (); ++ ++ if (__atomic_add_fetch (v, count, __ATOMIC_SEQ_CST) != 6) ++ abort (); ++} ++ ++ ++void ++test_sub_fetch (short* v) ++{ ++ *v = res = 20; ++ count = 0; ++ ++ if (__atomic_sub_fetch (v, count + 1, __ATOMIC_RELAXED) != --res) ++ abort (); ++ ++ if (__atomic_sub_fetch (v, 1, __ATOMIC_CONSUME) != --res) ++ abort (); ++ ++ if (__atomic_sub_fetch (v, count + 1, __ATOMIC_ACQUIRE) != --res) ++ abort (); ++ ++ if (__atomic_sub_fetch (v, 1, __ATOMIC_RELEASE) != --res) ++ abort (); ++ ++ if (__atomic_sub_fetch (v, count + 1, __ATOMIC_ACQ_REL) != --res) ++ abort (); ++ ++ if (__atomic_sub_fetch (v, count + 1, __ATOMIC_SEQ_CST) != --res) ++ abort (); ++} ++ ++void ++test_and_fetch (short* v) ++{ ++ *v = init; ++ ++ if (__atomic_and_fetch (v, 0, __ATOMIC_RELAXED) != 0) ++ abort (); ++ ++ *v = init; ++ if (__atomic_and_fetch (v, init, __ATOMIC_CONSUME) != init) ++ abort (); ++ ++ if (__atomic_and_fetch (v, 0, __ATOMIC_ACQUIRE) != 0) ++ abort (); ++ ++ *v = ~*v; ++ if (__atomic_and_fetch (v, init, __ATOMIC_RELEASE) != init) ++ abort (); ++ ++ if (__atomic_and_fetch (v, 0, __ATOMIC_ACQ_REL) != 0) ++ abort (); ++ ++ *v = ~*v; ++ if (__atomic_and_fetch (v, 0, __ATOMIC_SEQ_CST) != 0) ++ abort (); ++} ++ ++void ++test_nand_fetch (short* v) ++{ ++ *v = init; ++ ++ if (__atomic_nand_fetch (v, 0, __ATOMIC_RELAXED) != init) ++ abort (); ++ ++ if (__atomic_nand_fetch (v, init, __ATOMIC_CONSUME) != 0) ++ abort (); ++ ++ if (__atomic_nand_fetch (v, 0, __ATOMIC_ACQUIRE) != init) ++ abort (); ++ ++ if (__atomic_nand_fetch (v, init, __ATOMIC_RELEASE) != 0) ++ abort (); ++ ++ if (__atomic_nand_fetch (v, init, __ATOMIC_ACQ_REL) != init) ++ abort (); ++ ++ if (__atomic_nand_fetch (v, 0, __ATOMIC_SEQ_CST) != init) ++ abort (); ++} ++ ++ ++ ++void ++test_xor_fetch (short* v) ++{ ++ *v = init; ++ count = 0; ++ ++ if (__atomic_xor_fetch (v, count, __ATOMIC_RELAXED) != init) ++ abort (); ++ ++ if (__atomic_xor_fetch (v, ~count, __ATOMIC_CONSUME) != 0) ++ abort (); ++ ++ if (__atomic_xor_fetch (v, 0, __ATOMIC_ACQUIRE) != 0) ++ abort (); ++ ++ if (__atomic_xor_fetch (v, ~count, __ATOMIC_RELEASE) != init) ++ abort (); ++ ++ if (__atomic_xor_fetch (v, 0, __ATOMIC_ACQ_REL) != init) ++ abort (); ++ ++ if (__atomic_xor_fetch (v, ~count, __ATOMIC_SEQ_CST) != 0) ++ abort (); ++} ++ ++void ++test_or_fetch (short* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ if (__atomic_or_fetch (v, count, __ATOMIC_RELAXED) != 1) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_or_fetch (v, 2, __ATOMIC_CONSUME) != 3) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_or_fetch (v, count, __ATOMIC_ACQUIRE) != 7) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_or_fetch (v, 8, __ATOMIC_RELEASE) != 15) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_or_fetch (v, count, __ATOMIC_ACQ_REL) != 31) ++ abort (); ++ ++ count *= 2; ++ if (__atomic_or_fetch (v, count, __ATOMIC_SEQ_CST) != 63) ++ abort (); ++} ++ ++ ++/* Test the OP routines with a result which isn't used. Use both variations ++ within each function. */ ++ ++void ++test_add (short* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ __atomic_add_fetch (v, count, __ATOMIC_RELAXED); ++ if (*v != 1) ++ abort (); ++ ++ __atomic_fetch_add (v, count, __ATOMIC_CONSUME); ++ if (*v != 2) ++ abort (); ++ ++ __atomic_add_fetch (v, 1 , __ATOMIC_ACQUIRE); ++ if (*v != 3) ++ abort (); ++ ++ __atomic_fetch_add (v, 1, __ATOMIC_RELEASE); ++ if (*v != 4) ++ abort (); ++ ++ __atomic_add_fetch (v, count, __ATOMIC_ACQ_REL); ++ if (*v != 5) ++ abort (); ++ ++ __atomic_fetch_add (v, count, __ATOMIC_SEQ_CST); ++ if (*v != 6) ++ abort (); ++} ++ ++ ++void ++test_sub (short* v) ++{ ++ *v = res = 20; ++ count = 0; ++ ++ __atomic_sub_fetch (v, count + 1, __ATOMIC_RELAXED); ++ if (*v != --res) ++ abort (); ++ ++ __atomic_fetch_sub (v, count + 1, __ATOMIC_CONSUME); ++ if (*v != --res) ++ abort (); ++ ++ __atomic_sub_fetch (v, 1, __ATOMIC_ACQUIRE); ++ if (*v != --res) ++ abort (); ++ ++ __atomic_fetch_sub (v, 1, __ATOMIC_RELEASE); ++ if (*v != --res) ++ abort (); ++ ++ __atomic_sub_fetch (v, count + 1, __ATOMIC_ACQ_REL); ++ if (*v != --res) ++ abort (); ++ ++ __atomic_fetch_sub (v, count + 1, __ATOMIC_SEQ_CST); ++ if (*v != --res) ++ abort (); ++} ++ ++void ++test_and (short* v) ++{ ++ *v = init; ++ ++ __atomic_and_fetch (v, 0, __ATOMIC_RELAXED); ++ if (*v != 0) ++ abort (); ++ ++ *v = init; ++ __atomic_fetch_and (v, init, __ATOMIC_CONSUME); ++ if (*v != init) ++ abort (); ++ ++ __atomic_and_fetch (v, 0, __ATOMIC_ACQUIRE); ++ if (*v != 0) ++ abort (); ++ ++ *v = ~*v; ++ __atomic_fetch_and (v, init, __ATOMIC_RELEASE); ++ if (*v != init) ++ abort (); ++ ++ __atomic_and_fetch (v, 0, __ATOMIC_ACQ_REL); ++ if (*v != 0) ++ abort (); ++ ++ *v = ~*v; ++ __atomic_fetch_and (v, 0, __ATOMIC_SEQ_CST); ++ if (*v != 0) ++ abort (); ++} ++ ++void ++test_nand (short* v) ++{ ++ *v = init; ++ ++ __atomic_fetch_nand (v, 0, __ATOMIC_RELAXED); ++ if (*v != init) ++ abort (); ++ ++ __atomic_fetch_nand (v, init, __ATOMIC_CONSUME); ++ if (*v != 0) ++ abort (); ++ ++ __atomic_nand_fetch (v, 0, __ATOMIC_ACQUIRE); ++ if (*v != init) ++ abort (); ++ ++ __atomic_nand_fetch (v, init, __ATOMIC_RELEASE); ++ if (*v != 0) ++ abort (); ++ ++ __atomic_fetch_nand (v, init, __ATOMIC_ACQ_REL); ++ if (*v != init) ++ abort (); ++ ++ __atomic_nand_fetch (v, 0, __ATOMIC_SEQ_CST); ++ if (*v != init) ++ abort (); ++} ++ ++ ++ ++void ++test_xor (short* v) ++{ ++ *v = init; ++ count = 0; ++ ++ __atomic_xor_fetch (v, count, __ATOMIC_RELAXED); ++ if (*v != init) ++ abort (); ++ ++ __atomic_fetch_xor (v, ~count, __ATOMIC_CONSUME); ++ if (*v != 0) ++ abort (); ++ ++ __atomic_xor_fetch (v, 0, __ATOMIC_ACQUIRE); ++ if (*v != 0) ++ abort (); ++ ++ __atomic_fetch_xor (v, ~count, __ATOMIC_RELEASE); ++ if (*v != init) ++ abort (); ++ ++ __atomic_fetch_xor (v, 0, __ATOMIC_ACQ_REL); ++ if (*v != init) ++ abort (); ++ ++ __atomic_xor_fetch (v, ~count, __ATOMIC_SEQ_CST); ++ if (*v != 0) ++ abort (); ++} ++ ++void ++test_or (short* v) ++{ ++ *v = 0; ++ count = 1; ++ ++ __atomic_or_fetch (v, count, __ATOMIC_RELAXED); ++ if (*v != 1) ++ abort (); ++ ++ count *= 2; ++ __atomic_fetch_or (v, count, __ATOMIC_CONSUME); ++ if (*v != 3) ++ abort (); ++ ++ count *= 2; ++ __atomic_or_fetch (v, 4, __ATOMIC_ACQUIRE); ++ if (*v != 7) ++ abort (); ++ ++ count *= 2; ++ __atomic_fetch_or (v, 8, __ATOMIC_RELEASE); ++ if (*v != 15) ++ abort (); ++ ++ count *= 2; ++ __atomic_or_fetch (v, count, __ATOMIC_ACQ_REL); ++ if (*v != 31) ++ abort (); ++ ++ count *= 2; ++ __atomic_fetch_or (v, count, __ATOMIC_SEQ_CST); ++ if (*v != 63) ++ abort (); ++} ++ ++int ++main () { ++ short* V[] = {&A.a, &A.b}; ++ ++ for (int i = 0; i < 2; i++) { ++ test_fetch_add (V[i]); ++ test_fetch_sub (V[i]); ++ test_fetch_and (V[i]); ++ test_fetch_nand (V[i]); ++ test_fetch_xor (V[i]); ++ test_fetch_or (V[i]); ++ ++ test_add_fetch (V[i]); ++ test_sub_fetch (V[i]); ++ test_and_fetch (V[i]); ++ test_nand_fetch (V[i]); ++ test_xor_fetch (V[i]); ++ test_or_fetch (V[i]); ++ ++ test_add (V[i]); ++ test_sub (V[i]); ++ test_and (V[i]); ++ test_nand (V[i]); ++ test_xor (V[i]); ++ test_or (V[i]); ++ } ++ ++ return 0; ++} +diff --git a/gcc/testsuite/gcc.target/riscv/inline-atomics-5.c b/gcc/testsuite/gcc.target/riscv/inline-atomics-5.c +new file mode 100644 +index 00000000000..52093894a79 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/riscv/inline-atomics-5.c +@@ -0,0 +1,87 @@ ++/* Test __atomic routines for existence and proper execution on 1 byte ++ values with each valid memory model. */ ++/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-compare-exchange-1.c */ ++/* { dg-do run } */ ++/* { dg-options "-minline-atomics" } */ ++ ++/* Test the execution of the __atomic_compare_exchange_n builtin for a char. */ ++ ++extern void abort(void); ++ ++char v = 0; ++char expected = 0; ++char max = ~0; ++char desired = ~0; ++char zero = 0; ++ ++#define STRONG 0 ++#define WEAK 1 ++ ++int ++main () ++{ ++ ++ if (!__atomic_compare_exchange_n (&v, &expected, max, STRONG , __ATOMIC_RELAXED, __ATOMIC_RELAXED)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ ++ if (__atomic_compare_exchange_n (&v, &expected, 0, STRONG , __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) ++ abort (); ++ if (expected != max) ++ abort (); ++ ++ if (!__atomic_compare_exchange_n (&v, &expected, 0, STRONG , __ATOMIC_RELEASE, __ATOMIC_ACQUIRE)) ++ abort (); ++ if (expected != max) ++ abort (); ++ if (v != 0) ++ abort (); ++ ++ if (__atomic_compare_exchange_n (&v, &expected, desired, WEAK, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ ++ if (!__atomic_compare_exchange_n (&v, &expected, desired, STRONG , __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ if (v != max) ++ abort (); ++ ++ /* Now test the generic version. */ ++ ++ v = 0; ++ ++ if (!__atomic_compare_exchange (&v, &expected, &max, STRONG, __ATOMIC_RELAXED, __ATOMIC_RELAXED)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ ++ if (__atomic_compare_exchange (&v, &expected, &zero, STRONG , __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) ++ abort (); ++ if (expected != max) ++ abort (); ++ ++ if (!__atomic_compare_exchange (&v, &expected, &zero, STRONG , __ATOMIC_RELEASE, __ATOMIC_ACQUIRE)) ++ abort (); ++ if (expected != max) ++ abort (); ++ if (v != 0) ++ abort (); ++ ++ if (__atomic_compare_exchange (&v, &expected, &desired, WEAK, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ ++ if (!__atomic_compare_exchange (&v, &expected, &desired, STRONG , __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ if (v != max) ++ abort (); ++ ++ return 0; ++} +diff --git a/gcc/testsuite/gcc.target/riscv/inline-atomics-6.c b/gcc/testsuite/gcc.target/riscv/inline-atomics-6.c +new file mode 100644 +index 00000000000..8fee8c44811 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/riscv/inline-atomics-6.c +@@ -0,0 +1,87 @@ ++/* Test __atomic routines for existence and proper execution on 2 byte ++ values with each valid memory model. */ ++/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-compare-exchange-2.c */ ++/* { dg-do run } */ ++/* { dg-options "-minline-atomics" } */ ++ ++/* Test the execution of the __atomic_compare_exchange_n builtin for a short. */ ++ ++extern void abort(void); ++ ++short v = 0; ++short expected = 0; ++short max = ~0; ++short desired = ~0; ++short zero = 0; ++ ++#define STRONG 0 ++#define WEAK 1 ++ ++int ++main () ++{ ++ ++ if (!__atomic_compare_exchange_n (&v, &expected, max, STRONG , __ATOMIC_RELAXED, __ATOMIC_RELAXED)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ ++ if (__atomic_compare_exchange_n (&v, &expected, 0, STRONG , __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) ++ abort (); ++ if (expected != max) ++ abort (); ++ ++ if (!__atomic_compare_exchange_n (&v, &expected, 0, STRONG , __ATOMIC_RELEASE, __ATOMIC_ACQUIRE)) ++ abort (); ++ if (expected != max) ++ abort (); ++ if (v != 0) ++ abort (); ++ ++ if (__atomic_compare_exchange_n (&v, &expected, desired, WEAK, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ ++ if (!__atomic_compare_exchange_n (&v, &expected, desired, STRONG , __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ if (v != max) ++ abort (); ++ ++ /* Now test the generic version. */ ++ ++ v = 0; ++ ++ if (!__atomic_compare_exchange (&v, &expected, &max, STRONG, __ATOMIC_RELAXED, __ATOMIC_RELAXED)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ ++ if (__atomic_compare_exchange (&v, &expected, &zero, STRONG , __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) ++ abort (); ++ if (expected != max) ++ abort (); ++ ++ if (!__atomic_compare_exchange (&v, &expected, &zero, STRONG , __ATOMIC_RELEASE, __ATOMIC_ACQUIRE)) ++ abort (); ++ if (expected != max) ++ abort (); ++ if (v != 0) ++ abort (); ++ ++ if (__atomic_compare_exchange (&v, &expected, &desired, WEAK, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ ++ if (!__atomic_compare_exchange (&v, &expected, &desired, STRONG , __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) ++ abort (); ++ if (expected != 0) ++ abort (); ++ if (v != max) ++ abort (); ++ ++ return 0; ++} +diff --git a/gcc/testsuite/gcc.target/riscv/inline-atomics-7.c b/gcc/testsuite/gcc.target/riscv/inline-atomics-7.c +new file mode 100644 +index 00000000000..24c344c0ce3 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/riscv/inline-atomics-7.c +@@ -0,0 +1,69 @@ ++/* Test __atomic routines for existence and proper execution on 1 byte ++ values with each valid memory model. */ ++/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-exchange-1.c */ ++/* { dg-do run } */ ++/* { dg-options "-minline-atomics" } */ ++ ++/* Test the execution of the __atomic_exchange_n builtin for a char. */ ++ ++extern void abort(void); ++ ++char v, count, ret; ++ ++int ++main () ++{ ++ v = 0; ++ count = 0; ++ ++ if (__atomic_exchange_n (&v, count + 1, __ATOMIC_RELAXED) != count) ++ abort (); ++ count++; ++ ++ if (__atomic_exchange_n (&v, count + 1, __ATOMIC_ACQUIRE) != count) ++ abort (); ++ count++; ++ ++ if (__atomic_exchange_n (&v, count + 1, __ATOMIC_RELEASE) != count) ++ abort (); ++ count++; ++ ++ if (__atomic_exchange_n (&v, count + 1, __ATOMIC_ACQ_REL) != count) ++ abort (); ++ count++; ++ ++ if (__atomic_exchange_n (&v, count + 1, __ATOMIC_SEQ_CST) != count) ++ abort (); ++ count++; ++ ++ /* Now test the generic version. */ ++ ++ count++; ++ ++ __atomic_exchange (&v, &count, &ret, __ATOMIC_RELAXED); ++ if (ret != count - 1 || v != count) ++ abort (); ++ count++; ++ ++ __atomic_exchange (&v, &count, &ret, __ATOMIC_ACQUIRE); ++ if (ret != count - 1 || v != count) ++ abort (); ++ count++; ++ ++ __atomic_exchange (&v, &count, &ret, __ATOMIC_RELEASE); ++ if (ret != count - 1 || v != count) ++ abort (); ++ count++; ++ ++ __atomic_exchange (&v, &count, &ret, __ATOMIC_ACQ_REL); ++ if (ret != count - 1 || v != count) ++ abort (); ++ count++; ++ ++ __atomic_exchange (&v, &count, &ret, __ATOMIC_SEQ_CST); ++ if (ret != count - 1 || v != count) ++ abort (); ++ count++; ++ ++ return 0; ++} +diff --git a/gcc/testsuite/gcc.target/riscv/inline-atomics-8.c b/gcc/testsuite/gcc.target/riscv/inline-atomics-8.c +new file mode 100644 +index 00000000000..edc212df04e +--- /dev/null ++++ b/gcc/testsuite/gcc.target/riscv/inline-atomics-8.c +@@ -0,0 +1,69 @@ ++/* Test __atomic routines for existence and proper execution on 2 byte ++ values with each valid memory model. */ ++/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-exchange-2.c */ ++/* { dg-do run } */ ++/* { dg-options "-minline-atomics" } */ ++ ++/* Test the execution of the __atomic_X builtin for a short. */ ++ ++extern void abort(void); ++ ++short v, count, ret; ++ ++int ++main () ++{ ++ v = 0; ++ count = 0; ++ ++ if (__atomic_exchange_n (&v, count + 1, __ATOMIC_RELAXED) != count) ++ abort (); ++ count++; ++ ++ if (__atomic_exchange_n (&v, count + 1, __ATOMIC_ACQUIRE) != count) ++ abort (); ++ count++; ++ ++ if (__atomic_exchange_n (&v, count + 1, __ATOMIC_RELEASE) != count) ++ abort (); ++ count++; ++ ++ if (__atomic_exchange_n (&v, count + 1, __ATOMIC_ACQ_REL) != count) ++ abort (); ++ count++; ++ ++ if (__atomic_exchange_n (&v, count + 1, __ATOMIC_SEQ_CST) != count) ++ abort (); ++ count++; ++ ++ /* Now test the generic version. */ ++ ++ count++; ++ ++ __atomic_exchange (&v, &count, &ret, __ATOMIC_RELAXED); ++ if (ret != count - 1 || v != count) ++ abort (); ++ count++; ++ ++ __atomic_exchange (&v, &count, &ret, __ATOMIC_ACQUIRE); ++ if (ret != count - 1 || v != count) ++ abort (); ++ count++; ++ ++ __atomic_exchange (&v, &count, &ret, __ATOMIC_RELEASE); ++ if (ret != count - 1 || v != count) ++ abort (); ++ count++; ++ ++ __atomic_exchange (&v, &count, &ret, __ATOMIC_ACQ_REL); ++ if (ret != count - 1 || v != count) ++ abort (); ++ count++; ++ ++ __atomic_exchange (&v, &count, &ret, __ATOMIC_SEQ_CST); ++ if (ret != count - 1 || v != count) ++ abort (); ++ count++; ++ ++ return 0; ++} +diff --git a/libgcc/config/riscv/atomic.c b/libgcc/config/riscv/atomic.c +index 7007e7a20e4..a29909b97b5 100644 +--- a/libgcc/config/riscv/atomic.c ++++ b/libgcc/config/riscv/atomic.c +@@ -30,6 +30,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + #define INVERT "not %[tmp1], %[tmp1]\n\t" + #define DONT_INVERT "" + ++/* Logic duplicated in gcc/gcc/config/riscv/sync.md for use when inlining is enabled */ ++ + #define GENERATE_FETCH_AND_OP(type, size, opname, insn, invert, cop) \ + type __sync_fetch_and_ ## opname ## _ ## size (type *p, type v) \ + { \ +-- +2.35.2 + diff --git a/gcc12-riscv-pthread.patch b/gcc12-riscv-pthread.patch new file mode 100644 index 0000000..8d5786a --- /dev/null +++ b/gcc12-riscv-pthread.patch @@ -0,0 +1,21 @@ +Index: gcc-12.0.1+git192423/gcc/config/riscv/linux.h +=================================================================== +--- gcc-12.0.1+git192423.orig/gcc/config/riscv/linux.h ++++ gcc-12.0.1+git192423/gcc/config/riscv/linux.h +@@ -35,16 +35,6 @@ along with GCC; see the file COPYING3. + #undef MUSL_DYNAMIC_LINKER + #define MUSL_DYNAMIC_LINKER "/lib/ld-musl-riscv" XLEN_SPEC MUSL_ABI_SUFFIX ".so.1" + +-/* Because RISC-V only has word-sized atomics, it requries libatomic where +- others do not. So link libatomic by default, as needed. */ +-#undef LIB_SPEC +-#ifdef LD_AS_NEEDED_OPTION +-#define LIB_SPEC GNU_USER_TARGET_LIB_SPEC \ +- " %{pthread:" LD_AS_NEEDED_OPTION " -latomic " LD_NO_AS_NEEDED_OPTION "}" +-#else +-#define LIB_SPEC GNU_USER_TARGET_LIB_SPEC " -latomic " +-#endif +- + #define ICACHE_FLUSH_FUNC "__riscv_flush_icache" + + #define CPP_SPEC "%{pthread:-D_REENTRANT}" diff --git a/gcc12-rpmlintrc b/gcc12-rpmlintrc new file mode 100644 index 0000000..2299124 --- /dev/null +++ b/gcc12-rpmlintrc @@ -0,0 +1,19 @@ +# This line is mandatory to access the configuration functions +from Config import * + +# gcc/gcc-c++ are devel packages even if not called -devel... +addFilter ("gcc.*devel-file-in-non-devel-package") +addFilter ("gcc.*devel-dependency glibc-devel") +addFilter ("gcc.*devel-dependency libstdc") +# libstdc++6-devel is the devel package of libstdc++6, no better name exists +# and we do package static libs and the .so links (but in a gcc versioned +# directory) +addFilter ("libstdc.*shlib-policy-missing-lib") +# We have names lib libgcc_s1-gcc7 for non-default GCCs +addFilter ("shlib-policy-name-error") +addFilter ("shlib-legacy-policy-name-error") +# Packages provide libgcc_s1 = $version and conflict with other providers +# of libgcc_s1 +addFilter ("conflicts-with-provides") +# SLE12 rpmlint complains about valid SPDX licenses +addFilter ("invalid-license") diff --git a/gcc12-testresults-rpmlintrc b/gcc12-testresults-rpmlintrc new file mode 100644 index 0000000..f5dc018 --- /dev/null +++ b/gcc12-testresults-rpmlintrc @@ -0,0 +1,10 @@ +# This line is mandatory to access the configuration functions +from Config import * + +# Currently gotools.log contains $RPM_BUILD_ROOT and there's nothing +# to be done about that and neither do we care +addFilter ("gcc.*-testresults.*file-contains-buildroot") + +# The package should _not_ be noarch, testresults differ from architecture +# to architecture +addFilter ("gcc.*-testresults.*no-binary") diff --git a/gcc12-testsuite-fixes.patch b/gcc12-testsuite-fixes.patch new file mode 100644 index 0000000..ca53494 --- /dev/null +++ b/gcc12-testsuite-fixes.patch @@ -0,0 +1,187 @@ +From 5f803e68beee9f71c12c112ccda872997919f9cc Mon Sep 17 00:00:00 2001 +From: Richard Biener +Date: Wed, 10 May 2023 15:36:12 +0200 +Subject: [PATCH 1/4] Avoid g++.dg/torture/pr106922.C FAIL with the pre-C++11 + ABI +To: gcc-patches@gcc.gnu.org + +The following forces the g++.dg/torture/pr106922.C testcase to use +the C++11 libstdc++ ABI and checks whether that worked. + +gcc/testsuite/ + * g++.dg/torture/pr106922.C: Force _GLIBCXX_USE_CXX11_ABI to 1. + +(cherry picked from commit a056a9868e6ecab24b0b7e4e12e846097b8c8fb0) +--- + gcc/testsuite/g++.dg/torture/pr106922.C | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/gcc/testsuite/g++.dg/torture/pr106922.C b/gcc/testsuite/g++.dg/torture/pr106922.C +index 046fc6cce76..b0c1489fbdc 100644 +--- a/gcc/testsuite/g++.dg/torture/pr106922.C ++++ b/gcc/testsuite/g++.dg/torture/pr106922.C +@@ -4,8 +4,16 @@ + // -O1 doesn't iterate VN and thus has bogus uninit diagnostics + // { dg-skip-if "" { *-*-* } { "-O1" } { "" } } + ++// The testcase still emits bogus diagnostics with the pre-C++11 ABI ++#undef _GLIBCXX_USE_CXX11_ABI ++#define _GLIBCXX_USE_CXX11_ABI 1 ++ + #include + ++// When the library is not dual-ABI and defaults to old just compile ++// an empty TU ++#if _GLIBCXX_USE_CXX11_ABI ++ + #include + template + using Optional = std::optional; +@@ -46,3 +54,4 @@ void test() + externals.external2 = internal2; + } + } ++#endif +-- +2.35.3 + + +From 35ca946985773e0fa49624d37323e0338a39c5f3 Mon Sep 17 00:00:00 2001 +From: Richard Biener +Date: Thu, 11 May 2023 09:13:31 +0200 +Subject: [PATCH 3/4] testsuite/108776 - avoid c-c++-common/rotate-11.c FAIL +To: gcc-patches@gcc.gnu.org + +On the branch ranger isn't powerful enough to handle some cases +appearing with logical-op-non-short-circuit evaluating to false +causing FAILs of the testcase for ppc64le and s390x. The following +foces logical-op-non-short-circuit to true for this testcase +on the branch. + + PR testsuite/108776 + * c-c++-common/rotate-11.c: Add --param logical-op-non-short-circuit=1. +--- + gcc/testsuite/c-c++-common/rotate-11.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gcc/testsuite/c-c++-common/rotate-11.c b/gcc/testsuite/c-c++-common/rotate-11.c +index e57db19d949..85cde2786e2 100644 +--- a/gcc/testsuite/c-c++-common/rotate-11.c ++++ b/gcc/testsuite/c-c++-common/rotate-11.c +@@ -1,6 +1,6 @@ + /* PR tree-optimization/108440 */ + /* { dg-do compile { target { { ilp32 || lp64 } || llp64 } } } */ +-/* { dg-options "-O2 -fdump-tree-optimized" } */ ++/* { dg-options "-O2 -fdump-tree-optimized --param logical-op-non-short-circuit=1" } */ + /* { dg-final { scan-tree-dump-times " r<< " 5 "optimized" } } */ + /* { dg-final { scan-tree-dump-times " \\\& 7;" 4 "optimized" } } */ + +-- +2.35.3 + + +From 7b4ab70f2d7182f119bc927f15876a3178c0cc14 Mon Sep 17 00:00:00 2001 +From: Richard Biener +Date: Thu, 11 May 2023 09:30:52 +0200 +Subject: [PATCH 4/4] Fix gcc.dg/vect/pr108950.c +To: gcc-patches@gcc.gnu.org + +The following puts the dg-require-effective-target properly after +the dg-do. + + * gcc.dg/vect/pr108950.c: Re-order dg-require-effective-target + and dg-do. +--- + gcc/testsuite/gcc.dg/vect/pr108950.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gcc/testsuite/gcc.dg/vect/pr108950.c b/gcc/testsuite/gcc.dg/vect/pr108950.c +index ecf076c964b..563c4b9df38 100644 +--- a/gcc/testsuite/gcc.dg/vect/pr108950.c ++++ b/gcc/testsuite/gcc.dg/vect/pr108950.c +@@ -1,5 +1,5 @@ +-/* { dg-require-effective-target vect_simd_clones } */ + /* { dg-do compile } */ ++/* { dg-require-effective-target vect_simd_clones } */ + + int m; + short int n; +-- +2.35.3 + +From 16a76499f916b5b6d11bccc03cc0d16b2b1ee31b Mon Sep 17 00:00:00 2001 +From: Jonathan Wakely +Date: Wed, 16 Nov 2022 12:22:04 +0000 +Subject: [PATCH] libstdc++: Fix std::any pretty printer +To: gcc-patches@gcc.gnu.org + +The recent changes to FilteringTypePrinter affect the result of +gdb.lookup_type('std::string') in StdExpAnyPrinter, causing it to always +return the std::__cxx11::basic_string specialization. This then causes a +gdb.error exception when trying to lookup the std::any manager type for +a specialization using that string, but that manager was never +instantiated in the program. This causes FAILs when running the tests +with -D_GLIBCXX_USE_CXX11_ABI=0: + +FAIL: libstdc++-prettyprinters/libfundts.cc print as +FAIL: libstdc++-prettyprinters/libfundts.cc print as + +The ugly solution used in this patch is to repeat the lookup for every +type that std::string could be a typedef for, and hope it only works for +one of them. + +libstdc++-v3/ChangeLog: + + * python/libstdcxx/v6/printers.py (StdExpAnyPrinter): Make + expansion of std::string in manager name more robust. + +(cherry picked from commit 3c54805d03ac1bcc3d8547ffb5e6c4e1f301a7a2) +--- + libstdc++-v3/python/libstdcxx/v6/printers.py | 31 ++++++++++++++++++-- + 1 file changed, 28 insertions(+), 3 deletions(-) + +diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py +index bb06a4959ee..d27a25bd96f 100644 +--- a/libstdc++-v3/python/libstdcxx/v6/printers.py ++++ b/libstdc++-v3/python/libstdcxx/v6/printers.py +@@ -1216,9 +1216,34 @@ class StdExpAnyPrinter(SingleObjContainerPrinter): + mgrname = m.group(1) + # FIXME need to expand 'std::string' so that gdb.lookup_type works + if 'std::string' in mgrname: +- mgrname = re.sub("std::string(?!\w)", str(gdb.lookup_type('std::string').strip_typedefs()), m.group(1)) +- +- mgrtype = gdb.lookup_type(mgrname) ++ # This lookup for std::string might return the __cxx11 version, ++ # but that's not necessarily the one used by the std::any ++ # manager function we're trying to find. ++ strings = {str(gdb.lookup_type('std::string').strip_typedefs())} ++ # So also consider all the other possible std::string types! ++ s = 'basic_string, std::allocator >' ++ quals = ['std::', 'std::__cxx11::', 'std::' + _versioned_namespace] ++ strings |= {q+s for q in quals} # set of unique strings ++ mgrtypes = [] ++ for s in strings: ++ try: ++ x = re.sub("std::string(?!\w)", s, m.group(1)) ++ # The following lookup might raise gdb.error if the ++ # manager function was never instantiated for 's' in the ++ # program, because there will be no such type. ++ mgrtypes.append(gdb.lookup_type(x)) ++ except gdb.error: ++ pass ++ if len(mgrtypes) != 1: ++ # FIXME: this is unlikely in practice, but possible for ++ # programs that use both old and new string types with ++ # std::any in a single program. Can we do better? ++ # Maybe find the address of each type's _S_manage and ++ # compare to the address stored in _M_manager? ++ raise ValueError('Cannot uniquely determine std::string type used in std::any') ++ mgrtype = mgrtypes[0] ++ else: ++ mgrtype = gdb.lookup_type(mgrname) + self.contained_type = mgrtype.template_argument(0) + valptr = None + if '::_Manager_internal' in mgrname: +-- +2.35.3 + diff --git a/gcc12.spec b/gcc12.spec new file mode 100644 index 0000000..6a89fb7 --- /dev/null +++ b/gcc12.spec @@ -0,0 +1,3817 @@ +# +# spec file for package gcc12 +# +# Copyright (c) 2023 SUSE LLC +# +# All modifications and additions to the file contributed by third parties +# remain the property of their copyright owners, unless otherwise agreed +# upon. The license for this file, and modifications and additions to the +# file, is the same license as for the pristine package itself (unless the +# license for the pristine package is not an Open Source License, in which +# case the license is the MIT License). An "Open Source License" is a +# license that conforms to the Open Source Definition (Version 1.9) +# published by the Open Source Initiative. + +# Please submit bugfixes or comments via https://bugs.opensuse.org/ +# + + +%if 0%{?suse_version} < 1550 +%define _slibdir /%{_lib} +%define slibdir /lib +%define slibdir64 /lib64 +%else +%define _slibdir %{_libdir} +%define slibdir %{_prefix}/lib +%define slibdir64 %{_prefix}/lib64 +%define usrmerged 1 +%endif + +# Ada currently fails to build on a few platforms, enable it only +# on those that work +%if %{suse_version} >= 1310 +%if %{suse_version} >= 1330 +%define ada_arch %ix86 x86_64 ppc ppc64 ppc64le s390 s390x ia64 aarch64 riscv64 +%else +%define ada_arch %ix86 x86_64 ppc ppc64 s390 ia64 +%endif +%else +%define ada_arch %ix86 x86_64 ppc s390 ia64 +%endif + +%ifarch %ada_arch +%define build_ada 1 +%else +%define build_ada 0 +%endif + +%define quadmath_arch %ix86 x86_64 ia64 ppc64le +%define tsan_arch x86_64 aarch64 ppc ppc64 ppc64le s390 s390x +%define asan_arch x86_64 %ix86 ppc ppc64 ppc64le s390 s390x %sparc %arm aarch64 riscv64 +%define hwasan_arch aarch64 +%define itm_arch x86_64 %ix86 %arm aarch64 ppc ppc64 ppc64le s390 s390x %sparc +%define atomic_arch x86_64 %ix86 %arm aarch64 ppc ppc64 ppc64le s390 s390x %sparc m68k ia64 riscv64 +%define lsan_arch x86_64 aarch64 ppc ppc64 ppc64le s390 s390x +%define ubsan_arch x86_64 %ix86 ppc ppc64 ppc64le s390 s390x %arm aarch64 riscv64 +%if 0%{?build_libvtv:1} +%define vtv_arch x86_64 %ix86 +%endif + +%define build_cp 1 +%define build_fortran 1 +%define build_objc 1 +%define build_objcp 1 +%define build_go 1 +%ifarch x86_64 %ix86 %arm aarch64 riscv64 s390x +%define build_d 1 +%else +%define build_d 0 +%endif + +%if %{build_objcp} +%define build_cp 1 +%define build_objc 1 +%endif + +# For optional compilers only build C, C++, Fortran, Ada and Go +%if 0%{?build_optional_compiler_languages:1} +%define build_objc 0 +%define build_objcp 0 +%define build_d 0 +%endif + +%ifarch x86_64 +%define build_nvptx 1 +%else +%define build_nvptx 0 +%endif + +%ifarch x86_64 +# SLE12 does not fulfil build requirements for GCN, SLE15 SP1 does +# technically also SLE12 SP5 but do not bother there +%if %{suse_version} >= 1550 || 0%{?sle_version:%sle_version} >= 150100 +%define build_gcn 1 +%else +%define build_gcn 0 +%endif +%else +%define build_gcn 0 +%endif + +%define use_lto_bootstrap 0 +%ifarch x86_64 ppc64le s390x aarch64 +%if %{suse_version} > 1500 +%define use_lto_bootstrap 1 +%endif +%endif + +# Enable plugins just for Tumbleweed, not for SLES +%if 0%{!?sle_version:1} +%define enable_plugins 1 +%define build_jit 1 +%else +%define enable_plugins 0 +%define build_jit 0 +%endif + +# Shared library SONAME versions +%ifarch hppa +%define libgcc_s 4 +%else +%ifarch m68k +%define libgcc_s 2 +%else +%define libgcc_s 1 +%endif +%endif +%define libgomp_sover 1 +%define libstdcxx_sover 6 +%define libobjc_sover 4 +%define libgfortran_sover 5 +%define libquadmath_sover 0 +%define libasan_sover 8 +%define libtsan_sover 2 +%define libhwasan_sover 0 +%define libatomic_sover 1 +%define libitm_sover 1 +%define libubsan_sover 1 +%define liblsan_sover 0 +%define libvtv_sover 0 +%define libgo_sover 21 +%define libgphobos_sover 3 +%define libgdruntime_sover 3 +%define libgccjit_sover 0 + +# Shared library package suffix +# This is used for the "non-standard" set of libraries, the standard +# being defined by %%product_libs_gcc_ver, the GCC version that should +# provide un-suffixed shared library packages following the shared-library +# policy. Even suffixed variants should provide the shared-library policy +# mandated names and ensure they conflict with each other. +# Individual shared libraries can be directed to be built from individual +# gcc versions by defining %%product_libs_gcc_ver_libgcc_s1 for example, +# generally %%product_libs_gcc_ver_%%name%%sover, similarly. + +%define itsme12 1 +%define plv_ %{!?product_libs_gcc_ver:12}%{?product_libs_gcc_ver} +%define plv() %{expand:%%{!?itsme%{expand:%%{!?product_libs_gcc_ver_%{1}%{2}:%%{plv_}}%%{?product_libs_gcc_ver_%{1}%{2}}}:-gcc12}} + +%define libgcc_s_suffix %{plv libgcc_s %{libgcc_s}} +%define libgomp_suffix %{plv libgomp %{libgomp_sover}} +%define libstdcxx_suffix %{plv libstdcxx %{libstdcxx_sover}} +%define libobjc_suffix %{plv libobjc %{libobjc_sover}} +%define libgfortran_suffix %{plv libgfortran %{libgfortran_sover}} +%define libquadmath_suffix %{plv libquadmath %{libquadmath_sover}} +%define libasan_suffix %{plv libasan %{libasan_sover}} +%define libtsan_suffix %{plv libtsan %{libtsan_sover}} +%define libhwasan_suffix %{plv libhwasan %{libhwasan_sover}} +%define libatomic_suffix %{plv libatomic %{libatomic_sover}} +%define libitm_suffix %{plv libitm %{libitm_sover}} +%define libubsan_suffix %{plv libubsan %{libubsan_sover}} +%define liblsan_suffix %{plv liblsan %{liblsan_sover}} +%define libvtv_suffix %{plv libvtv %{libvtv_sover}} +%define libgo_suffix %{plv libgo %{libgo_sover}} +%define libgphobos_suffix %{plv libgphobos %{libgphobos_sover}} +%define libgdruntime_suffix %{plv libgdruntime %{libgdruntime_sover}} +%define libgccjit_suffix %{plv libgccjit %{libgccjit_sover}} + +# libFOO-devel package suffix +%define libdevel_suffix -gcc12 + +%if %{suse_version} >= 1220 +%define selfconflict() %1 +%else +%define selfconflict() otherproviders(%1) +%endif + +%define biarch_targets x86_64 s390x powerpc64 powerpc sparc sparc64 + +URL: https://gcc.gnu.org/ +Version: 12.3.0+git1204 +Release: 150000.1.16.1 +%define gcc_dir_version %(echo %version | sed 's/+.*//' | cut -d '.' -f 1) +%define gcc_snapshot_revision %(echo %version | sed 's/[3-9]\.[0-9]\.[0-6]//' | sed 's/+/-/') +%define binsuffix -12 + +Name: gcc12 +BuildRequires: xz +%if %{suse_version} > 1500 +BuildRequires: libzstd-devel +%endif +# With generated files in src we could drop the following +BuildRequires: bison +BuildRequires: flex +BuildRequires: gettext-devel +%if %{suse_version} > 1220 +BuildRequires: makeinfo +%else +BuildRequires: texinfo +%endif +# until here, but at least renaming and patching info files breaks this +BuildRequires: gcc-c++ +BuildRequires: glibc-devel-32bit glibc-32bit +BuildRequires: mpc-devel +BuildRequires: mpfr-devel +BuildRequires: perl +BuildRequires: zlib-devel +%if %{suse_version} >= 1500 +# for SDT markers in the C++ unwinder and gdb breakpoints on exceptions +BuildRequires: systemtap-headers +%endif +%if %{suse_version} >= 1230 +BuildRequires: isl-devel +%endif +%define hostsuffix %{nil} +%if %{build_ada} +%if 0%{?gcc_version:%{gcc_version}} > 12 +%define hostsuffix %{binsuffix} +BuildRequires: gcc12-ada +BuildRequires: gcc12-c++ +%else +%if %{suse_version} <= 1315 +%define hostsuffix -7 +BuildRequires: gcc7-ada +BuildRequires: gcc7-c++ +%else +%define hostsuffix %{nil} +BuildRequires: gcc-ada +%endif +%endif +%endif +%if %{build_d} +%if %{suse_version} < 1550 +BuildRequires: gcc11-d +BuildRequires: libstdc++6-devel-gcc11 +%else +BuildRequires: gcc-d +%endif +%endif +# We now require a C++ 11 capable compiler for bootstrapping +%if %{suse_version} < 1220 +%define hostsuffix -4.8 +BuildRequires: gcc48-c++ +%endif +%if 0%{?building_testsuite:1} +# For building the libstdc++ API reference +BuildRequires: doxygen +BuildRequires: graphviz +%endif +%ifarch ia64 +BuildRequires: libunwind-devel +%endif +%if 0%{?run_tests:1} +BuildRequires: dejagnu +BuildRequires: expect +BuildRequires: gdb +%if %{build_go} +BuildRequires: netcfg +BuildRequires: procps +%endif +%if %{build_nvptx} +BuildRequires: cross-nvptx-gcc12 +BuildRequires: cross-nvptx-newlib12-devel +%endif +%if %{build_gcn} +BuildRequires: cross-amdgcn-gcc12 +BuildRequires: cross-amdgcn-newlib12-devel +%endif +%endif +#!BuildIgnore: gcc-PIE + +%define separate_bi32 0 +%define separate_bi64 0 +%if 0%{!?disable_32bit:1} +%ifarch ppc sparcv9 +%define separate_bi64 1 +%endif +%ifarch x86_64 s390x ppc64 sparc64 +%define separate_bi32 1 +%endif +%define disable_multilib_arch %{nil} +%else +%define disable_multilib_arch ppc sparcv9 x86_64 s390x ppc64 sparc64 +%endif + +# Define two macros to trigger -32bit or -64bit package variants +%define separate_biarch 0 +%if %{separate_bi32} +%define separate_biarch 1 +%define separate_biarch_suffix -32bit +%endif +%if %{separate_bi64} +%define separate_biarch 1 +%define separate_biarch_suffix -64bit +%endif + +%ifarch aarch64 x86_64 ia64 s390x alpha ppc64 ppc64le sparc64 +# 64-bit is primary build target +%define build_primary_64bit 1 +%else +%define build_primary_64bit 0 +%endif + +%if !0%{?building_testsuite:1} +Requires: binutils +Requires: cpp12 = %{version}-%{release} +Requires: glibc-devel +Requires: libgcc_s%{libgcc_s} >= %{version}-%{release} +Requires: libgomp%{libgomp_sover} >= %{version}-%{release} +%ifarch %asan_arch +Requires: libasan%{libasan_sover} >= %{version}-%{release} +%endif +%ifarch %tsan_arch +%if %{build_primary_64bit} +Requires: libtsan%{libtsan_sover} >= %{version}-%{release} +%endif +%endif +%ifarch %hwasan_arch +Requires: libhwasan%{libhwasan_sover} >= %{version}-%{release} +%endif +%ifarch %atomic_arch +Requires: libatomic%{libatomic_sover} >= %{version}-%{release} +%endif +%ifarch %itm_arch +Requires: libitm%{libitm_sover} >= %{version}-%{release} +%endif +%ifarch %lsan_arch +%if %{build_primary_64bit} +Requires: liblsan%{liblsan_sover} >= %{version}-%{release} +%endif +%endif +%ifarch %ubsan_arch +Requires: libubsan%{libubsan_sover} >= %{version}-%{release} +%endif +%ifarch %vtv_arch +Requires: libvtv%{libvtv_sover} >= %{version}-%{release} +%endif +Suggests: gcc12-info gcc12-locale +%endif + +%if %{suse_version} < 1310 +BuildRoot: %{_tmppath}/%{name}-%{version}-build +%endif +Group: Development/Languages/C and C++ +Source: gcc-%{version}.tar.xz +Source1: change_spec +Source2: gcc12-rpmlintrc +Source3: gcc12-testresults-rpmlintrc +Source4: README.First-for.SuSE.packagers +Source5: newlib-4.2.0.20211231.tar.xz +Patch2: gcc-add-defaultsspec.diff +Patch5: tls-no-direct.diff +Patch6: gcc43-no-unwind-tables.diff +Patch7: gcc48-libstdc++-api-reference.patch +Patch11: gcc7-remove-Wexpansion-to-defined-from-Wextra.patch +Patch15: gcc7-avoid-fixinc-error.diff +Patch16: gcc9-reproducible-builds.patch +Patch17: gcc9-reproducible-builds-buildid-for-checksum.patch +Patch18: gcc10-amdgcn-llvm-as.patch +Patch19: gcc11-gdwarf-4-default.patch +Patch20: gcc11-amdgcn-disable-hot-cold-partitioning.patch +# taken from https://gcc.gnu.org/pipermail/gcc-patches/2022-April/593378.html +Patch22: gcc12-riscv-inline-atomics.patch +# remove libatomics linking +Patch23: gcc12-riscv-pthread.patch +Patch24: gcc12-testsuite-fixes.patch +Patch25: gcc12-aarch64-bsc1214052.patch +# A set of patches from the RH srpm +Patch51: gcc41-ppc32-retaddr.patch +# Some patches taken from Debian +Patch60: gcc44-textdomain.patch +Patch61: gcc44-rename-info-files.patch + +License: GPL-3.0-or-later +Summary: The GNU C Compiler and Support Files + +%description +Core package for the GNU Compiler Collection, including the C language +frontend. + +Language frontends other than C are split to different sub-packages, +namely gcc-ada, gcc-c++, gcc-fortran, gcc-obj, gcc-obj-c++ and gcc-go. + +%package -n gcc12-32bit +Summary: The GNU C Compiler 32bit support +Group: Development/Languages/C and C++ +Requires: gcc12 = %{version}-%{release} +Requires: libgcc_s%{libgcc_s}-32bit >= %{version}-%{release} +Requires: libgomp%{libgomp_sover}-32bit >= %{version}-%{release} +%ifarch %asan_arch +Requires: libasan%{libasan_sover}-32bit >= %{version}-%{release} +%endif +%ifarch %atomic_arch +Requires: libatomic%{libatomic_sover}-32bit >= %{version}-%{release} +%endif +%ifarch %itm_arch +Requires: libitm%{libitm_sover}-32bit >= %{version}-%{release} +%endif +%ifarch %ubsan_arch +Requires: libubsan%{libubsan_sover}-32bit >= %{version}-%{release} +%endif +%ifarch %vtv_arch +Requires: libvtv%{libvtv_sover}-32bit >= %{version}-%{release} +%endif +Requires: glibc-devel-32bit glibc-32bit + +%description -n gcc12-32bit +This package contains 32bit support for the GNU Compiler Collection. + +%package -n gcc12-64bit +Summary: The GNU C Compiler 64bit support +Group: Development/Languages/C and C++ +Requires: gcc12 = %{version}-%{release} +Requires: libgcc_s%{libgcc_s}-64bit >= %{version}-%{release} +Requires: libgomp%{libgomp_sover}-64bit >= %{version}-%{release} +%ifarch %asan_arch +Requires: libasan%{libasan_sover}-64bit >= %{version}-%{release} +%endif +%ifarch %tsan_arch +Requires: libtsan%{libtsan_sover}-64bit >= %{version}-%{release} +%endif +%ifarch %hwasan_arch +Requires: libhwasan%{libhwasan_sover}-64bit >= %{version}-%{release} +%endif +%ifarch %atomic_arch +Requires: libatomic%{libatomic_sover}-64bit >= %{version}-%{release} +%endif +%ifarch %itm_arch +Requires: libitm%{libitm_sover}-64bit >= %{version}-%{release} +%endif +%ifarch %lsan_arch +Requires: liblsan%{liblsan_sover}-64bit >= %{version}-%{release} +%endif +%ifarch %ubsan_arch +Requires: libubsan%{libubsan_sover}-64bit >= %{version}-%{release} +%endif +%ifarch %vtv_arch +Requires: libvtv%{libvtv_sover}-64bit >= %{version}-%{release} +%endif +Requires: glibc-devel-64bit + +%description -n gcc12-64bit +This package contains 64bit support for the GNU Compiler Collection. + +%package devel +Summary: GCC plugins development enviroment +License: GPL-3.0-or-later +Group: Development/Languages/C and C++ +Requires: gcc12 = %{version}-%{release} +Requires: gmp-devel +Requires: mpc-devel + +%description devel +Files required for developing and compiling GCC plugins. + +%package locale +Summary: Locale Data for the GNU Compiler Collection +License: GPL-3.0-or-later +Group: Development/Languages/C and C++ +Requires: gcc12 = %{version}-%{release} + +%description locale +Locale data for the GNU Compiler Collection (GCC) to give error message +in the current locale. + +%package PIE +Summary: A default configuration to build all binaries in PIE mode +License: GPL-3.0-or-later +Group: Development/Languages/Other +Requires: gcc12 = %{version}-%{release} + +%description PIE +This package contains a configuration file (spec) that changes the +compilers default setting to build all ELF binaries in the Position +Independend Executable (PIE) variant. This enables better address +space randomization (ASLR). + +%package c++ +Summary: The GNU C++ Compiler +License: GPL-3.0-or-later +Group: Development/Languages/C and C++ +Requires: gcc12 = %{version}-%{release} +Requires: gcc12-c++ = %{version}-%{release} +Requires: libstdc++%{libstdcxx_sover}-devel%{libdevel_suffix} = %{version}-%{release} + +%description c++ +This package contains the GNU compiler for C++. + +%package c++-32bit +Summary: The GNU C++ Compiler +License: GPL-3.0-or-later +Group: Development/Languages/C and C++ +Requires: gcc12-32bit = %{version}-%{release} +Requires: gcc12-c++ = %{version}-%{release} +Requires: libstdc++%{libstdcxx_sover}-devel%{libdevel_suffix}-32bit = %{version}-%{release} + +%description c++-32bit +This package contains the GNU compiler for C++. + +%package c++-64bit +Summary: The GNU C++ Compiler +License: GPL-3.0-or-later +Group: Development/Languages/C and C++ +Requires: gcc12-64bit = %{version}-%{release} +Requires: gcc12-c++ = %{version}-%{release} +Requires: libstdc++%{libstdcxx_sover}-devel%{libdevel_suffix}-64bit = %{version}-%{release} + +%description c++-64bit +This package contains the GNU compiler for C++. + +%package -n libstdc++%{libstdcxx_sover}-devel%{libdevel_suffix} +Summary: Include Files and Libraries mandatory for Development +License: GPL-3.0-or-later WITH GCC-exception-3.1 +Group: Development/Languages/C and C++ +Requires: glibc-devel +Requires: libstdc++%{libstdcxx_sover} >= %{version}-%{release} +%ifarch ia64 +Requires: libunwind-devel +%endif + +%description -n libstdc++%{libstdcxx_sover}-devel%{libdevel_suffix} +This package contains all the headers and libraries of the standard C++ +library. It is needed for compiling C++ code. + +%package -n libstdc++%{libstdcxx_sover}-devel%{libdevel_suffix}-32bit +Summary: Include Files and Libraries mandatory for Development +License: GPL-3.0-or-later WITH GCC-exception-3.1 +Group: Development/Languages/C and C++ +Requires: glibc-devel-32bit glibc-32bit +Requires: libstdc++%{libstdcxx_sover}-32bit >= %{version}-%{release} +%ifarch ia64 +Requires: libunwind-devel +%endif + +%description -n libstdc++%{libstdcxx_sover}-devel%{libdevel_suffix}-32bit +This package contains all the headers and libraries of the standard C++ +library. It is needed for compiling C++ code. + +%package -n libstdc++%{libstdcxx_sover}-devel%{libdevel_suffix}-64bit +Summary: Include Files and Libraries mandatory for Development +License: GPL-3.0-or-later WITH GCC-exception-3.1 +Group: Development/Languages/C and C++ +Requires: glibc-devel-64bit +Requires: libstdc++%{libstdcxx_sover}-64bit >= %{version}-%{release} +%ifarch ia64 +Requires: libunwind-devel +%endif + +%description -n libstdc++%{libstdcxx_sover}-devel%{libdevel_suffix}-64bit +This package contains all the headers and libraries of the standard C++ +library. It is needed for compiling C++ code. + +%package -n libstdc++%{libstdcxx_sover}-pp%{libstdcxx_suffix} +Summary: GDB pretty printers for the C++ standard library +License: GPL-3.0-or-later +Group: Development/Languages/C and C++ +# The -pp packages are tied to a specific shared library +Requires: libstdc++%{libstdcxx_sover} = %{version}-%{release} +Requires: libstdc++%{libstdcxx_sover}-pp%{libstdcxx_suffix} = %{version}-%{release} +Provides: libstdc++%{libstdcxx_sover}-pp = %{version}-%{release} +# To allow updates from libstdc++6-pp-gccM to libstdc++6-pp we need +# enumerates Obsoletes, the separate -pp package was introduced with GCC9 +# and dropped somewhen during the GCC11 to GCC12 transition +Obsoletes: libstdc++6-pp-gcc9 libstdc++6-pp-gcc10 +Obsoletes: libstdc++6-pp-gcc11 +Provides: libstdc++6-pp-gcc10 +Provides: libstdc++6-pp-gcc11 +Provides: libstdc++6-pp-gcc9 +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libstdc++%{libstdcxx_sover}-pp +# packageand() does not work with versioned specifications so the fallback +# is a Requires from libstdc++-devel to preserve previous behavior. +%if %{suse_version} >= 1500 +Supplements: (gdb and libstdc++%{libstdcxx_sover} = %{version}-%{release}) +%endif + +%description -n libstdc++%{libstdcxx_sover}-pp%{libstdcxx_suffix} +This package contains pretty printers for the C++ standard library usable +from GDB. + +%package -n libstdc++%{libstdcxx_sover}-pp%{libstdcxx_suffix}-32bit +Summary: GDB pretty printers for the C++ standard library +License: GPL-3.0-or-later +Group: Development/Languages/C and C++ +# The -pp packages are tied to a specific shared library +Requires: libstdc++%{libstdcxx_sover}-32bit = %{version}-%{release} +Requires: libstdc++%{libstdcxx_sover}-pp%{libstdcxx_suffix} = %{version}-%{release} +Provides: libstdc++%{libstdcxx_sover}-pp-32bit = %{version}-%{release} +# To allow updates from libstdc++6-pp-gccM to libstdc++6-pp we need +# enumerates Obsoletes, the separate -pp package was introduced with GCC9 +# and dropped somewhen during the GCC11 to GCC12 transition +Obsoletes: libstdc++6-pp-gcc9-32bit libstdc++6-pp-gcc10-32bit +Obsoletes: libstdc++6-pp-gcc11-32bit +Provides: libstdc++6-pp-gcc10-32bit +Provides: libstdc++6-pp-gcc11-32bit +Provides: libstdc++6-pp-gcc9-32bit +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libstdc++%{libstdcxx_sover}-pp-32bit +# packageand() does not work with versioned specifications so the fallback +# is a Requires from libstdc++-devel to preserve previous behavior. +%if %{suse_version} >= 1500 +Supplements: (gdb and libstdc++%{libstdcxx_sover}-32bit = %{version}-%{release}) +%endif + +%description -n libstdc++%{libstdcxx_sover}-pp%{libstdcxx_suffix}-32bit +This package contains pretty printers for the C++ standard library usable +from GDB. + +%package -n libstdc++%{libstdcxx_sover}-pp%{libstdcxx_suffix}-64bit +Summary: GDB pretty printers for the C++ standard library +License: GPL-3.0-or-later +Group: Development/Languages/C and C++ +# The -pp packages are tied to a specific shared library +Requires: libstdc++%{libstdcxx_sover}-64bit = %{version}-%{release} +Requires: libstdc++%{libstdcxx_sover}-pp%{libstdcxx_suffix} = %{version}-%{release} +Provides: libstdc++%{libstdcxx_sover}-pp-64bit = %{version}-%{release} +# To allow updates from libstdc++6-pp-gccM to libstdc++6-pp we need +# enumerates Obsoletes, the separate -pp package was introduced with GCC9 +# and dropped somewhen during the GCC11 to GCC12 transition +Obsoletes: libstdc++6-pp-gcc9-64bit libstdc++6-pp-gcc10-64bit +Obsoletes: libstdc++6-pp-gcc11-64bit +Provides: libstdc++6-pp-gcc10-64bit +Provides: libstdc++6-pp-gcc11-64bit +Provides: libstdc++6-pp-gcc9-64bit +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libstdc++%{libstdcxx_sover}-pp-64bit +# packageand() does not work with versioned specifications so the fallback +# is a Requires from libstdc++-devel to preserve previous behavior. +%if %{suse_version} >= 1500 +Supplements: (gdb and libstdc++%{libstdcxx_sover}-64bit = %{version}-%{release}) +%endif + +%description -n libstdc++%{libstdcxx_sover}-pp%{libstdcxx_suffix}-64bit +This package contains pretty printers for the C++ standard library usable +from GDB. + +%package -n libgcc_s%{libgcc_s}%{libgcc_s_suffix} +Summary: C compiler runtime library +License: GPL-3.0-or-later WITH GCC-exception-3.1 +Group: System/Base +Provides: libgcc_s%{libgcc_s} = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libgcc_s%{libgcc_s} + +%description -n libgcc_s%{libgcc_s}%{libgcc_s_suffix} +Libgcc is needed for dynamically linked C programs. + +%post -n libgcc_s%{libgcc_s}%{libgcc_s_suffix} -p /sbin/ldconfig + +%postun -n libgcc_s%{libgcc_s}%{libgcc_s_suffix} -p /sbin/ldconfig + +%package -n libgcc_s%{libgcc_s}%{libgcc_s_suffix}-32bit +Summary: C compiler runtime library +License: GPL-3.0-or-later WITH GCC-exception-3.1 +Group: System/Base +Provides: libgcc_s%{libgcc_s}-32bit = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libgcc_s%{libgcc_s}-32bit + +%description -n libgcc_s%{libgcc_s}%{libgcc_s_suffix}-32bit +Libgcc is needed for dynamically linked C programs. + +%post -n libgcc_s%{libgcc_s}%{libgcc_s_suffix}-32bit -p /sbin/ldconfig + +%postun -n libgcc_s%{libgcc_s}%{libgcc_s_suffix}-32bit -p /sbin/ldconfig + +%package -n libgcc_s%{libgcc_s}%{libgcc_s_suffix}-64bit +Summary: C compiler runtime library +License: GPL-3.0-or-later WITH GCC-exception-3.1 +Group: System/Base +Provides: libgcc_s%{libgcc_s}-64bit = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libgcc_s%{libgcc_s}-64bit + +%description -n libgcc_s%{libgcc_s}%{libgcc_s_suffix}-64bit +Libgcc is needed for dynamically linked C programs. + +%post -n libgcc_s%{libgcc_s}%{libgcc_s_suffix}-64bit -p /sbin/ldconfig + +%postun -n libgcc_s%{libgcc_s}%{libgcc_s_suffix}-64bit -p /sbin/ldconfig + +%package -n libgomp%{libgomp_sover}%{libgomp_suffix} +Summary: The GNU compiler collection OpenMP runtime library +License: GPL-3.0-or-later WITH GCC-exception-3.1 +Group: System/Base +Provides: libgomp%{libgomp_sover} = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libgomp%{libgomp_sover} + +%description -n libgomp%{libgomp_sover}%{libgomp_suffix} +This is the OpenMP runtime library needed by OpenMP enabled programs +that were built with the -fopenmp compiler option and by programs that +were auto-parallelized via the -ftree-parallelize-loops compiler +option. + + +%post -n libgomp%{libgomp_sover}%{libgomp_suffix} -p /sbin/ldconfig + +%postun -n libgomp%{libgomp_sover}%{libgomp_suffix} -p /sbin/ldconfig + +%package -n libgomp%{libgomp_sover}%{libgomp_suffix}-32bit +Summary: The GNU compiler collection OpenMP runtime library +License: GPL-3.0-or-later WITH GCC-exception-3.1 +Group: System/Base +Provides: libgomp%{libgomp_sover}-32bit = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libgomp%{libgomp_sover}-32bit + +%description -n libgomp%{libgomp_sover}%{libgomp_suffix}-32bit +This is the OpenMP runtime library needed by OpenMP enabled programs +that were built with the -fopenmp compiler option and by programs that +were auto-parallelized via the -ftree-parallelize-loops compiler +option. + + +%post -n libgomp%{libgomp_sover}%{libgomp_suffix}-32bit -p /sbin/ldconfig + +%postun -n libgomp%{libgomp_sover}%{libgomp_suffix}-32bit -p /sbin/ldconfig + +%package -n libgomp%{libgomp_sover}%{libgomp_suffix}-64bit +Summary: The GNU compiler collection OpenMP runtime library +License: GPL-3.0-or-later WITH GCC-exception-3.1 +Group: System/Base +Provides: libgomp%{libgomp_sover}-64bit = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libgomp%{libgomp_sover}-64bit + +%description -n libgomp%{libgomp_sover}%{libgomp_suffix}-64bit +This is the OpenMP runtime library needed by OpenMP enabled programs +that were built with the -fopenmp compiler option and by programs that +were auto-parallelized via the -ftree-parallelize-loops compiler +option. + + +%post -n libgomp%{libgomp_sover}%{libgomp_suffix}-64bit -p /sbin/ldconfig + +%postun -n libgomp%{libgomp_sover}%{libgomp_suffix}-64bit -p /sbin/ldconfig + +%package -n libstdc++%{libstdcxx_sover}%{libstdcxx_suffix} +Summary: The standard C++ shared library +License: GPL-3.0-or-later WITH GCC-exception-3.1 +Group: System/Libraries +Suggests: libstdc++%{libstdcxx_sover}-locale +Provides: libstdc++%{libstdcxx_sover} = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libstdc++%{libstdcxx_sover} +# Fallback for non-existing Supplements support +%if %{suse_version} < 1500 +Recommends: libstdc++%{libstdcxx_sover}-pp = %{version}-%{release} +%endif + +%description -n libstdc++%{libstdcxx_sover}%{libstdcxx_suffix} +The standard C++ library, needed for dynamically linked C++ programs. + + +%post -n libstdc++%{libstdcxx_sover}%{libstdcxx_suffix} -p /sbin/ldconfig + +%postun -n libstdc++%{libstdcxx_sover}%{libstdcxx_suffix} -p /sbin/ldconfig + +%package -n libstdc++%{libstdcxx_sover}%{libstdcxx_suffix}-32bit +Summary: The standard C++ shared library +License: GPL-3.0-or-later WITH GCC-exception-3.1 +Group: System/Libraries +Suggests: libstdc++%{libstdcxx_sover}-locale +Provides: libstdc++%{libstdcxx_sover}-32bit = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libstdc++%{libstdcxx_sover}-32bit +# Fallback for non-existing Supplements support +%if %{suse_version} < 1500 +Recommends: libstdc++%{libstdcxx_sover}-pp-32bit = %{version}-%{release} +%endif + +%description -n libstdc++%{libstdcxx_sover}%{libstdcxx_suffix}-32bit +The standard C++ library, needed for dynamically linked C++ programs. + + +%post -n libstdc++%{libstdcxx_sover}%{libstdcxx_suffix}-32bit -p /sbin/ldconfig + +%postun -n libstdc++%{libstdcxx_sover}%{libstdcxx_suffix}-32bit -p /sbin/ldconfig + +%package -n libstdc++%{libstdcxx_sover}%{libstdcxx_suffix}-64bit +Summary: The standard C++ shared library +License: GPL-3.0-or-later WITH GCC-exception-3.1 +Group: System/Libraries +Suggests: libstdc++%{libstdcxx_sover}-locale +Provides: libstdc++%{libstdcxx_sover}-64bit = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libstdc++%{libstdcxx_sover}-64bit +# Fallback for non-existing Supplements support +%if %{suse_version} < 1500 +Recommends: libstdc++%{libstdcxx_sover}-pp-64bit = %{version}-%{release} +%endif + +%description -n libstdc++%{libstdcxx_sover}%{libstdcxx_suffix}-64bit +The standard C++ library, needed for dynamically linked C++ programs. + + +%post -n libstdc++%{libstdcxx_sover}%{libstdcxx_suffix}-64bit -p /sbin/ldconfig + +%postun -n libstdc++%{libstdcxx_sover}%{libstdcxx_suffix}-64bit -p /sbin/ldconfig + +%package -n libstdc++%{libstdcxx_sover}%{libstdcxx_suffix}-locale +Summary: Standard C++ Library Locales +License: GPL-3.0-or-later WITH GCC-exception-3.1 +Group: System/Libraries +Provides: libstdc++%{libstdcxx_sover}-locale = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libstdc++%{libstdcxx_sover}-locale + +%description -n libstdc++%{libstdcxx_sover}%{libstdcxx_suffix}-locale +The standard C++ library locale data. + +%package info +Summary: Documentation for the GNU compiler collection +License: GFDL-1.2-only +Group: Documentation/Other +PreReq: %{install_info_prereq} +%if 0%{?suse_version} >= 1120 +BuildArch: noarch +%endif + +%description info +GNU info-pages for the GNU compiler collection covering both user-level +and internals documentation. + +%package objc +Summary: GNU Objective C Compiler +License: GPL-3.0-or-later +Group: Development/Languages/Other +Requires: gcc12 = %{version}-%{release} +Requires: gcc12-objc = %{version}-%{release} +Requires: libobjc%{libobjc_sover} >= %{version}-%{release} + +%description objc +This package contains the GNU Objective C compiler. Objective C is an +object oriented language, created by Next Inc. and used in their +Nextstep OS. The source code is available in the gcc package. + +%package objc-32bit +Summary: GNU Objective C Compiler +License: GPL-3.0-or-later +Group: Development/Languages/Other +Requires: gcc12-32bit = %{version}-%{release} +Requires: gcc12-objc = %{version}-%{release} +Requires: libobjc%{libobjc_sover}-32bit >= %{version}-%{release} + +%description objc-32bit +This package contains the GNU Objective C compiler. Objective C is an +object oriented language, created by Next Inc. and used in their +Nextstep OS. The source code is available in the gcc package. + +%package objc-64bit +Summary: GNU Objective C Compiler +License: GPL-3.0-or-later +Group: Development/Languages/Other +Requires: gcc12-64bit = %{version}-%{release} +Requires: gcc12-objc = %{version}-%{release} +Requires: libobjc%{libobjc_sover}-64bit >= %{version}-%{release} + +%description objc-64bit +This package contains the GNU Objective C compiler. Objective C is an +object oriented language, created by Next Inc. and used in their +Nextstep OS. The source code is available in the gcc package. + +%package -n libobjc%{libobjc_sover}%{libobjc_suffix} +Summary: Library for the GNU Objective C Compiler +License: GPL-3.0-or-later WITH GCC-exception-3.1 +Group: Development/Libraries/Other +Provides: libobjc%{libobjc_sover} = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libobjc%{libobjc_sover} + +%description -n libobjc%{libobjc_sover}%{libobjc_suffix} +The library for the GNU Objective C compiler. + +%post -n libobjc%{libobjc_sover}%{libobjc_suffix} -p /sbin/ldconfig + +%postun -n libobjc%{libobjc_sover}%{libobjc_suffix} -p /sbin/ldconfig + +%package -n libobjc%{libobjc_sover}%{libobjc_suffix}-32bit +Summary: Library for the GNU Objective C Compiler +License: GPL-3.0-or-later WITH GCC-exception-3.1 +Group: Development/Libraries/Other +Provides: libobjc%{libobjc_sover}-32bit = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libobjc%{libobjc_sover}-32bit + +%description -n libobjc%{libobjc_sover}%{libobjc_suffix}-32bit +The library for the GNU Objective C compiler. + +%post -n libobjc%{libobjc_sover}%{libobjc_suffix}-32bit -p /sbin/ldconfig + +%postun -n libobjc%{libobjc_sover}%{libobjc_suffix}-32bit -p /sbin/ldconfig + +%package -n libobjc%{libobjc_sover}%{libobjc_suffix}-64bit +Summary: Library for the GNU Objective C Compiler +License: GPL-3.0-or-later WITH GCC-exception-3.1 +Group: Development/Libraries/Other +Provides: libobjc%{libobjc_sover}-64bit = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libobjc%{libobjc_sover}-64bit + +%description -n libobjc%{libobjc_sover}%{libobjc_suffix}-64bit +The library for the GNU Objective C compiler. + +%post -n libobjc%{libobjc_sover}%{libobjc_suffix}-64bit -p /sbin/ldconfig + +%postun -n libobjc%{libobjc_sover}%{libobjc_suffix}-64bit -p /sbin/ldconfig + +%package obj-c++ +Summary: GNU Objective C++ Compiler +License: GPL-3.0-or-later +Group: Development/Languages/Other +Requires: gcc12-c++ = %{version}-%{release} +Requires: gcc12-obj-c++ = %{version}-%{release} +Requires: gcc12-objc = %{version}-%{release} + +%description obj-c++ +This package contains the GNU Objective C++ compiler. Objective C++ is an +object oriented language, created by Next Inc. and used in their +Nextstep OS. The source code is available in the gcc package. + +%package obj-c++-32bit +Summary: GNU Objective C++ Compiler +License: GPL-3.0-or-later +Group: Development/Languages/Other +Requires: gcc12-c++-32bit = %{version}-%{release} +Requires: gcc12-obj-c++ = %{version}-%{release} +Requires: gcc12-objc-32bit = %{version}-%{release} + +%description obj-c++-32bit +This package contains the GNU Objective C++ compiler. Objective C++ is an +object oriented language, created by Next Inc. and used in their +Nextstep OS. The source code is available in the gcc package. + +%package obj-c++-64bit +Summary: GNU Objective C++ Compiler +License: GPL-3.0-or-later +Group: Development/Languages/Other +Requires: gcc12-c++-64bit = %{version}-%{release} +Requires: gcc12-obj-c++ = %{version}-%{release} +Requires: gcc12-objc-64bit = %{version}-%{release} + +%description obj-c++-64bit +This package contains the GNU Objective C++ compiler. Objective C++ is an +object oriented language, created by Next Inc. and used in their +Nextstep OS. The source code is available in the gcc package. + +%package -n cpp12 +Summary: The GCC Preprocessor +License: GPL-3.0-or-later +Group: Development/Languages/C and C++ + +%description -n cpp12 +This Package contains just the preprocessor that is used by the X11 +packages. + +%package ada +Summary: GNU Ada Compiler Based on GCC (GNAT) +License: GPL-3.0-or-later +Group: Development/Languages/Other +Requires: gcc12 = %{version}-%{release} +Requires: gcc12-ada = %{version}-%{release} +Requires: libada12 = %{version}-%{release} + +%description ada +This package contains an Ada compiler and associated development +tools based on the GNU GCC technology. + +%package ada-32bit +Summary: GNU Ada Compiler Based on GCC (GNAT) +License: GPL-3.0-or-later +Group: Development/Languages/Other +Requires: gcc12-32bit = %{version}-%{release} +Requires: gcc12-ada = %{version}-%{release} +Requires: libada12-32bit = %{version}-%{release} + +%description ada-32bit +This package contains an Ada compiler and associated development +tools based on the GNU GCC technology. + +%package ada-64bit +Summary: GNU Ada Compiler Based on GCC (GNAT) +License: GPL-3.0-or-later +Group: Development/Languages/Other +Requires: gcc12-64bit = %{version}-%{release} +Requires: gcc12-ada = %{version}-%{release} +Requires: libada12-64bit = %{version}-%{release} + +%description ada-64bit +This package contains an Ada compiler and associated development +tools based on the GNU GCC technology. + +%package -n libada12 +Summary: GNU Ada Runtime Libraries +License: GPL-3.0-or-later WITH GCC-exception-3.1 +Group: System/Libraries +Provides: libgnarl-12 = %{version}-%{release} +Conflicts: %selfconflict libgnarl-12 +Provides: libgnat-12 = %{version}-%{release} +Conflicts: %selfconflict libgnat-12 + +%description -n libada12 +This package contains the shared libraries required to run programs +compiled with the GNU Ada compiler (GNAT) if they are compiled to use +shared libraries. It also contains the shared libraries for the +Implementation of the Ada Semantic Interface Specification (ASIS), the +implementation of Distributed Systems Programming (GLADE) and the Posix +1003.5 Binding (Florist). + +%post -n libada12 -p /sbin/ldconfig + +%postun -n libada12 -p /sbin/ldconfig + +%package -n libada12-32bit +Summary: GNU Ada Runtime Libraries +License: GPL-3.0-or-later WITH GCC-exception-3.1 +Group: System/Libraries +Provides: libgnarl-12-32bit = %{version}-%{release} +Conflicts: %selfconflict libgnarl-12-32bit +Provides: libgnat-12-32bit = %{version}-%{release} +Conflicts: %selfconflict libgnat-12-32bit + +%description -n libada12-32bit +This package contains the shared libraries required to run programs +compiled with the GNU Ada compiler (GNAT) if they are compiled to use +shared libraries. It also contains the shared libraries for the +Implementation of the Ada Semantic Interface Specification (ASIS), the +implementation of Distributed Systems Programming (GLADE) and the Posix +1003.5 Binding (Florist). + +%post -n libada12-32bit -p /sbin/ldconfig + +%postun -n libada12-32bit -p /sbin/ldconfig + +%package -n libada12-64bit +Summary: GNU Ada Runtime Libraries +License: GPL-3.0-or-later WITH GCC-exception-3.1 +Group: System/Libraries +Provides: libgnarl-12-64bit = %{version}-%{release} +Conflicts: %selfconflict libgnarl-12-64bit +Provides: libgnat-12-64bit = %{version}-%{release} +Conflicts: %selfconflict libgnat-12-64bit + +%description -n libada12-64bit +This package contains the shared libraries required to run programs +compiled with the GNU Ada compiler (GNAT) if they are compiled to use +shared libraries. It also contains the shared libraries for the +Implementation of the Ada Semantic Interface Specification (ASIS), the +implementation of Distributed Systems Programming (GLADE) and the Posix +1003.5 Binding (Florist). + +%post -n libada12-64bit -p /sbin/ldconfig + +%postun -n libada12-64bit -p /sbin/ldconfig + +%package fortran +Summary: The GNU Fortran Compiler and Support Files +License: GPL-3.0-or-later +Group: Development/Languages/Fortran +Requires: gcc12 = %{version}-%{release} +Requires: gcc12-fortran = %{version}-%{release} +Requires: libgfortran%{libgfortran_sover} >= %{version}-%{release} +%ifarch %quadmath_arch +Requires: libquadmath%{libquadmath_sover} >= %{version}-%{release} +%endif + +%description fortran +This is the Fortran compiler of the GNU Compiler Collection (GCC). + +%package fortran-32bit +Summary: The GNU Fortran Compiler and Support Files +License: GPL-3.0-or-later +Group: Development/Languages/Fortran +Requires: gcc12-32bit = %{version}-%{release} +Requires: gcc12-fortran = %{version}-%{release} +Requires: libgfortran%{libgfortran_sover}-32bit >= %{version}-%{release} +%ifarch %quadmath_arch +Requires: libquadmath%{libquadmath_sover}-32bit >= %{version}-%{release} +%endif + +%description fortran-32bit +This is the Fortran compiler of the GNU Compiler Collection (GCC). + +%package fortran-64bit +Summary: The GNU Fortran Compiler and Support Files +License: GPL-3.0-or-later +Group: Development/Languages/Fortran +Requires: gcc12-64bit = %{version}-%{release} +Requires: gcc12-fortran = %{version}-%{release} +Requires: libgfortran%{libgfortran_sover}-64bit >= %{version}-%{release} +%ifarch %quadmath_arch +Requires: libquadmath%{libquadmath_sover}-64bit >= %{version}-%{release} +%endif + +%description fortran-64bit +This is the Fortran compiler of the GNU Compiler Collection (GCC). + +%package -n libgfortran%{libgfortran_sover}%{libgfortran_suffix} +Summary: The GNU Fortran Compiler Runtime Library +License: GPL-3.0-or-later WITH GCC-exception-3.1 +Group: Development/Languages/Fortran +%ifarch %quadmath_arch +Requires: libquadmath%{libquadmath_sover} >= %{version}-%{release} +%endif +Provides: libgfortran%{libgfortran_sover} = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libgfortran%{libgfortran_sover} + +%description -n libgfortran%{libgfortran_sover}%{libgfortran_suffix} +The runtime library needed to run programs compiled with the Fortran compiler +of the GNU Compiler Collection (GCC). + +%post -n libgfortran%{libgfortran_sover}%{libgfortran_suffix} -p /sbin/ldconfig + +%postun -n libgfortran%{libgfortran_sover}%{libgfortran_suffix} -p /sbin/ldconfig + +%package -n libgfortran%{libgfortran_sover}%{libgfortran_suffix}-32bit +Summary: The GNU Fortran Compiler Runtime Library +License: GPL-3.0-or-later WITH GCC-exception-3.1 +Group: Development/Languages/Fortran +%ifarch %quadmath_arch +Requires: libquadmath%{libquadmath_sover}-32bit >= %{version}-%{release} +%endif +Provides: libgfortran%{libgfortran_sover}-32bit = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libgfortran%{libgfortran_sover}-32bit + +%description -n libgfortran%{libgfortran_sover}%{libgfortran_suffix}-32bit +The runtime library needed to run programs compiled with the Fortran compiler +of the GNU Compiler Collection (GCC). + +%post -n libgfortran%{libgfortran_sover}%{libgfortran_suffix}-32bit -p /sbin/ldconfig + +%postun -n libgfortran%{libgfortran_sover}%{libgfortran_suffix}-32bit -p /sbin/ldconfig + +%package -n libgfortran%{libgfortran_sover}%{libgfortran_suffix}-64bit +Summary: The GNU Fortran Compiler Runtime Library +License: GPL-3.0-or-later WITH GCC-exception-3.1 +Group: Development/Languages/Fortran +%ifarch %quadmath_arch +Requires: libquadmath%{libquadmath_sover}-64bit >= %{version}-%{release} +%endif +Provides: libgfortran%{libgfortran_sover}-64bit = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libgfortran%{libgfortran_sover}-64bit + +%description -n libgfortran%{libgfortran_sover}%{libgfortran_suffix}-64bit +The runtime library needed to run programs compiled with the Fortran compiler +of the GNU Compiler Collection (GCC). + +%post -n libgfortran%{libgfortran_sover}%{libgfortran_suffix}-64bit -p /sbin/ldconfig + +%postun -n libgfortran%{libgfortran_sover}%{libgfortran_suffix}-64bit -p /sbin/ldconfig + +%package -n libquadmath%{libquadmath_sover}%{libquadmath_suffix} +Summary: The GNU Fortran Compiler Quadmath Runtime Library +License: LGPL-2.1-only +Group: Development/Languages/Fortran +Provides: libquadmath%{libquadmath_sover} = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libquadmath%{libquadmath_sover} + +%description -n libquadmath%{libquadmath_sover}%{libquadmath_suffix} +The runtime library needed to run programs compiled with the Fortran compiler +of the GNU Compiler Collection (GCC) and quadruple precision floating point +operations. + +%post -n libquadmath%{libquadmath_sover}%{libquadmath_suffix} -p /sbin/ldconfig + +%postun -n libquadmath%{libquadmath_sover}%{libquadmath_suffix} -p /sbin/ldconfig + +%package -n libquadmath%{libquadmath_sover}%{libquadmath_suffix}-32bit +Summary: The GNU Fortran Compiler Quadmath Runtime Library +License: LGPL-2.1-only +Group: Development/Languages/Fortran +Provides: libquadmath%{libquadmath_sover}-32bit = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libquadmath%{libquadmath_sover}-32bit + +%description -n libquadmath%{libquadmath_sover}%{libquadmath_suffix}-32bit +The runtime library needed to run programs compiled with the Fortran compiler +of the GNU Compiler Collection (GCC) and quadruple precision floating point +operations. + +%post -n libquadmath%{libquadmath_sover}%{libquadmath_suffix}-32bit -p /sbin/ldconfig + +%postun -n libquadmath%{libquadmath_sover}%{libquadmath_suffix}-32bit -p /sbin/ldconfig + +%package -n libquadmath%{libquadmath_sover}%{libquadmath_suffix}-64bit +Summary: The GNU Fortran Compiler Quadmath Runtime Library +License: LGPL-2.1-only +Group: Development/Languages/Fortran +Provides: libquadmath%{libquadmath_sover}-64bit = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libquadmath%{libquadmath_sover}-64bit + +%description -n libquadmath%{libquadmath_sover}%{libquadmath_suffix}-64bit +The runtime library needed to run programs compiled with the Fortran compiler +of the GNU Compiler Collection (GCC) and quadruple precision floating point +operations. + +%post -n libquadmath%{libquadmath_sover}%{libquadmath_suffix}-64bit -p /sbin/ldconfig + +%postun -n libquadmath%{libquadmath_sover}%{libquadmath_suffix}-64bit -p /sbin/ldconfig + +%package -n libitm%{libitm_sover}%{libitm_suffix} +Summary: The GNU Compiler Transactional Memory Runtime Library +License: MIT +Group: Development/Languages/C and C++ +Provides: libitm%{libitm_sover} = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libitm%{libitm_sover} + +%description -n libitm%{libitm_sover}%{libitm_suffix} +The runtime library needed to run programs compiled with the +-fgnu-tm option of the GNU Compiler Collection (GCC). + +%post -n libitm%{libitm_sover}%{libitm_suffix} -p /sbin/ldconfig + +%postun -n libitm%{libitm_sover}%{libitm_suffix} -p /sbin/ldconfig + +%package -n libitm%{libitm_sover}%{libitm_suffix}-32bit +Summary: The GNU Compiler Transactional Memory Runtime Library +License: MIT +Group: Development/Languages/C and C++ +Provides: libitm%{libitm_sover}-32bit = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libitm%{libitm_sover}-32bit + +%description -n libitm%{libitm_sover}%{libitm_suffix}-32bit +The runtime library needed to run programs compiled with the +-fgnu-tm option of the GNU Compiler Collection (GCC). + +%post -n libitm%{libitm_sover}%{libitm_suffix}-32bit -p /sbin/ldconfig + +%postun -n libitm%{libitm_sover}%{libitm_suffix}-32bit -p /sbin/ldconfig + +%package -n libitm%{libitm_sover}%{libitm_suffix}-64bit +Summary: The GNU Compiler Transactional Memory Runtime Library +License: MIT +Group: Development/Languages/C and C++ +Provides: libitm%{libitm_sover}-64bit = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libitm%{libitm_sover}-64bit + +%description -n libitm%{libitm_sover}%{libitm_suffix}-64bit +The runtime library needed to run programs compiled with the +-fgnu-tm option of the GNU Compiler Collection (GCC). + +%post -n libitm%{libitm_sover}%{libitm_suffix}-64bit -p /sbin/ldconfig + +%postun -n libitm%{libitm_sover}%{libitm_suffix}-64bit -p /sbin/ldconfig + +%package -n libasan%{libasan_sover}%{libasan_suffix} +Summary: The GNU Compiler Address Sanitizer Runtime Library +License: MIT +Group: Development/Languages/C and C++ +Provides: libasan%{libasan_sover} = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libasan%{libasan_sover} + +%description -n libasan%{libasan_sover}%{libasan_suffix} +The runtime library needed to run programs compiled with the +-fsanitize=address option of the GNU Compiler Collection (GCC). + +%post -n libasan%{libasan_sover}%{libasan_suffix} -p /sbin/ldconfig + +%postun -n libasan%{libasan_sover}%{libasan_suffix} -p /sbin/ldconfig + +%package -n libasan%{libasan_sover}%{libasan_suffix}-32bit +Summary: The GNU Compiler Address Sanitizer Runtime Library +License: MIT +Group: Development/Languages/C and C++ +Provides: libasan%{libasan_sover}-32bit = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libasan%{libasan_sover}-32bit + +%description -n libasan%{libasan_sover}%{libasan_suffix}-32bit +The runtime library needed to run programs compiled with the +-fsanitize=address option of the GNU Compiler Collection (GCC). + +%post -n libasan%{libasan_sover}%{libasan_suffix}-32bit -p /sbin/ldconfig + +%postun -n libasan%{libasan_sover}%{libasan_suffix}-32bit -p /sbin/ldconfig + +%package -n libasan%{libasan_sover}%{libasan_suffix}-64bit +Summary: The GNU Compiler Address Sanitizer Runtime Library +License: MIT +Group: Development/Languages/C and C++ +Provides: libasan%{libasan_sover}-64bit = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libasan%{libasan_sover}-64bit + +%description -n libasan%{libasan_sover}%{libasan_suffix}-64bit +The runtime library needed to run programs compiled with the +-fsanitize=address option of the GNU Compiler Collection (GCC). + +%post -n libasan%{libasan_sover}%{libasan_suffix}-64bit -p /sbin/ldconfig + +%postun -n libasan%{libasan_sover}%{libasan_suffix}-64bit -p /sbin/ldconfig + +%package -n libtsan%{libtsan_sover}%{libtsan_suffix} +Summary: The GNU Compiler Thread Sanitizer Runtime Library +License: MIT +Group: Development/Languages/C and C++ +Provides: libtsan%{libtsan_sover} = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libtsan%{libtsan_sover} + +%description -n libtsan%{libtsan_sover}%{libtsan_suffix} +The runtime library needed to run programs compiled with the +-fsanitize=thread option of the GNU Compiler Collection (GCC). + +%post -n libtsan%{libtsan_sover}%{libtsan_suffix} -p /sbin/ldconfig + +%postun -n libtsan%{libtsan_sover}%{libtsan_suffix} -p /sbin/ldconfig + +%package -n libtsan%{libtsan_sover}%{libtsan_suffix}-32bit +Summary: The GNU Compiler Thread Sanitizer Runtime Library +License: MIT +Group: Development/Languages/C and C++ +Provides: libtsan%{libtsan_sover}-32bit = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libtsan%{libtsan_sover}-32bit + +%description -n libtsan%{libtsan_sover}%{libtsan_suffix}-32bit +The runtime library needed to run programs compiled with the +-fsanitize=thread option of the GNU Compiler Collection (GCC). + +%post -n libtsan%{libtsan_sover}%{libtsan_suffix}-32bit -p /sbin/ldconfig + +%postun -n libtsan%{libtsan_sover}%{libtsan_suffix}-32bit -p /sbin/ldconfig + +%package -n libtsan%{libtsan_sover}%{libtsan_suffix}-64bit +Summary: The GNU Compiler Thread Sanitizer Runtime Library +License: MIT +Group: Development/Languages/C and C++ +Provides: libtsan%{libtsan_sover}-64bit = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libtsan%{libtsan_sover}-64bit + +%description -n libtsan%{libtsan_sover}%{libtsan_suffix}-64bit +The runtime library needed to run programs compiled with the +-fsanitize=thread option of the GNU Compiler Collection (GCC). + +%post -n libtsan%{libtsan_sover}%{libtsan_suffix}-64bit -p /sbin/ldconfig + +%postun -n libtsan%{libtsan_sover}%{libtsan_suffix}-64bit -p /sbin/ldconfig + +%package -n libhwasan%{libhwasan_sover}%{libhwasan_suffix} +Summary: The GNU Compiler Hardware-assisted Address Sanitizer Runtime Library +License: MIT +Group: Development/Languages/C and C++ +Provides: libhwasan%{libhwasan_sover} = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libhwasan%{libhwasan_sover} + +%description -n libhwasan%{libhwasan_sover}%{libhwasan_suffix} +The runtime library needed to run programs compiled with the +-fsanitize=hwaddress option of the GNU Compiler Collection (GCC). + +%post -n libhwasan%{libhwasan_sover}%{libhwasan_suffix} -p /sbin/ldconfig + +%postun -n libhwasan%{libhwasan_sover}%{libhwasan_suffix} -p /sbin/ldconfig + +%package -n libhwasan%{libhwasan_sover}%{libhwasan_suffix}-32bit +Summary: The GNU Compiler Hardware-assisted Address Sanitizer Runtime Library +License: MIT +Group: Development/Languages/C and C++ +Provides: libhwasan%{libhwasan_sover}-32bit = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libhwasan%{libhwasan_sover}-32bit + +%description -n libhwasan%{libhwasan_sover}%{libhwasan_suffix}-32bit +The runtime library needed to run programs compiled with the +-fsanitize=hwaddress option of the GNU Compiler Collection (GCC). + +%post -n libhwasan%{libhwasan_sover}%{libhwasan_suffix}-32bit -p /sbin/ldconfig + +%postun -n libhwasan%{libhwasan_sover}%{libhwasan_suffix}-32bit -p /sbin/ldconfig + +%package -n libhwasan%{libhwasan_sover}%{libhwasan_suffix}-64bit +Summary: The GNU Compiler Hardware-assisted Address Sanitizer Runtime Library +License: MIT +Group: Development/Languages/C and C++ +Provides: libhwasan%{libhwasan_sover}-64bit = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libhwasan%{libhwasan_sover}-64bit + +%description -n libhwasan%{libhwasan_sover}%{libhwasan_suffix}-64bit +The runtime library needed to run programs compiled with the +-fsanitize=hwaddress option of the GNU Compiler Collection (GCC). + +%post -n libhwasan%{libhwasan_sover}%{libhwasan_suffix}-64bit -p /sbin/ldconfig + +%postun -n libhwasan%{libhwasan_sover}%{libhwasan_suffix}-64bit -p /sbin/ldconfig + +%package -n libatomic%{libatomic_sover}%{libatomic_suffix} +Summary: The GNU Compiler Atomic Operations Runtime Library +License: GPL-3.0-or-later WITH GCC-exception-3.1 +Group: Development/Languages/C and C++ +Provides: libatomic%{libatomic_sover} = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libatomic%{libatomic_sover} + +%description -n libatomic%{libatomic_sover}%{libatomic_suffix} +The runtime library for atomic operations of the GNU Compiler Collection (GCC). + +%post -n libatomic%{libatomic_sover}%{libatomic_suffix} -p /sbin/ldconfig + +%postun -n libatomic%{libatomic_sover}%{libatomic_suffix} -p /sbin/ldconfig + +%package -n libatomic%{libatomic_sover}%{libatomic_suffix}-32bit +Summary: The GNU Compiler Atomic Operations Runtime Library +License: GPL-3.0-or-later WITH GCC-exception-3.1 +Group: Development/Languages/C and C++ +Provides: libatomic%{libatomic_sover}-32bit = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libatomic%{libatomic_sover}-32bit + +%description -n libatomic%{libatomic_sover}%{libatomic_suffix}-32bit +The runtime library for atomic operations of the GNU Compiler Collection (GCC). + +%post -n libatomic%{libatomic_sover}%{libatomic_suffix}-32bit -p /sbin/ldconfig + +%postun -n libatomic%{libatomic_sover}%{libatomic_suffix}-32bit -p /sbin/ldconfig + +%package -n libatomic%{libatomic_sover}%{libatomic_suffix}-64bit +Summary: The GNU Compiler Atomic Operations Runtime Library +License: GPL-3.0-or-later WITH GCC-exception-3.1 +Group: Development/Languages/C and C++ +Provides: libatomic%{libatomic_sover}-64bit = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libatomic%{libatomic_sover}-64bit + +%description -n libatomic%{libatomic_sover}%{libatomic_suffix}-64bit +The runtime library for atomic operations of the GNU Compiler Collection (GCC). + +%post -n libatomic%{libatomic_sover}%{libatomic_suffix}-64bit -p /sbin/ldconfig + +%postun -n libatomic%{libatomic_sover}%{libatomic_suffix}-64bit -p /sbin/ldconfig + +%package -n liblsan%{liblsan_sover}%{liblsan_suffix} +Summary: The GNU Compiler Leak Sanitizer Runtime Library +License: MIT +Group: Development/Languages/C and C++ +Provides: liblsan%{liblsan_sover} = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict liblsan%{liblsan_sover} + +%description -n liblsan%{liblsan_sover}%{liblsan_suffix} +The runtime library needed to run programs compiled with the +-fsanitize=leak option of the GNU Compiler Collection (GCC). + +%post -n liblsan%{liblsan_sover}%{liblsan_suffix} -p /sbin/ldconfig + +%postun -n liblsan%{liblsan_sover}%{liblsan_suffix} -p /sbin/ldconfig + +%package -n liblsan%{liblsan_sover}%{liblsan_suffix}-32bit +Summary: The GNU Compiler Leak Sanitizer Runtime Library +License: MIT +Group: Development/Languages/C and C++ +Provides: liblsan%{liblsan_sover}-32bit = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict liblsan%{liblsan_sover}-32bit + +%description -n liblsan%{liblsan_sover}%{liblsan_suffix}-32bit +The runtime library needed to run programs compiled with the +-fsanitize=leak option of the GNU Compiler Collection (GCC). + +%post -n liblsan%{liblsan_sover}%{liblsan_suffix}-32bit -p /sbin/ldconfig + +%postun -n liblsan%{liblsan_sover}%{liblsan_suffix}-32bit -p /sbin/ldconfig + +%package -n liblsan%{liblsan_sover}%{liblsan_suffix}-64bit +Summary: The GNU Compiler Leak Sanitizer Runtime Library +License: MIT +Group: Development/Languages/C and C++ +Provides: liblsan%{liblsan_sover}-64bit = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict liblsan%{liblsan_sover}-64bit + +%description -n liblsan%{liblsan_sover}%{liblsan_suffix}-64bit +The runtime library needed to run programs compiled with the +-fsanitize=leak option of the GNU Compiler Collection (GCC). + +%post -n liblsan%{liblsan_sover}%{liblsan_suffix}-64bit -p /sbin/ldconfig + +%postun -n liblsan%{liblsan_sover}%{liblsan_suffix}-64bit -p /sbin/ldconfig + +%package -n libubsan%{libubsan_sover}%{libubsan_suffix} +Summary: The GNU Compiler Undefined Sanitizer Runtime Library +License: MIT +Group: Development/Languages/C and C++ +Provides: libubsan%{libubsan_sover} = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libubsan%{libubsan_sover} + +%description -n libubsan%{libubsan_sover}%{libubsan_suffix} +The runtime library needed to run programs compiled with the +-fsanitize=undefined option of the GNU Compiler Collection (GCC). + +%post -n libubsan%{libubsan_sover}%{libubsan_suffix} -p /sbin/ldconfig + +%postun -n libubsan%{libubsan_sover}%{libubsan_suffix} -p /sbin/ldconfig + +%package -n libubsan%{libubsan_sover}%{libubsan_suffix}-32bit +Summary: The GNU Compiler Undefined Sanitizer Runtime Library +License: MIT +Group: Development/Languages/C and C++ +Provides: libubsan%{libubsan_sover}-32bit = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libubsan%{libubsan_sover}-32bit + +%description -n libubsan%{libubsan_sover}%{libubsan_suffix}-32bit +The runtime library needed to run programs compiled with the +-fsanitize=undefined option of the GNU Compiler Collection (GCC). + +%post -n libubsan%{libubsan_sover}%{libubsan_suffix}-32bit -p /sbin/ldconfig + +%postun -n libubsan%{libubsan_sover}%{libubsan_suffix}-32bit -p /sbin/ldconfig + +%package -n libubsan%{libubsan_sover}%{libubsan_suffix}-64bit +Summary: The GNU Compiler Undefined Sanitizer Runtime Library +License: MIT +Group: Development/Languages/C and C++ +Provides: libubsan%{libubsan_sover}-64bit = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libubsan%{libubsan_sover}-64bit + +%description -n libubsan%{libubsan_sover}%{libubsan_suffix}-64bit +The runtime library needed to run programs compiled with the +-fsanitize=undefined option of the GNU Compiler Collection (GCC). + +%post -n libubsan%{libubsan_sover}%{libubsan_suffix}-64bit -p /sbin/ldconfig + +%postun -n libubsan%{libubsan_sover}%{libubsan_suffix}-64bit -p /sbin/ldconfig + +%package -n libvtv%{libvtv_sover}%{libvtv_suffix} +Summary: The GNU Compiler Vtable Verifier Runtime Library +License: MIT +Group: Development/Languages/C and C++ +Provides: libvtv%{libvtv_sover} = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libvtv%{libvtv_sover} + +%description -n libvtv%{libvtv_sover}%{libvtv_suffix} +The runtime library needed to run programs compiled with the +-fvtable-verify option of the GNU Compiler Collection (GCC). + +%post -n libvtv%{libvtv_sover}%{libvtv_suffix} -p /sbin/ldconfig + +%postun -n libvtv%{libvtv_sover}%{libvtv_suffix} -p /sbin/ldconfig + +%package -n libvtv%{libvtv_sover}%{libvtv_suffix}-32bit +Summary: The GNU Compiler Vtable Verifier Runtime Library +License: MIT +Group: Development/Languages/C and C++ +Provides: libvtv%{libvtv_sover}-32bit = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libvtv%{libvtv_sover}-32bit + +%description -n libvtv%{libvtv_sover}%{libvtv_suffix}-32bit +The runtime library needed to run programs compiled with the +-fvtable-verify option of the GNU Compiler Collection (GCC). + +%post -n libvtv%{libvtv_sover}%{libvtv_suffix}-32bit -p /sbin/ldconfig + +%postun -n libvtv%{libvtv_sover}%{libvtv_suffix}-32bit -p /sbin/ldconfig + +%package -n libvtv%{libvtv_sover}%{libvtv_suffix}-64bit +Summary: The GNU Compiler Vtable Verifier Runtime Library +License: MIT +Group: Development/Languages/C and C++ +Provides: libvtv%{libvtv_sover}-64bit = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libvtv%{libvtv_sover}-64bit + +%description -n libvtv%{libvtv_sover}%{libvtv_suffix}-64bit +The runtime library needed to run programs compiled with the +-fvtable-verify option of the GNU Compiler Collection (GCC). + +%post -n libvtv%{libvtv_sover}%{libvtv_suffix}-64bit -p /sbin/ldconfig + +%postun -n libvtv%{libvtv_sover}%{libvtv_suffix}-64bit -p /sbin/ldconfig + +%package -n libstdc++%{libstdcxx_sover}%{libdevel_suffix}-doc +Summary: Documentation for the GNU C++ standard library +License: GPL-3.0-or-later +Group: Documentation/HTML +%if 0%{?suse_version} >= 1120 +BuildArch: noarch +%endif + +%description -n libstdc++%{libstdcxx_sover}%{libdevel_suffix}-doc +Extensive HTML documentation for the GNU C++ standard library. + +%package go +Summary: GNU Go Compiler +License: GPL-3.0-or-later +Group: Development/Languages/Other +Requires: gcc12 = %{version}-%{release} +Requires: gcc12-go = %{version}-%{release} +Requires: libgo%{libgo_sover} >= %{version}-%{release} + +%description go +This package contains a Go compiler and associated development +files based on the GNU GCC technology. + +%package go-32bit +Summary: GNU Go Compiler +License: GPL-3.0-or-later +Group: Development/Languages/Other +Requires: gcc12-32bit = %{version}-%{release} +Requires: gcc12-go = %{version}-%{release} +Requires: libgo%{libgo_sover}-32bit >= %{version}-%{release} + +%description go-32bit +This package contains a Go compiler and associated development +files based on the GNU GCC technology. + +%package go-64bit +Summary: GNU Go Compiler +License: GPL-3.0-or-later +Group: Development/Languages/Other +Requires: gcc12-64bit = %{version}-%{release} +Requires: gcc12-go = %{version}-%{release} +Requires: libgo%{libgo_sover}-64bit >= %{version}-%{release} + +%description go-64bit +This package contains a Go compiler and associated development +files based on the GNU GCC technology. + +%package -n libgo%{libgo_sover}%{libgo_suffix} +Summary: GNU Go compiler runtime library +License: BSD-3-Clause +Group: Development/Languages/Other +Provides: libgo%{libgo_sover} = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libgo%{libgo_sover} + +%description -n libgo%{libgo_sover}%{libgo_suffix} +Runtime library for the GNU Go language. + +%post -n libgo%{libgo_sover}%{libgo_suffix} -p /sbin/ldconfig + +%postun -n libgo%{libgo_sover}%{libgo_suffix} -p /sbin/ldconfig + +%package -n libgo%{libgo_sover}%{libgo_suffix}-32bit +Summary: GNU Go compiler runtime library +License: BSD-3-Clause +Group: Development/Languages/Other +Provides: libgo%{libgo_sover}-32bit = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libgo%{libgo_sover}-32bit + +%description -n libgo%{libgo_sover}%{libgo_suffix}-32bit +Runtime library for the GNU Go language. + +%post -n libgo%{libgo_sover}%{libgo_suffix}-32bit -p /sbin/ldconfig + +%postun -n libgo%{libgo_sover}%{libgo_suffix}-32bit -p /sbin/ldconfig + +%package -n libgo%{libgo_sover}%{libgo_suffix}-64bit +Summary: GNU Go compiler runtime library +License: BSD-3-Clause +Group: Development/Languages/Other +Provides: libgo%{libgo_sover}-64bit = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libgo%{libgo_sover}-64bit + +%description -n libgo%{libgo_sover}%{libgo_suffix}-64bit +Runtime library for the GNU Go language. + +%post -n libgo%{libgo_sover}%{libgo_suffix}-64bit -p /sbin/ldconfig + +%postun -n libgo%{libgo_sover}%{libgo_suffix}-64bit -p /sbin/ldconfig + +%package d +Summary: GNU D Compiler +License: GPL-3.0-or-later +Group: Development/Languages/Other +Requires: gcc12 = %{version}-%{release} +Requires: gcc12-d = %{version}-%{release} +Requires: libgdruntime%{libgdruntime_sover} >= %{version}-%{release} +Requires: libgphobos%{libgphobos_sover} >= %{version}-%{release} + +%description d +This package contains a D compiler and associated development +files based on the GNU GCC technology. + +%package d-32bit +Summary: GNU D Compiler +License: GPL-3.0-or-later +Group: Development/Languages/Other +Requires: gcc12-32bit = %{version}-%{release} +Requires: gcc12-d = %{version}-%{release} +Requires: libgdruntime%{libgdruntime_sover}-32bit >= %{version}-%{release} +Requires: libgphobos%{libgphobos_sover}-32bit >= %{version}-%{release} + +%description d-32bit +This package contains a D compiler and associated development +files based on the GNU GCC technology. + +%package d-64bit +Summary: GNU D Compiler +License: GPL-3.0-or-later +Group: Development/Languages/Other +Requires: gcc12-64bit = %{version}-%{release} +Requires: gcc12-d = %{version}-%{release} +Requires: libgdruntime%{libgdruntime_sover}-64bit >= %{version}-%{release} +Requires: libgphobos%{libgphobos_sover}-64bit >= %{version}-%{release} + +%description d-64bit +This package contains a D compiler and associated development +files based on the GNU GCC technology. + +%package -n libgphobos%{libgphobos_sover}%{libgphobos_suffix} +Summary: GNU D compiler runtime library +License: BSL-1.0 +Group: Development/Languages/Other +Provides: libgphobos%{libgphobos_sover} = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libgphobos%{libgphobos_sover} + +%description -n libgphobos%{libgphobos_sover}%{libgphobos_suffix} +Runtime library for the GNU D language. + +%post -n libgphobos%{libgphobos_sover}%{libgphobos_suffix} -p /sbin/ldconfig + +%postun -n libgphobos%{libgphobos_sover}%{libgphobos_suffix} -p /sbin/ldconfig + +%package -n libgphobos%{libgphobos_sover}%{libgphobos_suffix}-32bit +Summary: GNU D compiler runtime library +License: BSL-1.0 +Group: Development/Languages/Other +Provides: libgphobos%{libgphobos_sover}-32bit = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libgphobos%{libgphobos_sover}-32bit + +%description -n libgphobos%{libgphobos_sover}%{libgphobos_suffix}-32bit +Runtime library for the GNU D language. + +%post -n libgphobos%{libgphobos_sover}%{libgphobos_suffix}-32bit -p /sbin/ldconfig + +%postun -n libgphobos%{libgphobos_sover}%{libgphobos_suffix}-32bit -p /sbin/ldconfig + +%package -n libgphobos%{libgphobos_sover}%{libgphobos_suffix}-64bit +Summary: GNU D compiler runtime library +License: BSL-1.0 +Group: Development/Languages/Other +Provides: libgphobos%{libgphobos_sover}-64bit = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libgphobos%{libgphobos_sover}-64bit + +%description -n libgphobos%{libgphobos_sover}%{libgphobos_suffix}-64bit +Runtime library for the GNU D language. + +%post -n libgphobos%{libgphobos_sover}%{libgphobos_suffix}-64bit -p /sbin/ldconfig + +%postun -n libgphobos%{libgphobos_sover}%{libgphobos_suffix}-64bit -p /sbin/ldconfig + +%package -n libgdruntime%{libgdruntime_sover}%{libgdruntime_suffix} +Summary: GNU D compiler runtime library +License: BSL-1.0 +Group: Development/Languages/Other +Provides: libgdruntime%{libgdruntime_sover} = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libgdruntime%{libgdruntime_sover} + +%description -n libgdruntime%{libgdruntime_sover}%{libgdruntime_suffix} +Runtime library for the GNU D language. + +%post -n libgdruntime%{libgdruntime_sover}%{libgdruntime_suffix} -p /sbin/ldconfig + +%postun -n libgdruntime%{libgdruntime_sover}%{libgdruntime_suffix} -p /sbin/ldconfig + +%package -n libgdruntime%{libgdruntime_sover}%{libgdruntime_suffix}-32bit +Summary: GNU D compiler runtime library +License: BSL-1.0 +Group: Development/Languages/Other +Provides: libgdruntime%{libgdruntime_sover}-32bit = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libgdruntime%{libgdruntime_sover}-32bit + +%description -n libgdruntime%{libgdruntime_sover}%{libgdruntime_suffix}-32bit +Runtime library for the GNU D language. + +%post -n libgdruntime%{libgdruntime_sover}%{libgdruntime_suffix}-32bit -p /sbin/ldconfig + +%postun -n libgdruntime%{libgdruntime_sover}%{libgdruntime_suffix}-32bit -p /sbin/ldconfig + +%package -n libgdruntime%{libgdruntime_sover}%{libgdruntime_suffix}-64bit +Summary: GNU D compiler runtime library +License: BSL-1.0 +Group: Development/Languages/Other +Provides: libgdruntime%{libgdruntime_sover}-64bit = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libgdruntime%{libgdruntime_sover}-64bit + +%description -n libgdruntime%{libgdruntime_sover}%{libgdruntime_suffix}-64bit +Runtime library for the GNU D language. + +%post -n libgdruntime%{libgdruntime_sover}%{libgdruntime_suffix}-64bit -p /sbin/ldconfig + +%postun -n libgdruntime%{libgdruntime_sover}%{libgdruntime_suffix}-64bit -p /sbin/ldconfig + +%package -n libgccjit%{libgccjit_sover}%{libgccjit_suffix} +Summary: The GNU Compiler Collection JIT library +License: GPL-3.0-or-later +Group: Development/Languages/C and C++ +Provides: libgccjit%{libgccjit_sover} = %{version}-%{release} +# Only one package may provide this - allows multiple gcc versions +# to co-exist without an overly large list of provides/obsoletes +Conflicts: %selfconflict libgccjit%{libgccjit_sover} +Requires: gcc12 + +%description -n libgccjit%{libgccjit_sover}%{libgccjit_suffix} +Support for embedding GCC inside programs and libraries + +%post -n libgccjit%{libgccjit_sover}%{libgccjit_suffix} -p /sbin/ldconfig + +%postun -n libgccjit%{libgccjit_sover}%{libgccjit_suffix} -p /sbin/ldconfig + +%package -n libgccjit%{libgccjit_sover}-devel%{libdevel_suffix} +Summary: Support for embedding GCC inside programs and libraries +License: GPL-3.0-or-later +Group: Development/Languages/C and C++ +Provides: libgccjit%{libgccjit_sover}-devel = %{version}-%{release} +# Only one gccjit package can be installed at the same time since +# header files conflict +Conflicts: %selfconflict libgccjit%{libgccjit_sover}-devel +Requires: libgccjit%{libgccjit_sover}%{libgccjit_suffix} + +%description -n libgccjit%{libgccjit_sover}-devel%{libdevel_suffix} +Package contains header files and documentation for GCC JIT front-end. + +%package -n gcc12-testresults +Summary: Testsuite results +License: SUSE-Public-Domain +Group: Development/Languages/C and C++ + +%description -n gcc12-testresults +Results from running the gcc and target library testsuites. + + + + +# Define the canonical target and host architecture +# %%gcc_target_arch is supposed to be the full target triple +# %%cross_arch is supposed to be the rpm target variant arch +# %%TARGET_ARCH will be the canonicalized target CPU part +# %%HOST_ARCH will be the canonicalized host CPU part +%if 0%{?gcc_target_arch:1} +%define TARGET_ARCH %(echo %{cross_arch} | sed -e "s/i.86/i586/;s/ppc/powerpc/;s/sparc64.*/sparc64/;s/sparcv.*/sparc/;") +%else +%define TARGET_ARCH %(echo %{_target_cpu} | sed -e "s/i.86/i586/;s/ppc/powerpc/;s/sparc64.*/sparc64/;s/sparcv.*/sparc/;") +%endif +%if 0%{?disable_32bit:1} +%define biarch 0 +%else +%define biarch %(case " %{biarch_targets} " in (*" %{TARGET_ARCH} "*) echo 1;; (*) echo 0;; esac) +%endif + +%define HOST_ARCH %(echo %{_host_cpu} | sed -e "s/i.86/i586/;s/ppc/powerpc/;s/sparc64.*/sparc64/;s/sparcv.*/sparc/;") +%ifarch ppc +%define GCCDIST powerpc64-suse-linux +%else +%ifarch %sparc +%define GCCDIST sparc64-suse-linux +%else +%ifarch %arm +%define GCCDIST %{HOST_ARCH}-suse-linux-gnueabi +%else +%define GCCDIST %{HOST_ARCH}-suse-linux +%endif +%endif +%endif + +%define libsubdir %{_libdir}/gcc/%{GCCDIST}/%{gcc_dir_version} +%define gxxinclude %{_prefix}/include/c++/%{gcc_dir_version} + +# Versionspecific directories +%define versmainlibdir %{libsubdir} +%define versmainlibdirbi32 %{libsubdir}/32 +%define versmainlibdirbi64 %{libsubdir}/64 +%ifarch ppc +%define versmainlibdirbi32 %{libsubdir} +%define versmainlibdirbi64 %{libsubdir}/64 +%endif +%if %{build_primary_64bit} +%define versmainlibdirbi %{versmainlibdirbi32} +%else +%define versmainlibdirbi %{versmainlibdirbi64} +%endif + +%define mainlibdir %{_libdir} +%define mainlibdirbi32 %{_prefix}/lib +%define mainlibdirbi64 %{_prefix}/lib64 +%if %{build_primary_64bit} +%define mainlibdirbi %{mainlibdirbi32} +%else +%define mainlibdirbi %{mainlibdirbi64} +%endif + +# Now define a few macros that make it easy to package libs and +# related files just to the right package, without caring for the +# exact path the files are in. +# %%mainlib package X from all dirs that belong to the main package +# %%biarchlib package X from all dirs that belong to the -32/64bit package +%define mainlib() %{mainlibdir}/%1\ +%{nil} +%define biarchlib() %{nil} +%if %{biarch} +%if !%{separate_biarch} +%define mainlib() %{mainlibdir}/%1\ +%{mainlibdirbi}/%1\ +%{nil} +%else +%define biarchlib() %{mainlibdirbi}/%1\ +%{nil} +%endif +%endif + +%define versmainlib() %{versmainlibdir}/%1\ +%{nil} +%define versbiarchlib() %{nil} +%if %{biarch} +%if !%{separate_biarch} +%define versmainlib() %{versmainlibdir}/%1\ +%{versmainlibdirbi}/%1\ +%{nil} +%else +%define versbiarchlib() %{versmainlibdirbi}/%1\ +%{nil} +%endif +%endif + +%if 0%{suse_version} >= 1500 +# Synchronize output by lines, useful for configure output +%define make_output_sync -Oline +%endif + +%prep +%if 0%{?nvptx_newlib:1}%{?amdgcn_newlib:1} +%setup -q -n gcc-%{version} -a 5 +ln -s newlib-4.2.0.20211231/newlib . +%else +%setup -q -n gcc-%{version} +%endif + +#test patching start + +%patch2 +%patch5 +%patch6 +%patch7 +%patch11 +%patch15 +%patch16 +%patch17 -p1 +%patch22 -p1 +%patch23 -p1 +%patch24 -p1 +%patch25 -p1 +# These patches are needed only for llvm11 +%if "%{TARGET_ARCH}" == "amdgcn" && %{suse_version} < 1550 +%patch18 -p1 +%patch20 -p1 +%endif +# In SLE15 and earlier default to dwarf4, not dwarf5 +%if %{suse_version} < 1550 +%patch19 -p1 +%endif +%patch51 +%patch60 -p1 +%patch61 + +#test patching end + +%build +%define _lto_cflags %{nil} +# Avoid rebuilding of generated files +contrib/gcc_update --touch + +# SLE11 does not allow empty rpms +%if %{suse_version} < 1310 +echo "This is a dummy package to provide a dependency." > README +%endif + +rm -rf obj-%{GCCDIST} +mkdir obj-%{GCCDIST} +cd obj-%{GCCDIST} +RPM_OPT_FLAGS="$RPM_OPT_FLAGS -U_FORTIFY_SOURCE" +RPM_OPT_FLAGS=`echo $RPM_OPT_FLAGS|sed -e 's/-fno-rtti//g' -e 's/-fno-exceptions//g' -e 's/-Wmissing-format-attribute//g' -e 's/-fstack-protector[^ ]*//g' -e 's/-ffortify=.//g' -e 's/-Wall//g' -e 's/-m32//g' -e 's/-m64//g'` +%ifarch %ix86 +# -mcpu is superceded by -mtune but -mtune is not supported by +# our bootstrap compiler. -mcpu gives a warning that stops +# the build process, so remove it for now. Also remove all other +# -march and -mtune flags. They are superseeded by proper +# default compiler settings now. +RPM_OPT_FLAGS=`echo $RPM_OPT_FLAGS|sed -e 's/-mcpu=i.86//g' -e 's/-march=i.86//g' -e 's/-mtune=i.86//g'` +%endif +%ifarch s390 s390x +RPM_OPT_FLAGS=`echo $RPM_OPT_FLAGS|sed -e 's/-fsigned-char//g'` +RPM_OPT_FLAGS=`echo $RPM_OPT_FLAGS|sed -e 's/-O1/-O2/g'` +%endif +%if 0%{?gcc_target_arch:1} +# Kill all -march/tune/cpu because that screws building the target libs +RPM_OPT_FLAGS=`echo $RPM_OPT_FLAGS|sed -e 's/-m\(arch\|tune\|cpu\)=[^ ]*//g'` +%endif +# Replace 2 spaces by one finally +RPM_OPT_FLAGS=`echo $RPM_OPT_FLAGS|sed -e 's/ / /g'` + +languages=c +%if %{build_cp} +languages=$languages,c++ +%endif +%if %{build_objc} +languages=$languages,objc +%endif +%if %{build_fortran} +languages=$languages,fortran +%endif +%if %{build_objcp} +languages=$languages,obj-c++ +%endif +%if %{build_ada} +languages=$languages,ada +%endif +%if %{build_go} +languages=$languages,go +%endif +%if %{build_d} +languages=$languages,d +%endif +%if %{build_jit} +languages=$languages,jit +%endif + +# In general we want to ship release checking enabled compilers +# which is the default for released compilers +#ENABLE_CHECKING="--enable-checking=yes" +ENABLE_CHECKING="--enable-checking=release" +#ENABLE_CHECKING="" + +# Work around tail/head -1 changes +export _POSIX2_VERSION=199209 + +%if "%{TARGET_ARCH}" == "amdgcn" +mkdir -p target-tools/bin +ln -s /usr/bin/llvm-ar target-tools/bin/amdgcn-amdhsa-ar +ln -s /usr/bin/llvm-mc target-tools/bin/amdgcn-amdhsa-as +ln -s /usr/bin/lld target-tools/bin/amdgcn-amdhsa-ld +ln -s /usr/bin/llvm-nm target-tools/bin/amdgcn-amdhsa-nm +ln -s /usr/bin/llvm-ranlib target-tools/bin/amdgcn-amdhsa-ranlib +export PATH="`pwd`/target-tools/bin:$PATH" +%endif + +%if "%{hostsuffix}" != "" +mkdir -p host-tools/bin +# Using the host gnatmake like +# CC="gcc%%{hostsuffix}" GNATBIND="gnatbind%%{hostsuffix}" +# GNATMAKE="gnatmake%%{hostsuffix}" +# doesn't work due to PR33857, so an un-suffixed gnatmake has to be +# available +%if %{build_ada} +cp -a /usr/bin/gnatmake%{hostsuffix} host-tools/bin/gnatmake +cp -a /usr/bin/gnatlink%{hostsuffix} host-tools/bin/gnatlink +cp -a /usr/bin/gnatbind%{hostsuffix} host-tools/bin/gnatbind +%endif +cp -a /usr/bin/gcc%{hostsuffix} host-tools/bin/gcc +cp -a /usr/bin/g++%{hostsuffix} host-tools/bin/g++ +ln -sf /usr/%{_lib} host-tools/%{_lib} +export PATH="`pwd`/host-tools/bin:$PATH" +%endif + +%if %{build_d} && %{suse_version} < 1550 +# We are using gcc11-d to bootstrap d +export GDC=gdc-11 +%endif + +# libsanitizer needs and since the glibc/libxcrypt split +# we don't have that yet in a pure cross environment +%if 0%{?gcc_target_arch:1} + CONFARGS="$CONFARGS --disable-libsanitizer" +%endif + +CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_FLAGS" XCFLAGS="$RPM_OPT_FLAGS" \ +TCFLAGS="$RPM_OPT_FLAGS" \ +../configure \ + --prefix=%{_prefix} \ + --infodir=%{_infodir} \ + --mandir=%{_mandir} \ + --libdir=%{_libdir} \ + --libexecdir=%{_libdir} \ + --enable-languages=$languages \ +%if %{build_nvptx} || %{build_gcn} + --enable-offload-targets=\ +%if %{build_nvptx} +nvptx-none,\ +%endif +%if %{build_gcn} +amdgcn-amdhsa,\ +%endif + --enable-offload-defaulted \ +%endif +%if %{build_nvptx} + --without-cuda-driver \ +%endif +%if %{build_jit} + --enable-host-shared \ +%endif + $ENABLE_CHECKING \ + --disable-werror \ + --with-gxx-include-dir=%{_prefix}/include/c++/%{gcc_dir_version} \ + --enable-ssp \ + --disable-libssp \ +%if 0%{!?build_libvtv:1} + --disable-libvtv \ +%endif +%if 0%{suse_version} >= 1500 + --enable-cet=auto \ +%else + --disable-cet \ +%endif + --disable-libcc1 \ +%if %{enable_plugins} + --enable-plugin \ +%else + --disable-plugin \ +%endif + --with-bugurl="https://bugs.opensuse.org/" \ + --with-pkgversion="SUSE Linux" \ +%if 0%{?sysroot:1} + --with-slibdir=%{sysroot}/%{_lib} \ +%else + --with-slibdir=/%{_lib} \ +%endif + --with-system-zlib \ + --enable-libstdcxx-allocator=new \ + --disable-libstdcxx-pch \ +%if 0%{suse_version} <= 1320 + --with-default-libstdcxx-abi=gcc4-compatible \ +%endif +%if %{build_d} + --enable-libphobos \ +%endif + --enable-version-specific-runtime-libs \ + --with-gcc-major-version-only \ +%if 0%{!?gcc_target_arch:1} + --enable-linker-build-id \ +%else +%if 0%{?gcc_target_glibc:1} + --enable-linker-build-id \ +%endif +%endif + --enable-linux-futex \ +%if %{suse_version} >= 1315 +%ifarch %ix86 x86_64 ppc ppc64 ppc64le %arm aarch64 s390 s390x %sparc + --enable-gnu-indirect-function \ +%endif +%endif + --program-suffix=%{binsuffix} \ +%ifarch %{disable_multilib_arch} + --disable-multilib \ +%endif +%if 0%{!?gcc_target_arch:1} +%ifarch ia64 + --with-system-libunwind \ +%else + --without-system-libunwind \ +%endif +%endif +%if 0%{?gcc_target_arch:1} + --program-prefix=%{gcc_target_arch}- \ + --target=%{gcc_target_arch} \ + --disable-nls \ +%if 0%{?sysroot:1} + --with-sysroot=%sysroot \ +%endif +%if 0%{?build_sysroot:1} + --with-build-sysroot=%{build_sysroot} \ +%else +%if 0%{?sysroot:1} + --with-build-sysroot=%{sysroot} \ +%endif +%endif +%if 0%{?binutils_os:1} + --with-build-time-tools=/usr/%{binutils_os}/bin \ +%endif +%if 0%{?gcc_target_newlib} + --with-newlib \ +%if 0%{?gcc_libc_bootstrap:1} + --disable-gcov \ +%endif +%else +%if 0%{?gcc_libc_bootstrap:1} + --disable-gcov --disable-threads --disable-shared \ + --disable-libmudflap --disable-libssp --disable-libgomp \ + --disable-libquadmath --disable-libatomic \ + --without-headers --with-newlib \ +%endif +%endif +%if "%{TARGET_ARCH}" == "spu" + --with-gxx-include-dir=%sysroot/include/c++/%{gcc_dir_version} \ + --with-newlib \ +%endif +%if "%{TARGET_ARCH}" == "nvptx" + --enable-as-accelerator-for=%{GCCDIST} \ + --disable-sjlj-exceptions \ + --enable-newlib-io-long-long \ +%endif +%if "%{TARGET_ARCH}" == "amdgcn" + --enable-as-accelerator-for=%{GCCDIST} \ + --enable-libgomp \ +%endif +%if "%{TARGET_ARCH}" == "avr" + --enable-lto \ + --without-gxx-include-dir \ + --with-native-system-header-dir=/include \ +%endif +%endif +%if "%{TARGET_ARCH}" == "arm-none" + --enable-multilib \ + --with-multilib-list=aprofile,rmprofile \ + --disable-decimal-float \ + --disable-libffi \ + --disable-libgomp \ + --disable-libmudflap \ + --disable-libquadmath \ + --disable-shared \ + --disable-threads \ + --disable-tls \ +%endif +%if "%{TARGET_ARCH}" == "armv6hl" || "%{TARGET_ARCH}" == "arm" + --with-cpu=arm1176jzf-s \ + --with-float=hard \ + --with-abi=aapcs-linux \ + --with-fpu=vfpv2 \ + --disable-sjlj-exceptions \ +%endif +%if "%{TARGET_ARCH}" == "armv7hl" + --with-cpu=generic-armv7-a \ + --with-float=hard \ + --with-abi=aapcs-linux \ + --with-fpu=vfpv3-d16 \ + --disable-sjlj-exceptions \ +%endif +%if "%{TARGET_ARCH}" == "aarch64" + --enable-fix-cortex-a53-835769 \ + --enable-fix-cortex-a53-843419 \ +%endif +%if "%{TARGET_ARCH}" == "powerpc64le" +%if %{suse_version} >= 1350 + --with-cpu=power8 \ + --with-tune=power9 \ +%else +%if %{suse_version} >= 1315 && %{suse_version} != 1320 + --with-cpu=power8 \ + --with-tune=power8 \ +%else + --with-cpu=power7 \ + --with-tune=power7 \ +%endif +%endif +%if %{suse_version} > 1500 + --with-long-double-format=ieee \ +%else + --with-long-double-format=ibm \ +%endif + --enable-secureplt \ + --with-long-double-128 \ + --enable-targets=powerpcle-linux \ + --disable-multilib \ +%endif +%if "%{TARGET_ARCH}" == "powerpc" || "%{TARGET_ARCH}" == "powerpc64" +%if "%{TARGET_ARCH}" == "powerpc" + --with-cpu=default32 \ +%endif + --with-cpu-64=power4 \ + --enable-secureplt \ + --with-long-double-128 \ +%endif +%if "%{TARGET_ARCH}" == "sparc64" + --with-cpu=ultrasparc \ + --with-long-double-128 \ +%endif +%if "%{TARGET_ARCH}" == "sparc" + --with-cpu=v8 \ + --with-long-double-128 \ +%endif +%if "%{TARGET_ARCH}" == "i586" +%if 0%{?sle_version:%sle_version} >= 150000 + --with-arch-32=x86-64 \ +%else + --with-arch-32=i586 \ +%endif + --with-tune=generic \ +%endif +%if "%{TARGET_ARCH}" == "x86_64" +%ifnarch %{disable_multilib_arch} + --enable-multilib \ + --with-arch-32=x86-64 \ +%endif + --with-tune=generic \ +%endif +%if "%{TARGET_ARCH}" == "s390" +%if %{suse_version} >= 1310 + --with-tune=zEC12 --with-arch=z196 \ +%else + --with-tune=z9-109 --with-arch=z900 \ +%endif + --with-long-double-128 \ + --enable-decimal-float \ +%endif +%if "%{TARGET_ARCH}" == "s390x" +%if %{suse_version} >= 1310 + --with-tune=zEC12 --with-arch=z196 \ +%else + --with-tune=z9-109 --with-arch=z900 \ +%endif + --with-long-double-128 \ + --enable-decimal-float \ +%endif +%if "%{TARGET_ARCH}" == "m68k" + --disable-multilib \ +%endif +%if "%{TARGET_ARCH}" == "riscv64" + --disable-multilib \ +%endif +%if %{use_lto_bootstrap} && !0%{?building_testsuite:1} + --with-build-config=bootstrap-lto-lean \ +%endif + --enable-link-serialization \ + $CONFARGS \ + --build=%{GCCDIST} \ + --host=%{GCCDIST} || \ + { + rc=$?; + echo "------- BEGIN config.log ------"; + %{__cat} config.log; + echo "------- END config.log ------"; + exit $rc; + } + +STAGE1_FLAGS="-g -O2" +%if 0%{?do_profiling} && !0%{?building_testsuite:1} +%ifarch x86_64 %ix86 ppc64le s390x aarch64 +%define use_pgo_bootstrap 1 +%endif +%endif +%{?use_pgo_bootstrap:setarch `arch` -R} make %{?make_output_sync} %{?use_pgo_bootstrap:profiledbootstrap} STAGE1_CFLAGS="$STAGE1_FLAGS" BOOT_CFLAGS="$RPM_OPT_FLAGS" %{?_smp_mflags} +make info +%if 0%{?run_tests:1} +echo "Run testsuite" +(make -C %{GCCDIST}/libstdc++-v3 check-abi || true) +mv %{GCCDIST}/libstdc++-v3/testsuite/libstdc++.log %{GCCDIST}/libstdc++-v3/testsuite/libstdc++-abi.log +mv %{GCCDIST}/libstdc++-v3/testsuite/libstdc++.sum %{GCCDIST}/libstdc++-v3/testsuite/libstdc++-abi.sum +# asan needs a whole shadow address space +ulimit -v unlimited || true +make -k check %{?_smp_mflags} || true +mkdir ../testresults +../contrib/test_summary | tee ../testresults/test_summary.txt +%endif + +%install +# Make sure libtool re-linking libasan at install time doesn't drop the +# libstdc++ reference to make asan of C++ modules in python work +export SUSE_ASNEEDED=0 +export NO_BRP_CHECK_BYTECODE_VERSION=true +cd obj-%{GCCDIST} +# Work around tail/head -1 changes +export _POSIX2_VERSION=199209 +export LIBRARY_PATH=%{buildroot}/%{libsubdir}:%{buildroot}/%{mainlibdirbi} + +%make_install + +# verify libasan really ended up with libstdc++ as NEEDED. +%ifarch %asan_arch + readelf -d %{buildroot}/%{versmainlibdir}/libasan.so.%{libasan_sover}* | grep 'NEEDED.*libstdc++' || exit 1 +%if %{biarch} + readelf -d %{buildroot}/%{versmainlibdirbi}/libasan.so.%{libasan_sover}* | grep 'NEEDED.*libstdc++' || exit 1 +%endif +%endif + +# Remove some useless .la files +for lib in libobjc libgfortran libquadmath libcaf_single \ + libgomp libgomp-plugin-hsa libstdc++ libsupc++ libgo \ + libasan libhwasan libatomic libitm libtsan liblsan libubsan libvtv \ + libstdc++fs libgomp-plugin-nvptx libgomp-plugin-gcn \ + libgdruntime libgphobos; do + rm -f %{buildroot}/%{versmainlibdir}/$lib.la +%if %{biarch} + rm -f %{buildroot}/%{versmainlibdirbi}/$lib.la +%endif +done + +mkdir -p %{buildroot}/%{_libdir} +%if %{biarch} +%if %{build_primary_64bit} +mkdir -p %{buildroot}/%{_prefix}/lib +%else +mkdir -p %{buildroot}/%{_prefix}/lib64 +%endif +%endif + +%if %{build_cp} +# Merge multilib c++config.h to allow omitting the duplicate and +# identical other arch specific headers +dir_ml= +cxxconfig="`find %{GCCDIST}/libstdc++-v3/include -name c++config.h`" +for i in `find %{GCCDIST}/[36]*/libstdc++-v3/include -name c++config.h 2>/dev/null`; do + if ! diff -up $cxxconfig $i; then + file_32=x + file_64=x + case $i in + %{GCCDIST}/32/*) + file_32=$i + file_64=$cxxconfig + dir_ml=32 + ;; + %{GCCDIST}/64/*) + file_32=$cxxconfig + file_64=$i + dir_ml=64 + ;; + esac + if ! ( test -f "$file_32" && test -f "$file_64" ); then + echo "Urgs?" + exit 1 + fi + + cat > %{buildroot}/%{_prefix}/include/c++/%{gcc_dir_version}/%{GCCDIST}/bits/c++config.h < +#if __WORDSIZE == 32 +`cat $file_32` +#else +`cat $file_64` +#endif +#endif +EOF + break + fi +done +rm -rf %{buildroot}/%{_prefix}/include/c++/%{gcc_dir_version}/%{GCCDIST}/[36]* +if ! test -z "$dir_ml"; then + ln -s . %{buildroot}/%{_prefix}/include/c++/%{gcc_dir_version}/%{GCCDIST}/$dir_ml +fi +%endif + +# move shared libs from versionspecific dir to main libdir +for libname in \ +%if %{build_fortran} + libgfortran \ +%endif +%ifarch %quadmath_arch + libquadmath \ +%endif +%if %{build_objc} + libobjc \ +%endif +%if %{build_cp} + libstdc++ \ +%endif +%if %{build_go} + libgo \ +%endif +%if %{build_d} + libgdruntime \ + libgphobos \ +%endif + libgomp \ +%if %{build_nvptx} + libgomp-plugin-nvptx \ +%endif +%if %{build_gcn} + libgomp-plugin-gcn \ +%endif +%ifarch %atomic_arch + libatomic \ +%endif +%ifarch %itm_arch + libitm \ +%endif +%ifarch %asan_arch + libasan \ +%endif +%ifarch %tsan_arch + libtsan \ +%endif +%ifarch %lsan_arch + liblsan \ +%endif +%ifarch %ubsan_arch + libubsan \ +%endif +%ifarch %hwasan_arch + libhwasan \ +%endif +%ifarch %vtv_arch + libvtv \ +%endif + ; do + for lib in `find %{buildroot}/%{versmainlibdir} -maxdepth 1 -name $libname.so.*`; do + mv $lib %{buildroot}/%{mainlibdir}/ + done + if test -L %{buildroot}/%{versmainlibdir}/$libname.so; then + ln -sf %{mainlibdir}/`readlink %{buildroot}/%{versmainlibdir}/$libname.so | sed -e 's/\(.*\.so\.[^\.]*\).*/\1/'` \ + %{buildroot}/%{versmainlibdir}/$libname.so + fi +%if %{biarch} + if test -d %{buildroot}/%{versmainlibdirbi}; then + for lib in `find %{buildroot}/%{versmainlibdirbi} -maxdepth 1 -name "$libname.so.*"`; do + mv $lib %{buildroot}/%{mainlibdirbi}/ + done + if test -L %{buildroot}/%{versmainlibdirbi}/$libname.so; then + ln -sf %{mainlibdirbi}/`readlink %{buildroot}/%{versmainlibdirbi}/$libname.so | sed -e 's/\(.*\.so\.[^\.]*\).*/\1/'` \ + %{buildroot}/%{versmainlibdirbi}/$libname.so + fi + fi +%endif +done +%if %{build_cp} +# And we want to move the shlib gdb pretty printers to a more sane +# place so ldconfig does not complain +mkdir -p %{buildroot}/%{_datadir}/gdb/auto-load%{mainlibdir} +mv %{buildroot}/%{mainlibdir}/libstdc++.so.*-gdb.py %{buildroot}/%{_datadir}/gdb/auto-load%{mainlibdir}/ +sed -i -e '/^libdir/s/\/gcc\/%{GCCDIST}\/%{gcc_dir_version}//g' %{buildroot}/%{_datadir}/gdb/auto-load%{mainlibdir}/libstdc++.so.*-gdb.py +%if %{biarch} + if test -d %{buildroot}/%{versmainlibdirbi}; then + mkdir -p %{buildroot}/%{_datadir}/gdb/auto-load%{mainlibdirbi} + mv %{buildroot}/%{mainlibdirbi}/libstdc++.so.*-gdb.py %{buildroot}/%{_datadir}/gdb/auto-load%{mainlibdirbi}/ + sed -i -e '/^libdir/s/\/gcc\/%{GCCDIST}\/%{gcc_dir_version}//g' %{buildroot}/%{_datadir}/gdb/auto-load%{mainlibdirbi}/libstdc++.so.*-gdb.py + fi +%endif +%endif + +# Move libgcc_s around +if test -L %{buildroot}/%{_lib}/libgcc_s.so; then + rm -f %{buildroot}/%{_lib}/libgcc_s.so + ln -sf /%{_lib}/libgcc_s.so.%{libgcc_s} %{buildroot}/%{versmainlibdir}/libgcc_s.so +else + mv %{buildroot}/%{_lib}/libgcc_s.so %{buildroot}/%{versmainlibdir}/ +fi +chmod a+x %{buildroot}/%{_lib}/libgcc_s.so.%{libgcc_s} +%if 0%{?usrmerged} +mv %{buildroot}/%{_lib}/libgcc_s.so.%{libgcc_s} %{buildroot}/%{_slibdir}/libgcc_s.so.%{libgcc_s} +%endif +%if %{biarch} +%if %{build_primary_64bit} +if test -L %{buildroot}/lib/libgcc_s.so; then + rm -f %{buildroot}/lib/libgcc_s.so + ln -sf /lib/libgcc_s.so.%{libgcc_s} %{buildroot}/%{versmainlibdirbi32}/libgcc_s.so +else + mv %{buildroot}/lib/libgcc_s.so %{buildroot}/%{versmainlibdirbi32}/ +fi +ln -sf %{versmainlibdirbi32}/libgcc_s.so %{buildroot}/%{versmainlibdirbi32}/libgcc_s_32.so +chmod a+x %{buildroot}/lib/libgcc_s.so.%{libgcc_s} +%if 0%{?usrmerged} +mv %{buildroot}/lib/libgcc_s.so.%{libgcc_s} %{buildroot}/%{slibdir}/libgcc_s.so.%{libgcc_s} +%endif +%else +# 32-bit biarch systems +if test -L %{buildroot}/lib64/libgcc_s.so; then + rm -f %{buildroot}/lib64/libgcc_s.so + ln -sf /lib64/libgcc_s.so.%{libgcc_s} %{buildroot}/%{versmainlibdirbi64}/libgcc_s.so +else + mv %{buildroot}/lib64/libgcc_s.so %{buildroot}/%{versmainlibdirbi64}/ +fi +ln -sf %{versmainlibdirbi64}/libgcc_s.so %{buildroot}/%{versmainlibdirbi64}/libgcc_s_64.so +chmod a+x %{buildroot}/lib64/libgcc_s.so.%{libgcc_s} +%if 0%{?usrmerged} +mv %{buildroot}/lib64/libgcc_s.so.%{libgcc_s} %{buildroot}/%{slibdir64}/libgcc_s.so.%{libgcc_s} +%endif +%endif +%endif + +%if %{build_ada} +mv %{buildroot}/%{libsubdir}/adalib/lib*-*.so %{buildroot}/%{_libdir} +ln -sf %{_libdir}/libgnarl%{binsuffix}.so %{buildroot}/%{libsubdir}/adalib/libgnarl.so +ln -sf %{_libdir}/libgnat%{binsuffix}.so %{buildroot}/%{libsubdir}/adalib/libgnat.so +chmod a+x %{buildroot}/%{_libdir}/libgna*-*.so +%if %{biarch} +mv %{buildroot}/%{versmainlibdirbi}/adalib/lib*-*.so %{buildroot}/%{mainlibdirbi}/ +ln -sf %{mainlibdirbi}/libgnarl%{binsuffix}.so %{buildroot}/%{versmainlibdirbi}/adalib/libgnarl.so +ln -sf %{mainlibdirbi}/libgnat%{binsuffix}.so %{buildroot}/%{versmainlibdirbi}/adalib/libgnat.so +chmod a+x %{buildroot}/%{mainlibdirbi}/libgna*-*.so +%endif +%endif + +rm -f %{buildroot}/%{_prefix}/bin/c++%{binsuffix} + +# Remove some crap from the .la files: +for l in `find %{buildroot} -name '*.la'`; do + echo "changing $l" + sed -e '/^dependency_libs/s| -L%{_builddir}/[^ ]*||g' \ + -e '/^dependency_libs/s| -L/usr/%{GCCDIST}/bin||g' \ + -e '/^dependency_libs/s|-lm \(-lm \)*|-lm |' \ + -e '/^dependency_libs/s|-L[^ ]* ||g' \ +%if %{biarch} +%if %{build_primary_64bit} + -e '/^libdir/s|%{_libdir}/32|%{_prefix}/lib|' \ + -e '/^libdir/s|lib64/\.\./||' \ +%else + -e '/^libdir/s|%{_libdir}/64|%{_prefix}/lib64|' \ +%endif +%endif + < $l > $l.new + mv $l.new $l +done + +# The spec for the PIE subpackage +cat > %{buildroot}/%{libsubdir}/defaults.spec < gcc12-locale.lang + +%post info +%install_info --info-dir=%{_infodir} %{_infodir}/cpp%{binsuffix}.info.gz +%install_info --info-dir=%{_infodir} %{_infodir}/cppinternals%{binsuffix}.info.gz +%install_info --info-dir=%{_infodir} %{_infodir}/gcc%{binsuffix}.info.gz +%install_info --info-dir=%{_infodir} %{_infodir}/gccint%{binsuffix}.info.gz +%install_info --info-dir=%{_infodir} %{_infodir}/gccinstall%{binsuffix}.info.gz +%install_info --info-dir=%{_infodir} %{_infodir}/libgomp%{binsuffix}.info.gz +%ifarch %itm_arch +%install_info --info-dir=%{_infodir} %{_infodir}/libitm%{binsuffix}.info.gz +%endif +%if %{build_fortran} +%install_info --info-dir=%{_infodir} %{_infodir}/gfortran%{binsuffix}.info.gz +%ifarch %quadmath_arch +%install_info --info-dir=%{_infodir} %{_infodir}/libquadmath%{binsuffix}.info.gz +%endif +%endif +%if %{build_ada} +%install_info --info-dir=%{_infodir} %{_infodir}/gnat-style%{binsuffix}.info.gz +%install_info --info-dir=%{_infodir} %{_infodir}/gnat_rm%{binsuffix}.info.gz +%install_info --info-dir=%{_infodir} %{_infodir}/gnat_ugn%{binsuffix}.info.gz +%endif + +%preun info +%install_info_delete --info-dir=%{_infodir} %{_infodir}/cpp%{binsuffix}.info.gz +%install_info_delete --info-dir=%{_infodir} %{_infodir}/cppinternals%{binsuffix}.info.gz +%install_info_delete --info-dir=%{_infodir} %{_infodir}/gcc%{binsuffix}.info.gz +%install_info_delete --info-dir=%{_infodir} %{_infodir}/gccint%{binsuffix}.info.gz +%install_info_delete --info-dir=%{_infodir} %{_infodir}/gccinstall%{binsuffix}.info.gz +%install_info_delete --info-dir=%{_infodir} %{_infodir}/libgomp%{binsuffix}.info.gz +%ifarch %itm_arch +%install_info_delete --info-dir=%{_infodir} %{_infodir}/libitm%{binsuffix}.info.gz +%endif +%if %{build_fortran} +%install_info_delete --info-dir=%{_infodir} %{_infodir}/gfortran%{binsuffix}.info.gz +%ifarch %quadmath_arch +%install_info_delete --info-dir=%{_infodir} %{_infodir}/libquadmath%{binsuffix}.info.gz +%endif +%endif +%if %{build_ada} +%install_info_delete --info-dir=%{_infodir} %{_infodir}/gnat-style%{binsuffix}.info.gz +%install_info_delete --info-dir=%{_infodir} %{_infodir}/gnat_rm%{binsuffix}.info.gz +%install_info_delete --info-dir=%{_infodir} %{_infodir}/gnat_ugn%{binsuffix}.info.gz +%endif + +%files +%defattr(-,root,root) +%dir %{_libdir}/gcc +%dir %{_libdir}/gcc/%{GCCDIST} +%dir %{libsubdir} +%dir %{libsubdir}/include +%dir %{libsubdir}/include-fixed +%if %{biarch} +%if %{build_primary_64bit} +%dir %{libsubdir}/32 +%else +%dir %{libsubdir}/64 +%endif +%endif +%{_prefix}/bin/gcc%{binsuffix} +%{_prefix}/bin/%{GCCDIST}-gcc%{binsuffix} +%{_prefix}/bin/gcov%{binsuffix} +%{_prefix}/bin/gcov-dump%{binsuffix} +%{_prefix}/bin/gcov-tool%{binsuffix} +%{_prefix}/bin/gcc-ar%{binsuffix} +%{_prefix}/bin/gcc-nm%{binsuffix} +%{_prefix}/bin/gcc-ranlib%{binsuffix} +%{_prefix}/bin/lto-dump%{binsuffix} +%{libsubdir}/collect2 +%{libsubdir}/lto1 +%{libsubdir}/lto-wrapper +%{libsubdir}/liblto_plugin.so* +%{libsubdir}/include-fixed/README +%{libsubdir}/include-fixed/limits.h +%{libsubdir}/include-fixed/syslimits.h +%{libsubdir}/include/omp.h +%{libsubdir}/include/float.h +%{libsubdir}/include/iso646.h +%{libsubdir}/include/stdarg.h +%{libsubdir}/include/stdbool.h +%{libsubdir}/include/stdfix.h +%{libsubdir}/include/stddef.h +%{libsubdir}/include/unwind.h +%{libsubdir}/include/varargs.h +%{libsubdir}/include/stdint.h +%{libsubdir}/include/stdint-gcc.h +%{libsubdir}/include/stdnoreturn.h +%{libsubdir}/include/stdalign.h +%{libsubdir}/include/stdatomic.h +%{libsubdir}/include/openacc.h +%{libsubdir}/include/gcov.h +%{libsubdir}/include/acc_prof.h +%ifarch %sparc +%{libsubdir}/include/visintrin.h +%endif +%ifarch ppc ppc64 ppc64le +%{libsubdir}/include/altivec.h +%{libsubdir}/include/ppc-asm.h +%{libsubdir}/include/ppu_intrinsics.h +%{libsubdir}/include/si2vmx.h +%{libsubdir}/include/spu2vmx.h +%{libsubdir}/include/vec_types.h +%{libsubdir}/include/htmintrin.h +%{libsubdir}/include/htmxlintrin.h +%{libsubdir}/include/amo.h +%{libsubdir}/include/bmi2intrin.h +%{libsubdir}/include/bmiintrin.h +%{libsubdir}/include/emmintrin.h +%{libsubdir}/include/mm_malloc.h +%{libsubdir}/include/mmintrin.h +%{libsubdir}/include/x86intrin.h +%{libsubdir}/include/xmmintrin.h +%{libsubdir}/include/pmmintrin.h +%{libsubdir}/include/tmmintrin.h +%{libsubdir}/include/smmintrin.h +%{libsubdir}/include/rs6000-vecdefines.h +%{libsubdir}/include/immintrin.h +%{libsubdir}/include/nmmintrin.h +%{libsubdir}/include/x86gprintrin.h +%endif +%ifarch s390 s390x +%{libsubdir}/include/htmintrin.h +%{libsubdir}/include/htmxlintrin.h +%{libsubdir}/include/s390intrin.h +%{libsubdir}/include/vecintrin.h +%endif +%ifarch ia64 +%{libsubdir}/include/ia64intrin.h +%endif +%ifarch %arm +%{libsubdir}/include/mmintrin.h +%{libsubdir}/include/unwind-arm-common.h +%{libsubdir}/include/arm_cmse.h +%{libsubdir}/include/arm_mve.h +%{libsubdir}/include/arm_mve_types.h +%{libsubdir}/include/arm_cde.h +%endif +%ifarch %arm aarch64 +%{libsubdir}/include/arm_neon.h +%{libsubdir}/include/arm_acle.h +%{libsubdir}/include/arm_fp16.h +%{libsubdir}/include/arm_bf16.h +%endif +%ifarch aarch64 +%{libsubdir}/include/arm_sve.h +%endif +%ifarch %ix86 x86_64 +%{libsubdir}/include/cross-stdarg.h +%{libsubdir}/include/cpuid.h +%{libsubdir}/include/mm3dnow.h +%{libsubdir}/include/mmintrin.h +%{libsubdir}/include/ammintrin.h +%{libsubdir}/include/bmmintrin.h +%{libsubdir}/include/emmintrin.h +%{libsubdir}/include/immintrin.h +%{libsubdir}/include/avxintrin.h +%{libsubdir}/include/pmmintrin.h +%{libsubdir}/include/xmmintrin.h +%{libsubdir}/include/tmmintrin.h +%{libsubdir}/include/nmmintrin.h +%{libsubdir}/include/smmintrin.h +%{libsubdir}/include/wmmintrin.h +%{libsubdir}/include/x86intrin.h +%{libsubdir}/include/ia32intrin.h +%{libsubdir}/include/mm_malloc.h +%{libsubdir}/include/fma4intrin.h +%{libsubdir}/include/xopintrin.h +%{libsubdir}/include/lwpintrin.h +%{libsubdir}/include/popcntintrin.h +%{libsubdir}/include/bmiintrin.h +%{libsubdir}/include/tbmintrin.h +%{libsubdir}/include/avx2intrin.h +%{libsubdir}/include/bmi2intrin.h +%{libsubdir}/include/fmaintrin.h +%{libsubdir}/include/lzcntintrin.h +%{libsubdir}/include/f16cintrin.h +%{libsubdir}/include/adxintrin.h +%{libsubdir}/include/fxsrintrin.h +%{libsubdir}/include/prfchwintrin.h +%{libsubdir}/include/rdseedintrin.h +%{libsubdir}/include/rtmintrin.h +%{libsubdir}/include/xsaveintrin.h +%{libsubdir}/include/xsaveoptintrin.h +%{libsubdir}/include/xtestintrin.h +%{libsubdir}/include/avx512cdintrin.h +%{libsubdir}/include/avx512erintrin.h +%{libsubdir}/include/avx512fintrin.h +%{libsubdir}/include/avx512pfintrin.h +%{libsubdir}/include/shaintrin.h +%{libsubdir}/include/avx512bwintrin.h +%{libsubdir}/include/avx512dqintrin.h +%{libsubdir}/include/avx512vlbwintrin.h +%{libsubdir}/include/avx512vldqintrin.h +%{libsubdir}/include/avx512vlintrin.h +%{libsubdir}/include/avx512ifmaintrin.h +%{libsubdir}/include/avx512ifmavlintrin.h +%{libsubdir}/include/avx512vbmiintrin.h +%{libsubdir}/include/avx512vbmivlintrin.h +%{libsubdir}/include/avx5124fmapsintrin.h +%{libsubdir}/include/avx5124vnniwintrin.h +%{libsubdir}/include/avx512vpopcntdqintrin.h +%{libsubdir}/include/avx512vbmi2intrin.h +%{libsubdir}/include/avx512vbmi2vlintrin.h +%{libsubdir}/include/avx512vnniintrin.h +%{libsubdir}/include/avx512vnnivlintrin.h +%{libsubdir}/include/avx512bitalgintrin.h +%{libsubdir}/include/avx512vpopcntdqvlintrin.h +%{libsubdir}/include/avx512bf16intrin.h +%{libsubdir}/include/avx512bf16vlintrin.h +%{libsubdir}/include/avx512vp2intersectintrin.h +%{libsubdir}/include/avx512vp2intersectvlintrin.h +%{libsubdir}/include/vpclmulqdqintrin.h +%{libsubdir}/include/enqcmdintrin.h +%{libsubdir}/include/cet.h +%{libsubdir}/include/vaesintrin.h +%{libsubdir}/include/clwbintrin.h +%{libsubdir}/include/clflushoptintrin.h +%{libsubdir}/include/xsavecintrin.h +%{libsubdir}/include/xsavesintrin.h +%{libsubdir}/include/mwaitxintrin.h +%{libsubdir}/include/clzerointrin.h +%{libsubdir}/include/pkuintrin.h +%{libsubdir}/include/sgxintrin.h +%{libsubdir}/include/cetintrin.h +%{libsubdir}/include/gfniintrin.h +%{libsubdir}/include/pconfigintrin.h +%{libsubdir}/include/wbnoinvdintrin.h +%{libsubdir}/include/movdirintrin.h +%{libsubdir}/include/cldemoteintrin.h +%{libsubdir}/include/waitpkgintrin.h +%{libsubdir}/include/serializeintrin.h +%{libsubdir}/include/tsxldtrkintrin.h +%{libsubdir}/include/amxbf16intrin.h +%{libsubdir}/include/amxint8intrin.h +%{libsubdir}/include/amxtileintrin.h +%{libsubdir}/include/x86gprintrin.h +%{libsubdir}/include/hresetintrin.h +%{libsubdir}/include/uintrintrin.h +%{libsubdir}/include/keylockerintrin.h +%{libsubdir}/include/avxvnniintrin.h +%{libsubdir}/include/mwaitintrin.h +%{libsubdir}/include/avx512fp16intrin.h +%{libsubdir}/include/avx512fp16vlintrin.h +%endif +%ifarch m68k +%{libsubdir}/include/math-68881.h +%endif +%ifarch %asan_arch +%{libsubdir}/include/sanitizer +%endif +%if %{build_fortran} +%{libsubdir}/include/ISO_Fortran_binding.h +%endif +%versmainlib *crt*.o +%versmainlib libgcc*.a +%versmainlib libgcov.a +%versmainlib libgcc_s*.so +%versmainlib libgomp.so +%versmainlib libgomp.a +%versmainlib libgomp.spec +%if %{build_nvptx} +%versmainlib libgomp-plugin-nvptx.so +%endif +%if %{build_gcn} +%versmainlib libgomp-plugin-gcn.so +%endif +%ifarch %itm_arch +%versmainlib libitm.so +%versmainlib libitm.a +%versmainlib libitm.spec +%endif +%ifarch %atomic_arch +%versmainlib libatomic.so +%versmainlib libatomic.a +%endif +%ifarch %asan_arch +%versmainlib libasan.so +%versmainlib libasan.a +%versmainlib libasan_preinit.o +%endif +%ifarch %tsan_arch +%if %build_primary_64bit +%versmainlib libtsan.so +%versmainlib libtsan.a +%versmainlib libtsan_preinit.o +%endif +%endif +%ifarch %lsan_arch +%if %build_primary_64bit +%versmainlib liblsan.so +%versmainlib liblsan.a +%versmainlib liblsan_preinit.o +%endif +%endif +%ifarch %ubsan_arch +%versmainlib libubsan.so +%versmainlib libubsan.a +%endif +%ifarch %hwasan_arch +%versmainlib libhwasan.so +%versmainlib libhwasan.a +%endif +%ifarch %asan_arch %ubsan_arch %tsan_arch %lsan_arch %hwasan_arch +%versmainlib libsanitizer.spec +%endif +%ifarch %vtv_arch +%versmainlib libvtv.so +%versmainlib libvtv.a +%endif +%doc %{_mandir}/man1/gcc%{binsuffix}.1.gz +%doc %{_mandir}/man1/gcov%{binsuffix}.1.gz +%doc %{_mandir}/man1/gcov-dump%{binsuffix}.1.gz +%doc %{_mandir}/man1/gcov-tool%{binsuffix}.1.gz +%doc %{_mandir}/man1/lto-dump%{binsuffix}.1.gz + +%if %{separate_biarch} +%files -n gcc12%{separate_biarch_suffix} +%defattr(-,root,root) +%versbiarchlib *crt*.o +%versbiarchlib libgcc*.a +%versbiarchlib libgcov.a +%versbiarchlib libgcc_s*.so +%versbiarchlib libgomp.so +%versbiarchlib libgomp.a +%versbiarchlib libgomp.spec +# No 32-bit plugins for nvptx and gcn +%ifarch %itm_arch +%versbiarchlib libitm.so +%versbiarchlib libitm.a +%versbiarchlib libitm.spec +%endif +%ifarch %atomic_arch +%versbiarchlib libatomic.a +%versbiarchlib libatomic.so +%endif +%ifarch %asan_arch +%versbiarchlib libasan.a +%versbiarchlib libasan.so +%versbiarchlib libasan_preinit.o +%endif +%ifarch %ubsan_arch +%versbiarchlib libubsan.a +%versbiarchlib libubsan.so +%endif +%ifarch %tsan_arch +%if %separate_bi64 +%versbiarchlib libtsan.a +%versbiarchlib libtsan.so +%versbiarchlib libtsan_preinit.o +%endif +%endif +%ifarch %lsan_arch +%if %separate_bi64 +%versbiarchlib liblsan.a +%versbiarchlib liblsan.so +%versbiarchlib liblsan_preinit.o +%endif +%endif +%ifarch %hwasan_arch +%versbiarchlib libhwasan.a +%versbiarchlib libhwasan.so +%endif +%ifarch %asan_arch %ubsan_arch %tsan_arch %lsan_arch %hwasan_arch +%versbiarchlib libsanitizer.spec +%endif +%ifarch %vtv_arch +%versbiarchlib libvtv.a +%versbiarchlib libvtv.so +%endif +%endif + +%if %{enable_plugins} +%files devel +%defattr(-,root,root) +%dir %{libsubdir}/plugin +%{libsubdir}/plugin +%endif + +%files locale -f gcc12-locale.lang + +%files -n libstdc++%{libstdcxx_sover}%{libstdcxx_suffix}-locale -f libstdc++.lang + +%files PIE +%defattr(-,root,root) +%dir %{libsubdir} +%{libsubdir}/defaults.spec + +%if %{build_cp} +%files c++ +%defattr(-,root,root) +%dir %{_libdir}/gcc +%dir %{_libdir}/gcc/%{GCCDIST} +%dir %{libsubdir} +%{_prefix}/bin/g++%{binsuffix} +%doc %{_mandir}/man1/g++%{binsuffix}.1.gz +%{libsubdir}/cc1plus +%{libsubdir}/g++-mapper-server + +%if %{separate_biarch} +%files c++%{separate_biarch_suffix} +%defattr(-,root,root) +# empty - only for the dependency +%if %{suse_version} < 1310 +%doc README +%endif +%endif + +%files -n libstdc++%{libstdcxx_sover}%{libstdcxx_suffix} +%defattr(-,root,root) +%mainlib libstdc++.so.%{libstdcxx_sover}* + +%if %{separate_biarch} +%files -n libstdc++%{libstdcxx_sover}%{libstdcxx_suffix}%{separate_biarch_suffix} +%defattr(-,root,root) +%biarchlib libstdc++.so.%{libstdcxx_sover}* +%endif + +%files -n libstdc++%{libstdcxx_sover}-devel%{libdevel_suffix} +%defattr(-,root,root) +%versmainlib libstdc++.a +%versmainlib libstdc++fs.a +%versmainlib libstdc++.so +%versmainlib libsupc++.a +%{_prefix}/include/c++ + +%files -n libstdc++%{libstdcxx_sover}-pp%{libstdcxx_suffix} +%defattr(-,root,root) +%dir %{_datadir}/gdb +%dir %{_datadir}/gdb/auto-load +%dir %{_datadir}/gdb/auto-load%{_prefix} +%dir %{_datadir}/gdb/auto-load/%{mainlibdir} +%{_datadir}/gdb/auto-load/%{mainlibdir}/libstdc++.so.*-gdb.py +%{_datadir}/gcc%{binsuffix} + +%if %{separate_biarch} +%files -n libstdc++%{libstdcxx_sover}-devel%{libdevel_suffix}%{separate_biarch_suffix} +%defattr(-,root,root) +%versbiarchlib libstdc++.a +%versbiarchlib libstdc++fs.a +%versbiarchlib libstdc++.so +%versbiarchlib libsupc++.a + +%files -n libstdc++%{libstdcxx_sover}-pp%{libstdcxx_suffix}%{separate_biarch_suffix} +%defattr(-,root,root) +%dir %{_datadir}/gdb/auto-load/%{mainlibdirbi} +%{_datadir}/gdb/auto-load/%{mainlibdirbi}/libstdc++.so.*-gdb.py +%endif +%endif + +%files -n libgcc_s%{libgcc_s}%{libgcc_s_suffix} +%defattr(-,root,root) +%{_slibdir}/libgcc_s.so.%{libgcc_s} +%if %{biarch} +%if %{build_primary_64bit} +%if !%{separate_bi32} +%{slibdir}/libgcc_s.so.%{libgcc_s} +%endif +%else +%if !%{separate_bi64} +%{slibdir64}/libgcc_s.so.%{libgcc_s} +%endif +%endif +%endif + +%if %{separate_bi64} +%files -n libgcc_s%{libgcc_s}%{libgcc_s_suffix}-64bit +%defattr(-,root,root) +%{slibdir64}/libgcc_s.so.%{libgcc_s} +%endif + +%if %{separate_bi32} +%files -n libgcc_s%{libgcc_s}%{libgcc_s_suffix}-32bit +%defattr(-,root,root) +%{slibdir}/libgcc_s.so.%{libgcc_s} +%endif + +%files -n libgomp%{libgomp_sover}%{libgomp_suffix} +%defattr(-,root,root) +%mainlib libgomp.so.%{libgomp_sover}* +%if %{build_nvptx} +%mainlib libgomp-plugin-nvptx.so.%{libgomp_sover}* +%endif +%if %{build_gcn} +%mainlib libgomp-plugin-gcn.so.%{libgomp_sover}* +%endif + +%if %{separate_biarch} +%files -n libgomp%{libgomp_sover}%{libgomp_suffix}%{separate_biarch_suffix} +%defattr(-,root,root) +%biarchlib libgomp.so.%{libgomp_sover}* +%endif +# No 32-bit plugins for nvptx and gcn + +%ifarch %asan_arch +%files -n libasan%{libasan_sover}%{libasan_suffix} +%defattr(-,root,root) +%mainlib libasan.so.%{libasan_sover}* + +%if %{separate_biarch} +%files -n libasan%{libasan_sover}%{libasan_suffix}%{separate_biarch_suffix} +%defattr(-,root,root) +%biarchlib libasan.so.%{libasan_sover}* +%endif +%endif + +%ifarch %lsan_arch +%if %build_primary_64bit +%files -n liblsan%{liblsan_sover}%{liblsan_suffix} +%defattr(-,root,root) +%mainlib liblsan.so.%{liblsan_sover}* +%endif + +%if %{separate_biarch} && %{separate_bi64} +%files -n liblsan%{liblsan_sover}%{liblsan_suffix}%{separate_biarch_suffix} +%defattr(-,root,root) +%biarchlib liblsan.so.%{liblsan_sover}* +%endif +%endif + +%ifarch %tsan_arch +%if %build_primary_64bit +%files -n libtsan%{libtsan_sover}%{libtsan_suffix} +%defattr(-,root,root) +%mainlib libtsan.so.%{libtsan_sover}* +%endif + +%if %{separate_biarch} && %{separate_bi64} +%files -n libtsan%{libtsan_sover}%{libtsan_suffix}%{separate_biarch_suffix} +%defattr(-,root,root) +%biarchlib libtsan.so.%{libtsan_sover}* +%endif +%endif + +%ifarch %hwasan_arch +%files -n libhwasan%{libhwasan_sover}%{libhwasan_suffix} +%defattr(-,root,root) +%mainlib libhwasan.so.%{libhwasan_sover}* + +%if %{separate_biarch} +%files -n libhwasan%{libhwasan_sover}%{libhwasan_suffix}%{separate_biarch_suffix} +%defattr(-,root,root) +%biarchlib libhwasan.so.%{libhwasan_sover}* +%endif +%endif + +%ifarch %atomic_arch +%files -n libatomic%{libatomic_sover}%{libatomic_suffix} +%defattr(-,root,root) +%mainlib libatomic.so.%{libatomic_sover}* + +%if %{separate_biarch} +%files -n libatomic%{libatomic_sover}%{libatomic_suffix}%{separate_biarch_suffix} +%defattr(-,root,root) +%biarchlib libatomic.so.%{libatomic_sover}* +%endif +%endif + +%ifarch %itm_arch +%files -n libitm%{libitm_sover}%{libitm_suffix} +%defattr(-,root,root) +%mainlib libitm.so.%{libitm_sover}* + +%if %{separate_biarch} +%files -n libitm%{libitm_sover}%{libitm_suffix}%{separate_biarch_suffix} +%defattr(-,root,root) +%biarchlib libitm.so.%{libitm_sover}* +%endif +%endif + +%ifarch %ubsan_arch +%files -n libubsan%{libubsan_sover}%{libubsan_suffix} +%defattr(-,root,root) +%mainlib libubsan.so.%{libubsan_sover}* + +%if %{separate_biarch} +%files -n libubsan%{libubsan_sover}%{libubsan_suffix}%{separate_biarch_suffix} +%defattr(-,root,root) +%biarchlib libubsan.so.%{libubsan_sover}* +%endif +%endif + +%ifarch %vtv_arch +%files -n libvtv%{libvtv_sover}%{libvtv_suffix} +%defattr(-,root,root) +%mainlib libvtv.so.%{libvtv_sover}* + +%if %{separate_biarch} +%files -n libvtv%{libvtv_sover}%{libvtv_suffix}%{separate_biarch_suffix} +%defattr(-,root,root) +%biarchlib libvtv.so.%{libvtv_sover}* +%endif + +%endif + +%if %{build_fortran} +%files fortran +%defattr(-,root,root) +%dir %{libsubdir}/finclude +%{_prefix}/bin/gfortran%{binsuffix} +%{libsubdir}/f951 +%{libsubdir}/finclude/* +%versmainlib libgfortran.a +%versmainlib libgfortran.so +%versmainlib libgfortran.spec +%versmainlib libcaf_single.a +%ifarch %quadmath_arch +%{libsubdir}/include/quadmath.h +%{libsubdir}/include/quadmath_weak.h +%versmainlib libquadmath.a +%versmainlib libquadmath.so +%endif +%doc %{_mandir}/man1/gfortran%{binsuffix}.1.gz + +%if %{separate_biarch} +%files fortran%{separate_biarch_suffix} +%defattr(-,root,root) +%dir %{versmainlibdirbi}/finclude +%{versmainlibdirbi}/finclude/* +%versbiarchlib libgfortran.a +%versbiarchlib libgfortran.so +%versbiarchlib libgfortran.spec +%versbiarchlib libcaf_single.a +%ifarch %quadmath_arch +%versbiarchlib libquadmath.a +%versbiarchlib libquadmath.so +%endif +%endif + +%files -n libgfortran%{libgfortran_sover}%{libgfortran_suffix} +%defattr(-,root,root) +%mainlib libgfortran.so.%{libgfortran_sover}* + +%if %{separate_biarch} +%files -n libgfortran%{libgfortran_sover}%{libgfortran_suffix}%{separate_biarch_suffix} +%defattr(-,root,root) +%biarchlib libgfortran.so.%{libgfortran_sover}* +%endif + +%ifarch %quadmath_arch +%files -n libquadmath%{libquadmath_sover}%{libquadmath_suffix} +%defattr(-,root,root) +%mainlib libquadmath.so.%{libquadmath_sover}* + +%if %{separate_biarch} +%files -n libquadmath%{libquadmath_sover}%{libquadmath_suffix}%{separate_biarch_suffix} +%defattr(-,root,root) +%biarchlib libquadmath.so.%{libquadmath_sover}* +%endif +%endif +%endif + +%files info +%defattr(-,root,root) +%doc %{_infodir}/cpp%{binsuffix}.info*.gz +%doc %{_infodir}/cppinternals%{binsuffix}.info*.gz +%doc %{_infodir}/gcc%{binsuffix}.info*.gz +%doc %{_infodir}/gccint%{binsuffix}.info*.gz +%doc %{_infodir}/gccinstall%{binsuffix}.info*.gz +%doc %{_infodir}/libgomp%{binsuffix}.info*.gz +%ifarch %itm_arch +%doc %{_infodir}/libitm%{binsuffix}.info*.gz +%endif +%if %{build_fortran} +%doc %{_infodir}/gfortran%{binsuffix}.info*.gz +%ifarch %quadmath_arch +%doc %{_infodir}/libquadmath%{binsuffix}.info*.gz +%endif +%endif +%if %{build_ada} +%doc %{_infodir}/gnat-style%{binsuffix}.info*gz +%doc %{_infodir}/gnat_rm%{binsuffix}.info*gz +%doc %{_infodir}/gnat_ugn%{binsuffix}.info*gz +%endif +%if %{build_d} +%doc %{_infodir}/gdc%{binsuffix}.info*gz +%endif + +%files -n cpp12 +%defattr(-,root,root) +%dir %{_libdir}/gcc +%dir %{_libdir}/gcc/%{GCCDIST} +%dir %{libsubdir} +%{_prefix}/bin/cpp%{binsuffix} +%{libsubdir}/cc1 +%doc %{_mandir}/man1/cpp%{binsuffix}.1.gz + +%if %{build_objc} +%files objc +%defattr(-,root,root) +%{libsubdir}/cc1obj +%{libsubdir}/include/objc +%versmainlib libobjc.a +%versmainlib libobjc.so + +%if %{separate_biarch} +%files objc%{separate_biarch_suffix} +%defattr(-,root,root) +%versbiarchlib libobjc.a +%versbiarchlib libobjc.so +%endif + +%files -n libobjc%{libobjc_sover}%{libobjc_suffix} +%defattr(-,root,root) +%mainlib libobjc.so.%{libobjc_sover}* + +%if %{separate_biarch} +%files -n libobjc%{libobjc_sover}%{libobjc_suffix}%{separate_biarch_suffix} +%defattr(-,root,root) +%biarchlib libobjc.so.%{libobjc_sover}* +%endif +%endif + +%if %{build_objcp} +%files obj-c++ +%defattr(-,root,root) +%{libsubdir}/cc1objplus + +%if %{separate_biarch} +%files obj-c++%{separate_biarch_suffix} +%defattr(-,root,root) +# empty - only for the dependency +%if %{suse_version} < 1310 +%doc README +%endif +%endif +%endif + +%if %{build_ada} +%files ada +%defattr(-,root,root) +%dir %{_libdir}/gcc +%dir %{_libdir}/gcc/%{GCCDIST} +%dir %{libsubdir} +%{_prefix}/bin/gnat* +%dir %{versmainlibdir}/adalib +%{versmainlibdir}/adainclude +%{versmainlibdir}/adalib/*.ali +%{versmainlibdir}/adalib/*.a +%{versmainlibdir}/adalib/libgnarl.so +%{versmainlibdir}/adalib/libgnat.so +%{versmainlibdir}/gnat1 +%{versmainlibdir}/ada_target_properties + +%if %{separate_biarch} +%files ada%{separate_biarch_suffix} +%defattr(-,root,root) +%dir %{versmainlibdirbi}/adalib +%{versmainlibdirbi}/adainclude +%{versmainlibdirbi}/adalib/*.ali +%{versmainlibdirbi}/adalib/*.a +%{versmainlibdirbi}/adalib/libgnarl.so +%{versmainlibdirbi}/adalib/libgnat.so +%{versmainlibdirbi}/ada_target_properties +%endif + +%files -n libada12 +%defattr(-,root,root) +%mainlib libgnarl%{binsuffix}.so +%mainlib libgnat%{binsuffix}.so + +%if %{separate_biarch} +%files -n libada12%{separate_biarch_suffix} +%defattr(-,root,root) +%biarchlib libgnarl%{binsuffix}.so +%biarchlib libgnat%{binsuffix}.so +%endif +%endif + +%if %{build_go} +%files go +%defattr(-,root,root) +%{_prefix}/bin/gccgo%{binsuffix} +%{_prefix}/bin/go%{binsuffix} +%{_prefix}/bin/gofmt%{binsuffix} +%{libsubdir}/go1 +%versmainlib libgo.a +%versmainlib libgo.so +%versmainlib libgobegin.a +%versmainlib libgolibbegin.a +%versmainlibdir/buildid +%versmainlibdir/cgo +%dir %mainlibdir/go +%dir %mainlibdir/go/%{gcc_dir_version} +%mainlibdir/go/%{gcc_dir_version}/%{GCCDIST} +%doc %{_mandir}/man1/gccgo%{binsuffix}.1.gz +%doc %{_mandir}/man1/go%{binsuffix}.1.gz +%doc %{_mandir}/man1/gofmt%{binsuffix}.1.gz + +%if %{separate_biarch} +%files go%{separate_biarch_suffix} +%defattr(-,root,root) +%versbiarchlib libgo.a +%versbiarchlib libgo.so +%versbiarchlib libgobegin.a +%versbiarchlib libgolibbegin.a +%dir %mainlibdirbi/go +%dir %mainlibdirbi/go/%{gcc_dir_version} +%mainlibdirbi/go/%{gcc_dir_version}/%{GCCDIST} +%endif + +%files -n libgo%{libgo_sover}%{libgo_suffix} +%defattr(-,root,root) +%mainlib libgo.so.%{libgo_sover}* + +%if %{separate_biarch} +%files -n libgo%{libgo_sover}%{libgo_suffix}%{separate_biarch_suffix} +%defattr(-,root,root) +%biarchlib libgo.so.%{libgo_sover}* +%endif +%endif + +%if %{build_d} +%files d +%defattr(-,root,root) +%{_prefix}/bin/gdc%{binsuffix} +%{libsubdir}/d21 +%versmainlib libgphobos.a +%versmainlib libgphobos.so +%versmainlib libgdruntime.a +%versmainlib libgdruntime.so +%versmainlib libgphobos.spec +%{versmainlibdir}/include/d +%doc %{_mandir}/man1/gdc%{binsuffix}.1.gz + +%if %{separate_biarch} +%files d%{separate_biarch_suffix} +%defattr(-,root,root) +%versbiarchlib libgphobos.a +%versbiarchlib libgphobos.so +%versbiarchlib libgdruntime.a +%versbiarchlib libgdruntime.so +%versbiarchlib libgphobos.spec +%endif + +%files -n libgphobos%{libgphobos_sover}%{libgphobos_suffix} +%defattr(-,root,root) +%mainlib libgphobos.so.%{libgphobos_sover}* + +%if %{separate_biarch} +%files -n libgphobos%{libgphobos_sover}%{libgphobos_suffix}%{separate_biarch_suffix} +%defattr(-,root,root) +%biarchlib libgphobos.so.%{libgphobos_sover}* +%endif + +%files -n libgdruntime%{libgdruntime_sover}%{libgdruntime_suffix} +%defattr(-,root,root) +%mainlib libgdruntime.so.%{libgdruntime_sover}* + +%if %{separate_biarch} +%files -n libgdruntime%{libgdruntime_sover}%{libgdruntime_suffix}%{separate_biarch_suffix} +%defattr(-,root,root) +%biarchlib libgdruntime.so.%{libgdruntime_sover}* +%endif +%endif + +%if %{build_jit} +%files -n libgccjit%{libgccjit_sover}%{libgccjit_suffix} +%defattr(-,root,root) +%{_prefix}/%{_lib}/libgccjit.so.%{libgccjit_sover}* + +%files -n libgccjit%{libgccjit_sover}-devel%{libdevel_suffix} +%defattr(-,root,root) +%doc gcc/jit/docs/examples +%{_prefix}/%{_lib}/libgccjit.so +%{_prefix}/include/libgccjit.h +%{_prefix}/include/libgccjit++.h +%{_infodir}/libgccjit.info.gz +%endif + +%if 0%{?run_tests:1} +%files -n gcc12-testresults +%defattr(-,root,root) +%doc testresults/test_summary.txt +%doc testresults/*.sum +%doc testresults/*.log +%endif + +%changelog +* Thu Aug 17 2023 rguenther@suse.com +- Add gcc12-aarch64-bsc1214052.patch to fix -fstack-protector issues + with variable length stack allocations on aarch64. + Fixes CVE-2023-4039. [bsc#1214052] +* Mon May 8 2023 rguenther@suse.com +- Update to GCC 12.3 release, 0c61aa720e62f1baf0bfd178e283, git1204 + * includes regression bug fixes +- Add gcc12-testsuite-fixes.patch to pick testsuite related fixes + from the branch after the release. +* Wed Mar 29 2023 mliska@suse.cz +- Speed up builds with --enable-link-serialization. +* Tue Jan 24 2023 rguenther@suse.com +- Update to gcc-12 branch head, 193f7e62815b4089dfaed4c2bd3, git749 +* Tue Dec 27 2022 lnussel@suse.com +- Don't rely on %%usrmerged, set it based on standard %%suse_version +* Thu Dec 22 2022 rguenther@suse.com +- Update to gcc-12 branch head, e4b5fec75aa8d0d01f6e042ec28, git696 + * remove gcc12-fifo-jobserver-support.patch which is now + included upstream +* Wed Nov 23 2022 dmueller@suse.com +- avoid trailing backslashes at the end of post install scripts +* Thu Oct 20 2022 rguenther@suse.com +- Update to gcc-12 branch head, 0aaef83351473e8f4eb774f8f99, git537 +* Thu Oct 13 2022 rguenther@suse.com +- Update embedded newlib to version 4.2.0 + * includes newlib-4.1.0-aligned_alloc.patch +* Mon Sep 26 2022 dmueller@suse.com +- add gcc12-riscv-inline-atomics.patch, + gcc12-riscv-pthread.patch: handle subword size inline atomics + (needed by several openSUSE packages) +* Wed Aug 31 2022 rguenther@suse.com +- Prune invalid-license rpmlint warnings, the SLE12 codestream + doesn't get fixed but FF applies there, too. [bsc#1185337] +* Tue Aug 30 2022 rguenther@suse.com +- Update to gcc-12 branch head, e927d1cf141f221c5a32574bde0, git416 + * includes GCC 12.2 release + * includes recent fixes backported from trunk +* Mon Aug 29 2022 mliska@suse.cz +- Add gcc12-fifo-jobserver-support.patch that adds support + for FIFO jobserver for make. +* Sun Aug 21 2022 matwey.kornilov@gmail.com +- Allow cross-pru-gcc12-bootstrap for armv7l architecture. + PRU architecture is used for real-time MCUs embedded into TI + armv7l and aarch64 SoCs. We need to have cross-pru-gcc12 for + armv7l in order to build both host applications and PRU firmware + during the same build. +* Fri Aug 12 2022 rguenther@suse.com +- Update to gcc-12 branch head, 6b7d570a5001bb79e34c0d1626a, git372 + * includes release candidate for GCC 12.2 +* Mon Aug 8 2022 mliska@suse.cz +- Remove workaround for obs-service-format_spec_file. +* Tue Jul 26 2022 rguenther@suse.com +- Add Provides of libstdc++6-pp-gccN to libstdc++6-pp. [bsc#1201848] +* Thu Jul 21 2022 rguenther@suse.com +- Update to gcc-12 branch head, 4f15d2234608e82159d030dadb1, git287 + * includes build fixes when building against glibc 2.33. +* Wed Jun 29 2022 rguenther@suse.com +- Update to gcc-12 branch head, 7811663964aa7e31c3939b859bb, git215 + * includes libgomp mold linker detection fix + * includes nvptx offload compiler build fix + * includes s390x tsan executable stack fix +* Tue May 17 2022 rguenther@suse.com +- Update to gcc-12 branch head, 325d82b08696da17fb26bd2e1b6b, git78 +* Tue May 10 2022 matwey.kornilov@gmail.com +- Enable PRU architecture for AM335x platforms +* Fri May 6 2022 rguenther@suse.com +- Update to GCC 12.1 release, 1ea978e3066ac565a1ec28a96a4d61, git27 +* Fri Apr 29 2022 rguenther@suse.com +- Bump to 621650f64fb6679c457c33abf27c925f28bddc62, git9 + * GCC 12.1 release candidate +* Thu Apr 28 2022 rguenther@suse.com +- Bump to f27848a5dc4d3b16cd4112bddcb59e0916eba623, git192706. +- Switch ppc64le to the IEEE long double ABI by default in Factory. +- Separate ppc64le from ppc/ppc64 specific configury. +- Add _multibuild to gather all .spec files and reduce the number + of .changes files to one, autogenerated by change_spec. +- Drop %%ringdisabled handling. +- Ada bootstrap now requires at least GCC 5, use GCC 7 on SLES 12 + instead of GCC 4.8. +* Wed Apr 27 2022 rguenther@suse.com +- Drop no longer necessary gcc12-d-workaround.patch +* Tue Apr 19 2022 mliska@suse.cz +- Bump to b85abacd902813daec5e44b97f275eb88caaf715, git192607. +* Wed Apr 6 2022 schwab@suse.de +- On SLE15 and later, use make -Oline to synchronize configure output by + lines +* Wed Apr 6 2022 mliska@suse.cz +- Bump to 86242eb1bd03eba82d8e22b01b16925d43bcc539, git192423. + Fixes aarch64 bootstrap issue (PR105144). +* Fri Apr 1 2022 rguenther@suse.com +- Add provides/conflicts to glibc crosses since only one GCC version + for the same target can be installed at the same time. +- Add provides/conflicts to libgccjit +* Mon Mar 28 2022 mliska@suse.cz +- Bump to 9f37d31324f89d0b7b2abac988a976d121ae29c6, git192251. +* Wed Mar 23 2022 mliska@suse.cz +- Bump to e8cd3edc0fc6c02a732dcecf519c22d835e5f422, git192197. +* Thu Mar 17 2022 mliska@suse.cz +- Bump to c43cb355f25dd22133d15819bd6ec03d3d3939fd, git192094. +* Tue Mar 15 2022 matz@suse.com +- Add a proper barebones cross compiler for hppa + (named cross-hppa-gcc12-bootstrap). Doesn't yet drop or + rename the icecream variant cross-hppa-gcc12, not does this + add a proper glibc-using cross compiler for hppa. +* Mon Mar 7 2022 dmueller@suse.com +- drop armv5tel, merge arm and armv6hl +- use --with-cpu rather than specifying --with-arch/--with-tune +* Mon Mar 7 2022 mliska@suse.cz +- Bump to 40c1d4a07e5798c01e4364336c9617550744861d, git191925. +* Wed Mar 2 2022 rguenther@suse.com +- Drop unconditional -gccN suffix from libstdc++6-pp packages and + instead use the same suffix as for the matching libstdc++6 + package it supplements to ease future updates. Add Obsoletes + to pre-existing libstdc++6-pp-gcc{9,10,11} packages to allow + updates to happen. [bsc#1196107] +* Tue Mar 1 2022 mliska@suse.cz +- Use proper patch for SLE 15.x. +* Tue Mar 1 2022 mliska@suse.cz +- Bump to 4a1c20df82c9e14478d79fbe1ae9690a36285ac1, git191847. +* Tue Mar 1 2022 mliska@suse.cz +- Add gcc12-d-workaround.patch that fixes issue with gcc11 compiler. +* Tue Mar 1 2022 mliska@suse.cz +- Bump to 673a10aee1aafe0c99bfadc29a7458339bdddb3a, git191845. +* Mon Feb 28 2022 mliska@suse.cz +- Bump to 37b583b9d7719f663656ce65ac822c11471fb540, git191817. +- Bump sover of libgo library. +* Fri Feb 11 2022 rguenther@suse.com +- Update to trunk head, 165947fecf4d78c7effb0f1ee15e694 (git191602) +- Add gcc12-PIE, similar to gcc-PIE but affecting gcc12 [bsc#1195628] +* Wed Feb 9 2022 rguenther@suse.com +- Put libstdc++6-pp Requires on the shared library and drop + to Recoomends. +* Tue Feb 8 2022 mliska@suse.cz +- Bump to 943d631abdd7be623cbf2b870d3d0cfef89f5f26, git191519. +* Mon Jan 24 2022 rguenther@suse.com +- Update to trunk head, 978abe918f8c8deed28e92297d3c0cc (git191254) +- Fix filenames in the following patches: + gcc11-amdgcn-disable-hot-cold-partitioning.patch, + gcc41-ppc32-retaddr.patch. +* Wed Jan 19 2022 mliska@suse.cz +- Bump to 0bd247bbbe4cf396173f09eeec37e116e98f8471. +- Fix filename in gcc10-amdgcn-llvm-as.patch. +* Wed Jan 19 2022 rguenther@suse.com +- Remove sys/rseq.h from include-fixed +* Tue Jan 18 2022 mliska@suse.cz +- Bump to 3c4a54adb2164315d18fd8980c0fc37eb3d22252. +- Rebase patches after .cc renaming. +* Thu Jan 13 2022 mliska@suse.cz +- New package, inherits from gcc11 + * Enable LSAN and TSAN for s390x target. + * Require gcc-d as dependency for proper bootstrap. + * Use gcc11-amdgcn-disable-hot-cold-partitioning.patch only conditionally + on older SUSE products. + * Add --enable-offload-defaulted to configure options. + * Include a couple of new header files. + * Do not require llvm11 for cross compilers (assembler was fixed + in latest LLVM releases), use llvm11 only on SLE 15. + * Remove unnecessary gcc10-foffload-default.patch patch. +- Take patches inherited from GCC 11. + * gcc-add-defaultsspec.diff, add the ability to provide a specs + file that is read by default + * tls-no-direct.diff, avoid direct %%fs references on x86 to not + slow down Xen + * gcc43-no-unwind-tables.diff, do not produce unwind tables for + CRT files + * gcc41-ppc32-retaddr.patch, fix expansion of __builtin_return_addr + for ppc, just a testcase + * gcc44-textdomain.patch, make translation files version specific + and adjust textdomain to find them + * gcc44-rename-info-files.patch, fix cross-references in info files + when renaming them to be version specific + * gcc48-libstdc++-api-reference.patch, fix link in the installed + libstdc++ html documentation + * gcc48-remove-mpfr-2.4.0-requirement.patch, make GCC work with + earlier mpfr versions on old products + * gcc5-no-return-gcc43-workaround.patch, make build work with + host gcc 4.3 + * gcc7-remove-Wexpansion-to-defined-from-Wextra.patch, removes + new warning from -Wextra + * gcc7-avoid-fixinc-error.diff + * gcc9-reproducible-builds-buildid-for-checksum.patch + * gcc9-reproducible-builds.patch + * gcc10-amdgcn-llvm-as.patch diff --git a/gcc41-ppc32-retaddr.patch b/gcc41-ppc32-retaddr.patch new file mode 100644 index 0000000..fde9d74 --- /dev/null +++ b/gcc41-ppc32-retaddr.patch @@ -0,0 +1,91 @@ +2005-11-28 Jakub Jelinek + + * config/rs6000/rs6000.c (rs6000_return_addr): If COUNT == 0, + read word RETURN_ADDRESS_OFFSET bytes above arg_pointer_rtx + instead of doing an extran indirection from frame_pointer_rtx. + + * gcc.dg/20051128-1.c: New test. + +#Index: gcc/config/rs6000/rs6000.cc +#=================================================================== +#--- gcc/config/rs6000/rs6000.cc.orig 2013-11-26 15:42:33.000000000 +0100 +#+++ gcc/config/rs6000/rs6000.cc 2013-11-26 16:44:14.566089231 +0100 +#@@ -20878,18 +20878,22 @@ rs6000_return_addr (int count, rtx frame + if (count != 0 + || ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_DARWIN) && flag_pic)) + { ++ rtx x; + cfun->machine->ra_needs_full_frame = 1; + +- return +- gen_rtx_MEM +- (Pmode, +- memory_address +- (Pmode, +- plus_constant (Pmode, +- copy_to_reg +- (gen_rtx_MEM (Pmode, +- memory_address (Pmode, frame))), +- RETURN_ADDRESS_OFFSET))); ++ if (count == 0) ++ { ++ gcc_assert (frame == frame_pointer_rtx); ++ x = arg_pointer_rtx; ++ } ++ else ++ { ++ x = memory_address (Pmode, frame); ++ x = copy_to_reg (gen_rtx_MEM (Pmode, x)); ++ } ++ ++ x = plus_constant (Pmode, x, RETURN_ADDRESS_OFFSET); ++ return gen_rtx_MEM (Pmode, memory_address (Pmode, x)); + } + + cfun->machine->ra_need_lr = 1; +Index: gcc/testsuite/gcc.dg/20051128-1.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ gcc/testsuite/gcc.dg/20051128-1.c 2013-11-26 16:44:14.566089231 +0100 +@@ -0,0 +1,41 @@ ++/* { dg-do run } */ ++/* { dg-options "-O2 -fpic" } */ ++ ++extern void exit (int); ++extern void abort (void); ++ ++int b; ++ ++struct A ++{ ++ void *pad[147]; ++ void *ra, *h; ++ long o; ++}; ++ ++void ++__attribute__((noinline)) ++foo (struct A *a, void *x) ++{ ++ __builtin_memset (a, 0, sizeof (a)); ++ if (!b) ++ exit (0); ++} ++ ++void ++__attribute__((noinline)) ++bar (void) ++{ ++ struct A a; ++ ++ __builtin_unwind_init (); ++ foo (&a, __builtin_return_address (0)); ++} ++ ++int ++main (void) ++{ ++ bar (); ++ abort (); ++ return 0; ++} diff --git a/gcc43-no-unwind-tables.diff b/gcc43-no-unwind-tables.diff new file mode 100644 index 0000000..2216f0f --- /dev/null +++ b/gcc43-no-unwind-tables.diff @@ -0,0 +1,13 @@ +Index: libgcc/Makefile.in +=================================================================== +--- libgcc/Makefile.in.orig 2015-12-14 11:33:03.225790694 +0100 ++++ libgcc/Makefile.in 2015-12-17 15:09:45.415136693 +0100 +@@ -301,7 +301,7 @@ CRTSTUFF_CFLAGS = -O2 $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -g0 \ + $(NO_PIE_CFLAGS) -finhibit-size-directive -fno-inline -fno-exceptions \ + -fno-zero-initialized-in-bss -fno-toplevel-reorder -fno-tree-vectorize \ + -fbuilding-libgcc -fno-stack-protector $(FORCE_EXPLICIT_EH_REGISTRY) \ +- $(INHIBIT_LIBC_CFLAGS) $(USE_TM_CLONE_REGISTRY) ++ $(INHIBIT_LIBC_CFLAGS) $(USE_TM_CLONE_REGISTRY) -fno-unwind-tables -fno-asynchronous-unwind-tables + + # Extra flags to use when compiling crt{begin,end}.o. + CRTSTUFF_T_CFLAGS = diff --git a/gcc44-rename-info-files.patch b/gcc44-rename-info-files.patch new file mode 100644 index 0000000..8cf22ad --- /dev/null +++ b/gcc44-rename-info-files.patch @@ -0,0 +1,708 @@ +#! /bin/sh -e + +# DP: Allow transformations on info file names. Reference the +# DP: transformed info file names in the texinfo files. + +dir= +if [ $# -eq 3 -a "$2" = '-d' ]; then + pdir="-d $3" + dir="$3/" +elif [ $# -ne 1 ]; then + echo >&2 "`basename $0`: script expects -patch|-unpatch as argument" + exit 1 +fi +case "$1" in + -patch) + patch $pdir -f --no-backup-if-mismatch -p0 < $0 + ;; + -unpatch) + patch $pdir -f --no-backup-if-mismatch -R -p0 < $0 + ;; + *) + echo >&2 "`basename $0`: script expects -patch|-unpatch as argument" + exit 1 +esac +exit 0 + + +gcc/ChangeLog: + +2004-02-17 Matthias Klose + + * Makefile.in: Allow transformations on info file names. + Define MAKEINFODEFS, macros to pass transformated info file + names to makeinfo. + * doc/cpp.texi: Use macros defined in MAKEINFODEFS for references. + * doc/cppinternals.texi: Likewise. + * doc/extend.texi: Likewise. + * doc/gcc.texi: Likewise. + * doc/gccint.texi: Likewise. + * doc/invoke.texi: Likewise. + * doc/libgcc.texi: Likewise. + * doc/makefile.texi: Likewise. + * doc/passes.texi: Likewise. + * doc/sourcebuild.texi: Likewise. + * doc/standards.texi: Likewise. + * doc/trouble.texi: Likewise. + +gcc/fortran/ChangeLog: + * Make-lang.in: Allow transformations on info file names. + Pass macros of transformated info file defined in MAKEINFODEFS + names to makeinfo. + * gfortran.texi: Use macros defined in MAKEINFODEFS for references. + +gcc/java/ChangeLog: + * Make-lang.in: Allow transformations on info file names. + Pass macros of transformated info file defined in MAKEINFODEFS + names to makeinfo. + * gcj.texi: Use macros defined in MAKEINFODEFS for references. + + +--- + gcc/Makefile.in | 74 ++++++++++++++++++++++++++++++++++++---------- + gcc/ada/gnat-style.texi | 2 - + gcc/ada/gnat_rm.texi | 2 - + gcc/ada/gnat_ugn.texi | 2 - + gcc/doc/cpp.texi | 2 - + gcc/doc/cppinternals.texi | 2 - + gcc/doc/extend.texi | 2 - + gcc/doc/gcc.texi | 8 ++-- + gcc/doc/gccint.texi | 4 +- + gcc/doc/install.texi | 2 - + gcc/doc/invoke.texi | 10 +++--- + gcc/doc/libgcc.texi | 2 - + gcc/doc/makefile.texi | 2 - + gcc/doc/passes.texi | 2 - + gcc/doc/standards.texi | 4 +- + gcc/fortran/Make-lang.in | 11 +++--- + gcc/fortran/gfortran.texi | 2 - + gcc/java/Make-lang.in | 19 +++++++++-- + gcc/java/gcj.texi | 20 ++++++------ + libgomp/Makefile.am | 13 ++++---- + libgomp/Makefile.in | 14 ++++---- + libgomp/libgomp.texi | 2 - + 22 files changed, 131 insertions(+), 70 deletions(-) + +Index: gcc/Makefile.in +=================================================================== +--- gcc/Makefile.in.orig 2018-11-14 11:23:57.356904398 +0100 ++++ gcc/Makefile.in 2018-11-14 11:23:57.368904603 +0100 +@@ -3133,8 +3133,29 @@ install-no-fixedincludes: + + doc: $(BUILD_INFO) $(GENERATED_MANPAGES) + +-INFOFILES = doc/cpp.info doc/gcc.info doc/gccint.info \ +- doc/gccinstall.info doc/cppinternals.info ++INFO_CPP_NAME = $(shell echo cpp|sed '$(program_transform_name)') ++INFO_GCC_NAME = $(shell echo gcc|sed '$(program_transform_name)') ++INFO_GXX_NAME = $(shell echo g++|sed '$(program_transform_name)') ++INFO_GCCINT_NAME = $(shell echo gccint|sed '$(program_transform_name)') ++INFO_GCCINSTALL_NAME = $(shell echo gccinstall|sed '$(program_transform_name)') ++INFO_CPPINT_NAME = $(shell echo cppinternals|sed '$(program_transform_name)') ++ ++INFO_FORTRAN_NAME = $(shell echo gfortran|sed '$(program_transform_name)') ++INFO_GCJ_NAME = $(shell echo gcj|sed '$(program_transform_name)') ++INFO_GDC_NAME = $(shell echo gdc|sed '$(program_transform_name)') ++ ++INFOFILES = doc/$(INFO_CPP_NAME).info doc/$(INFO_GCC_NAME).info \ ++ doc/$(INFO_GCCINT_NAME).info \ ++ doc/$(INFO_GCCINSTALL_NAME).info doc/$(INFO_CPPINT_NAME).info ++ ++MAKEINFODEFS = -D 'fncpp $(INFO_CPP_NAME)' -D 'fngcc $(INFO_GCC_NAME)' \ ++ -D 'fngxx $(INFO_GXX_NAME)' \ ++ -D 'fngccint $(INFO_GCCINT_NAME)' \ ++ -D 'fngccinstall $(INFO_GCCINSTALL_NAME)' \ ++ -D 'fncppint $(INFO_CPPINT_NAME)' \ ++ -D 'fngfortran $(INFO_FORTRAN_NAME)' \ ++ -D 'fngcj $(INFO_GCJ_NAME)' \ ++ -D 'fngdc $(INFO_GDC_NAME)' + + info: $(INFOFILES) lang.info @GENINSRC@ srcinfo lang.srcinfo + +@@ -3189,21 +3210,41 @@ gcc-vers.texi: $(BASEVER) $(DEVPHASE) + # patterns. To use them, put each of the specific targets with its + # specific dependencies but no build commands. + +-doc/cpp.info: $(TEXI_CPP_FILES) +-doc/gcc.info: $(TEXI_GCC_FILES) +-doc/gccint.info: $(TEXI_GCCINT_FILES) +-doc/cppinternals.info: $(TEXI_CPPINT_FILES) +- ++# Generic entry to handle info files, which are not renamed (currently Ada) + doc/%.info: %.texi + if [ x$(BUILD_INFO) = xinfo ]; then \ + $(MAKEINFO) $(MAKEINFOFLAGS) -I . -I $(gcc_docdir) \ + -I $(gcc_docdir)/include -o $@ $<; \ + fi + ++doc/$(INFO_CPP_NAME).info: $(TEXI_CPP_FILES) ++ if [ x$(BUILD_INFO) = xinfo ]; then \ ++ $(MAKEINFO) $(MAKEINFOFLAGS) $(MAKEINFODEFS) -I $(gcc_docdir) \ ++ -I $(gcc_docdir)/include -o $@ $<; \ ++ fi ++ ++doc/$(INFO_GCC_NAME).info: $(TEXI_GCC_FILES) ++ if [ x$(BUILD_INFO) = xinfo ]; then \ ++ $(MAKEINFO) $(MAKEINFOFLAGS) $(MAKEINFODEFS) -I $(gcc_docdir) \ ++ -I $(gcc_docdir)/include -o $@ $<; \ ++ fi ++ ++doc/$(INFO_GCCINT_NAME).info: $(TEXI_GCCINT_FILES) ++ if [ x$(BUILD_INFO) = xinfo ]; then \ ++ $(MAKEINFO) $(MAKEINFOFLAGS) $(MAKEINFODEFS) -I $(gcc_docdir) \ ++ -I $(gcc_docdir)/include -o $@ $<; \ ++ fi ++ ++doc/$(INFO_CPPINT_NAME).info: $(TEXI_CPPINT_FILES) ++ if [ x$(BUILD_INFO) = xinfo ]; then \ ++ $(MAKEINFO) $(MAKEINFOFLAGS) $(MAKEINFODEFS) -I $(gcc_docdir) \ ++ -I $(gcc_docdir)/include -o $@ $<; \ ++ fi ++ + # Duplicate entry to handle renaming of gccinstall.info +-doc/gccinstall.info: $(TEXI_GCCINSTALL_FILES) ++doc/$(INFO_GCCINSTALL_NAME).info: $(TEXI_GCCINSTALL_FILES) + if [ x$(BUILD_INFO) = xinfo ]; then \ +- $(MAKEINFO) $(MAKEINFOFLAGS) -I $(gcc_docdir) \ ++ $(MAKEINFO) $(MAKEINFOFLAGS) $(MAKEINFODEFS) -I $(gcc_docdir) \ + -I $(gcc_docdir)/include -o $@ $<; \ + fi + +@@ -3622,11 +3663,11 @@ install-driver: installdirs xgcc$(exeext + # $(INSTALL_DATA) might be a relative pathname, so we can't cd into srcdir + # to do the install. + install-info:: doc installdirs \ +- $(DESTDIR)$(infodir)/cpp.info \ +- $(DESTDIR)$(infodir)/gcc.info \ +- $(DESTDIR)$(infodir)/cppinternals.info \ +- $(DESTDIR)$(infodir)/gccinstall.info \ +- $(DESTDIR)$(infodir)/gccint.info \ ++ $(DESTDIR)$(infodir)/$(INFO_CPP_NAME).info \ ++ $(DESTDIR)$(infodir)/$(INFO_GCC_NAME).info \ ++ $(DESTDIR)$(infodir)/$(INFO_CPPINT_NAME).info \ ++ $(DESTDIR)$(infodir)/$(INFO_GCCINSTALL_NAME).info \ ++ $(DESTDIR)$(infodir)/$(INFO_GCCINT_NAME).info \ + lang.install-info + + $(DESTDIR)$(infodir)/%.info: doc/%.info installdirs +@@ -3847,8 +3888,11 @@ uninstall: lang.uninstall + -rm -rf $(DESTDIR)$(bindir)/$(GCOV_INSTALL_NAME)$(exeext) + -rm -rf $(DESTDIR)$(man1dir)/$(GCC_INSTALL_NAME)$(man1ext) + -rm -rf $(DESTDIR)$(man1dir)/cpp$(man1ext) +- -rm -f $(DESTDIR)$(infodir)/cpp.info* $(DESTDIR)$(infodir)/gcc.info* +- -rm -f $(DESTDIR)$(infodir)/cppinternals.info* $(DESTDIR)$(infodir)/gccint.info* ++ -rm -f $(DESTDIR)$(infodir)/$(INFO_CPP_NAME).info* ++ -rm -f $(DESTDIR)$(infodir)/$(INFO_GCC_NAME).info* ++ -rm -f $(DESTDIR)$(infodir)/$(INFO_CPPINT_NAME).info* ++ -rm -f $(DESTDIR)$(infodir)/$(INFO_GCCINT_NAME).info* ++ -rm -f $(DESTDIR)$(infodir)/$(INFO_GCCINSTALL_NAME).info* + for i in ar nm ranlib ; do \ + install_name=`echo gcc-$$i|sed '$(program_transform_name)'`$(exeext) ;\ + target_install_name=$(target_noncanonical)-`echo gcc-$$i|sed '$(program_transform_name)'`$(exeext) ; \ +Index: gcc/ada/gnat-style.texi +=================================================================== +--- gcc/ada/gnat-style.texi.orig 2016-08-16 10:58:00.521572015 +0200 ++++ gcc/ada/gnat-style.texi 2018-11-14 11:23:57.368904603 +0100 +@@ -12,7 +12,7 @@ + @finalout + @dircategory GNU Ada Tools + @direntry +-* gnat-style: (gnat-style.info). gnat-style ++* gnat-style: (gnat-style-12.info). gnat-style + @end direntry + + @definfoenclose strong,`,' +Index: gcc/ada/gnat_rm.texi +=================================================================== +--- gcc/ada/gnat_rm.texi.orig 2018-10-26 10:14:40.688554403 +0200 ++++ gcc/ada/gnat_rm.texi 2018-11-14 11:23:57.372904672 +0100 +@@ -12,7 +12,7 @@ + @finalout + @dircategory GNU Ada Tools + @direntry +-* gnat_rm: (gnat_rm.info). gnat_rm ++* GNAT Reference Manual: (gnat_rm-12). Reference Manual for GNU Ada tools. + @end direntry + + @definfoenclose strong,`,' +Index: gcc/ada/gnat_ugn.texi +=================================================================== +--- gcc/ada/gnat_ugn.texi.orig 2018-10-26 10:14:48.048683475 +0200 ++++ gcc/ada/gnat_ugn.texi 2018-11-14 11:23:57.376904740 +0100 +@@ -12,7 +12,7 @@ + @finalout + @dircategory GNU Ada Tools + @direntry +-* gnat_ugn: (gnat_ugn.info). gnat_ugn ++* User's Guide: (gnat_ugn-12). + @end direntry + + @definfoenclose strong,`,' +Index: gcc/doc/cpp.texi +=================================================================== +--- gcc/doc/cpp.texi.orig 2018-11-14 11:16:31.441269711 +0100 ++++ gcc/doc/cpp.texi 2018-11-14 11:23:57.376904740 +0100 +@@ -50,7 +50,7 @@ This manual contains no Invariant Sectio + @ifinfo + @dircategory Software development + @direntry +-* Cpp: (cpp). The GNU C preprocessor. ++* @value{fncpp}: (@value{fncpp}). The GNU C preprocessor. + @end direntry + @end ifinfo + +Index: gcc/doc/cppinternals.texi +=================================================================== +--- gcc/doc/cppinternals.texi.orig 2018-01-05 11:48:15.057892840 +0100 ++++ gcc/doc/cppinternals.texi 2018-11-14 11:23:57.376904740 +0100 +@@ -7,7 +7,7 @@ + @ifinfo + @dircategory Software development + @direntry +-* Cpplib: (cppinternals). Cpplib internals. ++* @value{fncppint}: (@value{fncppint}). Cpplib internals. + @end direntry + @end ifinfo + +Index: gcc/doc/extend.texi +=================================================================== +--- gcc/doc/extend.texi.orig 2018-11-14 11:16:31.449269848 +0100 ++++ gcc/doc/extend.texi 2018-11-14 11:23:57.380904808 +0100 +@@ -23097,7 +23097,7 @@ want to write code that checks whether t + test for the GNU compiler the same way as for C programs: check for a + predefined macro @code{__GNUC__}. You can also use @code{__GNUG__} to + test specifically for GNU C++ (@pxref{Common Predefined Macros,, +-Predefined Macros,cpp,The GNU C Preprocessor}). ++Predefined Macros,@value{fncpp},The GNU C Preprocessor}). + + @menu + * C++ Volatiles:: What constitutes an access to a volatile object. +Index: gcc/doc/gcc.texi +=================================================================== +--- gcc/doc/gcc.texi.orig 2018-01-05 11:48:15.049892709 +0100 ++++ gcc/doc/gcc.texi 2018-11-14 11:23:57.380904808 +0100 +@@ -63,12 +63,12 @@ Texts being (a) (see below), and with the Back-Cover Texts being (b) + @ifnottex + @dircategory Software development + @direntry +-* gcc: (gcc). The GNU Compiler Collection. +-* g++: (gcc). The GNU C++ compiler. +-* gcov: (gcc) Gcov. @command{gcov}---a test coverage program. +-* gcov-tool: (gcc) Gcov-tool. @command{gcov-tool}---an offline gcda profile processing program. +-* gcov-dump: (gcc) Gcov-dump. @command{gcov-dump}---an offline gcda and gcno profile dump tool. +-* lto-dump: (gcc) lto-dump. @command{lto-dump}---Tool for ++* @value{fngcc}: (@value{fngcc}). The GNU Compiler Collection. ++* @value{fngxx}: (@value{fngcc}). The GNU C++ compiler. ++* gcov: (@value{fngcc}) Gcov. @command{gcov}---a test coverage program. ++* gcov-tool: (@value{fngcc}) Gcov-tool. @command{gcov-tool}---an offline gcda profile processing program. ++* gcov-dump: (@value{fngcc}) Gcov-dump. @command{gcov-dump}---an offline gcda and gcno profile dump tool. ++* lto-dump: (@value{fngcc}) Lto-dump. @command{lto-dump}---Tool for + dumping LTO object files. + @end direntry + This file documents the use of the GNU compilers. +@@ -127,7 +127,7 @@ version @value{version-GCC}. + The internals of the GNU compilers, including how to port them to new + targets and some information about how to write front ends for new + languages, are documented in a separate manual. @xref{Top,, +-Introduction, gccint, GNU Compiler Collection (GCC) Internals}. ++Introduction, @value{fngccint}, GNU Compiler Collection (GCC) Internals}. + + @menu + * G++ and GCC:: You can compile C or C++ programs. +Index: gcc/doc/gccint.texi +=================================================================== +--- gcc/doc/gccint.texi.orig 2018-10-26 10:14:33.412426798 +0200 ++++ gcc/doc/gccint.texi 2018-11-14 11:23:57.380904808 +0100 +@@ -49,7 +49,7 @@ Texts being (a) (see below), and with th + @ifnottex + @dircategory Software development + @direntry +-* gccint: (gccint). Internals of the GNU Compiler Collection. ++* @value{fngccint}: (@value{fngccint}). Internals of the GNU Compiler Collection. + @end direntry + This file documents the internals of the GNU compilers. + @sp 1 +@@ -81,7 +81,7 @@ write front ends for new languages. It + @value{VERSION_PACKAGE} + @end ifset + version @value{version-GCC}. The use of the GNU compilers is documented in a +-separate manual. @xref{Top,, Introduction, gcc, Using the GNU ++separate manual. @xref{Top,, Introduction, @value{fngcc}, Using the GNU + Compiler Collection (GCC)}. + + This manual is mainly a reference manual rather than a tutorial. It +Index: gcc/doc/install.texi +=================================================================== +--- gcc/doc/install.texi.orig 2018-11-14 11:16:31.485270465 +0100 ++++ gcc/doc/install.texi 2018-11-14 11:23:57.380904808 +0100 +@@ -94,7 +94,7 @@ Free Documentation License}''. + @end ifinfo + @dircategory Software development + @direntry +-* gccinstall: (gccinstall). Installing the GNU Compiler Collection. ++* @value{fngccinstall}: (@value{fngccinstall}). Installing the GNU Compiler Collection. + @end direntry + + @c Part 3 Titlepage and Copyright +Index: gcc/doc/invoke.texi +=================================================================== +--- gcc/doc/invoke.texi.orig 2018-11-14 11:16:31.473270259 +0100 ++++ gcc/doc/invoke.texi 2018-11-14 11:23:57.384904877 +0100 +@@ -12812,7 +12812,7 @@ One of the standard libraries bypassed b + @option{-nodefaultlibs} is @file{libgcc.a}, a library of internal subroutines + which GCC uses to overcome shortcomings of particular machines, or special + needs for some languages. +-(@xref{Interface,,Interfacing to GCC Output,gccint,GNU Compiler ++(@xref{Interface,,Interfacing to GCC Output,@value{fngccint},GNU Compiler + Collection (GCC) Internals}, + for more discussion of @file{libgcc.a}.) + In most cases, you need @file{libgcc.a} even when you want to avoid +@@ -12821,7 +12821,7 @@ or @option{-nodefaultlibs} you should us + This ensures that you have no unresolved references to internal GCC + library subroutines. + (An example of such an internal subroutine is @code{__main}, used to ensure C++ +-constructors are called; @pxref{Collect2,,@code{collect2}, gccint, ++constructors are called; @pxref{Collect2,,@code{collect2}, @value{fngccint}, + GNU Compiler Collection (GCC) Internals}.) + + @item -e @var{entry} +@@ -29745,7 +29745,7 @@ Note that you can also specify places to + @option{-B}, @option{-I} and @option{-L} (@pxref{Directory Options}). These + take precedence over places specified using environment variables, which + in turn take precedence over those specified by the configuration of GCC@. +-@xref{Driver,, Controlling the Compilation Driver @file{gcc}, gccint, ++@xref{Driver,, Controlling the Compilation Driver @file{gcc}, @value{fngccint}, + GNU Compiler Collection (GCC) Internals}. + + @table @env +@@ -29905,7 +29905,7 @@ the headers it contains change. + + A precompiled header file is searched for when @code{#include} is + seen in the compilation. As it searches for the included file +-(@pxref{Search Path,,Search Path,cpp,The C Preprocessor}) the ++(@pxref{Search Path,,Search Path,@value{fncpp},The C Preprocessor}) the + compiler looks for a precompiled header in each directory just before it + looks for the include file in that directory. The name searched for is + the name specified in the @code{#include} with @samp{.gch} appended. If +Index: gcc/doc/libgcc.texi +=================================================================== +--- gcc/doc/libgcc.texi.orig 2018-01-05 11:48:15.629902164 +0100 ++++ gcc/doc/libgcc.texi 2018-11-14 11:23:57.384904877 +0100 +@@ -24,7 +24,7 @@ that needs them. + GCC will also generate calls to C library routines, such as + @code{memcpy} and @code{memset}, in some cases. The set of routines + that GCC may possibly use is documented in @ref{Other +-Builtins,,,gcc, Using the GNU Compiler Collection (GCC)}. ++Builtins,,,@value{fngcc}, Using the GNU Compiler Collection (GCC)}. + + These routines take arguments and return values of a specific machine + mode, not a specific C type. @xref{Machine Modes}, for an explanation +Index: gcc/fortran/Make-lang.in +=================================================================== +--- gcc/fortran/Make-lang.in.orig 2018-10-26 10:15:03.220949527 +0200 ++++ gcc/fortran/Make-lang.in 2018-11-14 11:23:57.384904877 +0100 +@@ -116,7 +116,8 @@ fortran.tags: force + cd $(srcdir)/fortran; $(ETAGS) -o TAGS.sub *.c *.h; \ + $(ETAGS) --include TAGS.sub --include ../TAGS.sub + +-fortran.info: doc/gfortran.info doc/gfc-internals.info ++INFO_FORTRAN_NAME = $(shell echo gfortran|sed '$(program_transform_name)') ++fortran.info: doc/$(INFO_FORTRAN_NAME).info + + F95_DVIFILES = doc/gfortran.dvi + +@@ -184,10 +185,10 @@ GFORTRAN_TEXI = \ + $(srcdir)/doc/include/gcc-common.texi \ + gcc-vers.texi + +-doc/gfortran.info: $(GFORTRAN_TEXI) ++doc/$(INFO_FORTRAN_NAME).info: $(GFORTRAN_TEXI) + if [ x$(BUILD_INFO) = xinfo ]; then \ + rm -f doc/gfortran.info-*; \ +- $(MAKEINFO) -I $(srcdir)/doc/include -I $(srcdir)/fortran \ ++ $(MAKEINFO) $(MAKEINFODEFS) -I $(srcdir)/doc/include -I $(srcdir)/fortran \ + -o $@ $<; \ + else true; fi + +@@ -252,7 +253,7 @@ fortran.install-common: install-finclude + + fortran.install-plugin: + +-fortran.install-info: $(DESTDIR)$(infodir)/gfortran.info ++fortran.install-info: $(DESTDIR)$(infodir)/$(INFO_FORTRAN_NAME).info + + fortran.install-man: $(DESTDIR)$(man1dir)/$(GFORTRAN_INSTALL_NAME)$(man1ext) + +@@ -270,7 +271,7 @@ fortran.uninstall: + rm -rf $(DESTDIR)$(bindir)/$(GFORTRAN_INSTALL_NAME)$(exeext); \ + rm -rf $(DESTDIR)$(man1dir)/$(GFORTRAN_INSTALL_NAME)$(man1ext); \ + rm -rf $(DESTDIR)$(bindir)/$(GFORTRAN_TARGET_INSTALL_NAME)$(exeext); \ +- rm -rf $(DESTDIR)$(infodir)/gfortran.info* ++ rm -rf $(DESTDIR)$(infodir)/$(INFO_FORTRAN_NAME).info* + + # + # Clean hooks: +Index: gcc/fortran/gfortran.texi +=================================================================== +--- gcc/fortran/gfortran.texi.orig 2018-11-02 12:34:35.446010493 +0100 ++++ gcc/fortran/gfortran.texi 2018-11-14 11:23:57.384904877 +0100 +@@ -101,7 +101,7 @@ Texts being (a) (see below), and with th + @ifinfo + @dircategory Software development + @direntry +-* gfortran: (gfortran). The GNU Fortran Compiler. ++* @value{fngfortran}: (@value{fngfortran}). The GNU Fortran Compiler. + @end direntry + This file documents the use and the internals of + the GNU Fortran compiler, (@command{gfortran}). +Index: libffi/Makefile.am +=================================================================== +--- libffi/Makefile.am.orig 2018-11-02 12:34:40.094088439 +0100 ++++ libffi/Makefile.am 2018-11-14 11:23:57.384904877 +0100 +@@ -25,6 +25,8 @@ TEXINFO_TEX = ../gcc/doc/include/texin + # Defines info, dvi, pdf and html targets + MAKEINFOFLAGS = -I $(srcdir)/../gcc/doc/include + info_TEXINFOS = doc/libffi.texi ++INFO_LIBFFI_NAME = $(shell echo libffi | sed '${program_transform_name}') ++INFO_DEPS = doc/$(INFO_LIBFFI_NAME).info + + # AM_CONDITIONAL on configure option --generated-files-in-srcdir + if GENINSRC +@@ -42,14 +44,14 @@ endif + + all-local: $(STAMP_GENINSRC) + +-stamp-geninsrc: doc/libffi.info +- cp -p $(top_builddir)/doc/libffi.info $(srcdir)/doc/libffi.info ++stamp-geninsrc: doc/$(INFO_LIBFFI_NAME).info ++ cp -p $(top_builddir)/doc/$(INFO_LIBFFI_NAME).info $(srcdir)/doc/libffi.info + @touch $@ + +-doc/libffi.info: $(STAMP_BUILD_INFO) ++doc/$(INFO_LIBFFI_NAME).info: $(STAMP_BUILD_INFO) + + stamp-build-info: doc/libffi.texi $(srcdir)/doc/version.texi doc/$(am__dirstamp) +- $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)/doc -o doc/libffi.info $(srcdir)/doc/libffi.texi ++ $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -D 'fnlibffi $(INFO_LIBFFI_NAME)' -I $(srcdir)/doc -o doc/$(INFO_LIBFFI_NAME).info $(srcdir)/doc/libffi.texi + @touch $@ + + CLEANFILES = $(STAMP_GENINSRC) $(STAMP_BUILD_INFO) +Index: libffi/Makefile.in +=================================================================== +--- libffi/Makefile.in.orig 2018-11-02 12:34:43.298142170 +0100 ++++ libffi/Makefile.in 2018-11-14 11:23:57.384904877 +0100 +@@ -247,7 +247,8 @@ AM_V_texidevnull = $(am__v_texidevnull_@AM_V@) + am__v_texidevnull_ = $(am__v_texidevnull_@AM_DEFAULT_V@) + am__v_texidevnull_0 = > /dev/null + am__v_texidevnull_1 = +-INFO_DEPS = doc/libffi.info ++INFO_LIBFFI_NAME = $(shell echo libffi | sed '${program_transform_name}') ++INFO_DEPS = doc/$(INFO_LIBFFI_NAME).info + am__TEXINFO_TEX_DIR = $(srcdir)/../gcc/doc/include + DVIS = doc/libffi.dvi + PDFS = doc/libffi.pdf +@@ -470,6 +471,8 @@ TEXINFO_TEX = ../gcc/doc/include/texinfo.tex + # Defines info, dvi, pdf and html targets + MAKEINFOFLAGS = -I $(srcdir)/../gcc/doc/include + info_TEXINFOS = doc/libffi.texi ++INFO_LIBFFI_NAME = $(shell echo libffi | sed '${program_transform_name}') ++INFO_DEPS = doc/$(INFO_LIBFFI_NAME).info + @GENINSRC_FALSE@STAMP_GENINSRC = + + # AM_CONDITIONAL on configure option --generated-files-in-srcdir +@@ -1903,14 +1906,15 @@ uninstall-am: uninstall-dvi-am uninstall-html-am uninstall-info-am \ + + all-local: $(STAMP_GENINSRC) + +-stamp-geninsrc: doc/libffi.info +- cp -p $(top_builddir)/doc/libffi.info $(srcdir)/doc/libffi.info ++$(srcdir)/doc/libffi.info: stamp-geninsrc ++stamp-geninsrc: doc/$(INFO_LIBFFI_NAME).info ++ cp -p $(top_builddir)/doc/$(INFO_LIBFFI_NAME).info $(srcdir)/doc/libffi.info + @touch $@ + +-doc/libffi.info: $(STAMP_BUILD_INFO) ++doc/$(INFO_LIBFFI_NAME).info: $(STAMP_BUILD_INFO) + + stamp-build-info: doc/libffi.texi $(srcdir)/doc/version.texi doc/$(am__dirstamp) +- $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)/doc -o doc/libffi.info $(srcdir)/doc/libffi.texi ++ $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -D 'fnlibffi $(INFO_LIBFFI_NAME)' -I $(srcdir)/doc -o doc/$(INFO_LIBFFI_NAME).info $(srcdir)/doc/libffi.texi + @touch $@ + @LIBFFI_BUILD_VERSIONED_SHLIB_SUN_TRUE@@LIBFFI_BUILD_VERSIONED_SHLIB_TRUE@libffi.map-sun : libffi.map $(top_srcdir)/../contrib/make_sunver.pl \ + @LIBFFI_BUILD_VERSIONED_SHLIB_SUN_TRUE@@LIBFFI_BUILD_VERSIONED_SHLIB_TRUE@ $(libffi_la_OBJECTS) $(libffi_la_LIBADD) +Index: libffi/doc/libffi.texi +=================================================================== +--- libffi/doc/libffi.texi.orig 2015-01-29 13:55:28.849745068 +0100 ++++ libffi/doc/libffi.texi 2018-11-14 11:23:57.384904877 +0100 +@@ -43,7 +43,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @dircategory Development + @direntry +-* libffi: (libffi). Portable foreign function interface library. ++* libffi: (@value{fnlibffi}). Portable foreign-function interface library. + @end direntry + + @titlepage +Index: libgomp/Makefile.am +=================================================================== +--- libgomp/Makefile.am.orig 2018-11-14 11:16:19.017056772 +0100 ++++ libgomp/Makefile.am 2018-11-14 11:23:57.384904877 +0100 +@@ -127,14 +127,17 @@ endif + + all-local: $(STAMP_GENINSRC) + +-stamp-geninsrc: libgomp.info +- cp -p $(top_builddir)/libgomp.info $(srcdir)/libgomp.info ++INFO_LIBGOMP_NAME = $(shell echo libgomp|sed '$(program_transform_name)') ++stamp-geninsrc: $(INFO_LIBGOMP_NAME).info ++ cp -p $(top_builddir)/$(INFO_LIBGOMP_NAME).info $(srcdir)/libgomp.info + @touch $@ + +-libgomp.info: $(STAMP_BUILD_INFO) ++libgomp.info: $(INFO_LIBGOMP_NAME).info ++ cp $(INFO_LIBGOMP_NAME).info libgomp.info ++$(STAMP_BUILD_INFO).info: $(STAMP_BUILD_INFO) + + stamp-build-info: libgomp.texi +- $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) -o libgomp.info $(srcdir)/libgomp.texi ++ $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) -o $(INFO_LIBGOMP_NAME).info $(srcdir)/libgomp.texi + @touch $@ + + +Index: libgomp/Makefile.in +=================================================================== +--- libgomp/Makefile.in.orig 2018-11-14 11:16:58.797738530 +0100 ++++ libgomp/Makefile.in 2018-11-14 11:23:57.384904877 +0100 +@@ -601,6 +601,7 @@ info_TEXINFOS = libgomp.texi + + # AM_CONDITIONAL on configure check ACX_CHECK_PROG_VER([MAKEINFO]) + @BUILD_INFO_TRUE@STAMP_BUILD_INFO = stamp-build-info ++INFO_LIBGOMP_NAME = $(shell echo libgomp|sed '$(program_transform_name)') + CLEANFILES = $(STAMP_GENINSRC) $(STAMP_BUILD_INFO) + MAINTAINERCLEANFILES = $(srcdir)/libgomp.info + MULTISRCTOP = +@@ -1428,15 +1429,16 @@ env.lo: libgomp_f.h + env.o: libgomp_f.h + + all-local: $(STAMP_GENINSRC) +- +-stamp-geninsrc: libgomp.info +- cp -p $(top_builddir)/libgomp.info $(srcdir)/libgomp.info ++stamp-geninsrc: $(INFO_LIBGOMP_NAME).info ++ cp -p $(top_builddir)/$(INFO_LIBGOMP_NAME).info $(srcdir)/libgomp.info + @touch $@ + +-libgomp.info: $(STAMP_BUILD_INFO) ++libgomp.info: $(INFO_LIBGOMP_NAME).info ++ cp $(INFO_LIBGOMP_NAME).info libgomp.info ++$(INFO_LIBGOMP_NAME).info: $(STAMP_BUILD_INFO) + + stamp-build-info: libgomp.texi +- $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) -o libgomp.info $(srcdir)/libgomp.texi ++ $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -D 'fnlibgomp $(INFO_LIBGOMP_NAME)' -I $(srcdir) -o $(INFO_LIBGOMP_NAME).info $(srcdir)/libgomp.texi + @touch $@ + + # target overrides +Index: libgomp/libgomp.texi +=================================================================== +--- libgomp/libgomp.texi.orig 2018-10-26 10:15:47.925733302 +0200 ++++ libgomp/libgomp.texi 2018-11-14 11:23:57.388904945 +0100 +@@ -31,7 +31,7 @@ texts being (a) (see below), and with th + @ifinfo + @dircategory GNU Libraries + @direntry +-* libgomp: (libgomp). GNU Offloading and Multi Processing Runtime Library. ++* @value{fnlibgomp}: (@value{fnlibgomp}). GNU Offloading and Multi Processing Runtime Library. + @end direntry + + This manual documents libgomp, the GNU Offloading and Multi Processing +Index: libitm/libitm.texi +=================================================================== +--- libitm/libitm.texi.orig 2018-01-05 11:47:36.801269131 +0100 ++++ libitm/libitm.texi 2018-11-14 11:23:57.388904945 +0100 +@@ -20,7 +20,7 @@ Free Documentation License''. + @ifinfo + @dircategory GNU Libraries + @direntry +-* libitm: (libitm). GNU Transactional Memory Library ++* libitm: (libitm-6). GNU Transactional Memory Library + @end direntry + + This manual documents the GNU Transactional Memory Library. +Index: libquadmath/libquadmath.texi +=================================================================== +--- libquadmath/libquadmath.texi.orig 2018-11-06 11:26:49.566013749 +0100 ++++ libquadmath/libquadmath.texi 2018-11-14 11:23:57.388904945 +0100 +@@ -25,7 +25,7 @@ copy and modify this GNU manual. + @ifinfo + @dircategory GNU Libraries + @direntry +-* libquadmath: (libquadmath). GCC Quad-Precision Math Library ++* libquadmath: (libquadmath-6). GCC Quad-Precision Math Library + @end direntry + + This manual documents the GCC Quad-Precision Math Library API. +Index: gcc/d/Make-lang.in +=================================================================== +--- gcc/d/Make-lang.in.orig 2018-11-02 12:34:28.053886530 +0100 ++++ gcc/d/Make-lang.in 2018-11-14 11:23:57.388904945 +0100 +@@ -157,10 +157,11 @@ D_TEXI_FILES = \ + $(gcc_docdir)/include/gcc-common.texi \ + gcc-vers.texi + +-doc/gdc.info: $(D_TEXI_FILES) ++INFO_GDC_NAME = $(shell echo gdc|sed '$(program_transform_name)') ++doc/$(INFO_GDC_NAME).info: $(D_TEXI_FILES) + if test "x$(BUILD_INFO)" = xinfo; then \ +- rm -f doc/gdc.info*; \ +- $(MAKEINFO) $(MAKEINFOFLAGS) -I $(gcc_docdir) \ ++ rm -f doc/$(INFO_GDC_NAME).info*; \ ++ $(MAKEINFO) $(MAKEINFOFLAGS) $(MAKEINFODEFS) -I $(gcc_docdir) \ + -I $(gcc_docdir)/include -o $@ $<; \ + else true; fi + +@@ -186,11 +187,11 @@ gdc.pod: d/gdc.texi + d.all.cross: gdc-cross$(exeext) + d.start.encap: gdc$(exeext) + d.rest.encap: +-d.info: doc/gdc.info ++d.info: doc/$(INFO_GDC_NAME).info + d.dvi: doc/gdc.dvi + d.pdf: doc/gdc.pdf + d.html: $(build_htmldir)/d/index.html +-d.srcinfo: doc/gdc.info ++d.srcinfo: doc/$(INFO_GDC_NAME).info + -cp -p $^ $(srcdir)/doc + d.srcextra: + +@@ -231,7 +232,7 @@ d.install-common: installdirs + + d.install-plugin: + +-d.install-info: $(DESTDIR)$(infodir)/gdc.info ++d.install-info: $(DESTDIR)$(infodir)/$(INFO_GDC_NAME).info + + d.install-pdf: doc/gdc.pdf + @$(NORMAL_INSTALL) +@@ -271,7 +272,7 @@ d.uninstall: + -rm -rf $(DESTDIR)$(bindir)/$(D_INSTALL_NAME)$(exeext) + -rm -rf $(DESTDIR)$(man1dir)/$(D_INSTALL_NAME)$(man1ext) + -rm -rf $(DESTDIR)$(bindir)/$(D_TARGET_INSTALL_NAME)$(exeext) +- -rm -rf $(DESTDIR)$(infodir)/gdc.info* ++ -rm -rf $(DESTDIR)$(infodir)/$(INFO_GDC_NAME).info* + + # Clean hooks. + +Index: gcc/d/gdc.texi +=================================================================== +--- gcc/d/gdc.texi.orig 2018-10-29 10:38:03.898079629 +0100 ++++ gcc/d/gdc.texi 2018-11-14 11:23:57.388904945 +0100 +@@ -36,7 +36,7 @@ man page gfdl(7). + @format + @dircategory Software development + @direntry +-* gdc: (gdc). A GCC-based compiler for the D language ++* @value{fngdc}: (@value{fngdc}). A GCC-based compiler for the D language + @end direntry + @end format + diff --git a/gcc44-textdomain.patch b/gcc44-textdomain.patch new file mode 100644 index 0000000..34fd076 --- /dev/null +++ b/gcc44-textdomain.patch @@ -0,0 +1,115 @@ +#! /bin/sh -e + +# DP: Set gettext's domain and textdomain to the versioned package name. + +dir= +if [ $# -eq 3 -a "$2" = '-d' ]; then + pdir="-d $3" + dir="$3/" +elif [ $# -ne 1 ]; then + echo >&2 "`basename $0`: script expects -patch|-unpatch as argument" + exit 1 +fi +case "$1" in + -patch) + patch $pdir -f --no-backup-if-mismatch -p0 < $0 + ;; + -unpatch) + patch $pdir -f --no-backup-if-mismatch -R -p0 < $0 + ;; + *) + echo >&2 "`basename $0`: script expects -patch|-unpatch as argument" + exit 1 +esac +exit 0 + +diff --git a/gcc/Makefile.in b/gcc/Makefile.in +index 0fe2ba241..86e5fb9e7 100644 +--- a/gcc/Makefile.in ++++ b/gcc/Makefile.in +@@ -4303,8 +4303,8 @@ install-po: + dir=$(localedir)/$$lang/LC_MESSAGES; \ + echo $(mkinstalldirs) $(DESTDIR)$$dir; \ + $(mkinstalldirs) $(DESTDIR)$$dir || exit 1; \ +- echo $(INSTALL_DATA) $$cat $(DESTDIR)$$dir/gcc.mo; \ +- $(INSTALL_DATA) $$cat $(DESTDIR)$$dir/gcc.mo; \ ++ echo $(INSTALL_DATA) $$cat $(DESTDIR)$$dir/gcc-12.mo; \ ++ $(INSTALL_DATA) $$cat $(DESTDIR)$$dir/gcc-12.mo; \ + done + + # Rule for regenerating the message template (gcc.pot). +diff --git a/gcc/intl.cc b/gcc/intl.cc +index e8108b7dc..62895c11f 100644 +--- a/gcc/intl.cc ++++ b/gcc/intl.cc +@@ -55,8 +55,8 @@ gcc_init_libintl (void) + setlocale (LC_ALL, ""); + #endif + +- (void) bindtextdomain ("gcc", LOCALEDIR); +- (void) textdomain ("gcc"); ++ (void) bindtextdomain ("gcc-12", LOCALEDIR); ++ (void) textdomain ("gcc-12"); + + /* Opening quotation mark. */ + open_quote = _("`"); +diff --git a/libcpp/Makefile.in b/libcpp/Makefile.in +index 5fbba9b9c..c37bc6bcf 100644 +--- a/libcpp/Makefile.in ++++ b/libcpp/Makefile.in +@@ -49,6 +49,7 @@ LDFLAGS = @LDFLAGS@ + LIBICONV = @LIBICONV@ + LIBINTL = @LIBINTL@ + PACKAGE = @PACKAGE@ ++PACKAGE_SUFFIX = -12 + RANLIB = @RANLIB@ + SHELL = @SHELL@ + USED_CATALOGS = @USED_CATALOGS@ +@@ -76,8 +77,10 @@ INCLUDES = -I$(srcdir) -I. -I$(srcdir)/../include @INCINTL@ \ + + ALL_CFLAGS = $(CFLAGS) $(WARN_CFLAGS) $(INCLUDES) $(CPPFLAGS) $(PICFLAG) \ + $(CET_HOST_FLAGS) ++ALL_CFLAGS += -DPACKAGE_SUFFIX=\"$(strip $(PACKAGE_SUFFIX))\" + ALL_CXXFLAGS = $(CXXFLAGS) $(WARN_CXXFLAGS) $(NOEXCEPTION_FLAGS) $(INCLUDES) \ + $(CPPFLAGS) $(PICFLAG) $(CET_HOST_FLAGS) ++ALL_CXXFLAGS += -DPACKAGE_SUFFIX=\"$(strip $(PACKAGE_SUFFIX))\" + + # The name of the compiler to use. + COMPILER = $(CXX) +@@ -166,8 +169,8 @@ install-strip install: all installdirs + else continue; \ + fi; \ + dir=$(localedir)/$$lang/LC_MESSAGES; \ +- echo $(INSTALL_DATA) $$cat $(DESTDIR)$$dir/$(PACKAGE).mo; \ +- $(INSTALL_DATA) $$cat $(DESTDIR)$$dir/$(PACKAGE).mo; \ ++ echo $(INSTALL_DATA) $$cat $(DESTDIR)$$dir/$(PACKAGE)$(PACKAGE_SUFFIX).mo; \ ++ $(INSTALL_DATA) $$cat $(DESTDIR)$$dir/$(PACKAGE)$(PACKAGE_SUFFIX).mo; \ + done + + mostlyclean: +diff --git a/libcpp/init.cc b/libcpp/init.cc +index 63124c816..4471ff358 100644 +--- a/libcpp/init.cc ++++ b/libcpp/init.cc +@@ -167,7 +167,7 @@ init_library (void) + init_trigraph_map (); + + #ifdef ENABLE_NLS +- (void) bindtextdomain (PACKAGE, LOCALEDIR); ++ (void) bindtextdomain (PACKAGE PACKAGE_SUFFIX, LOCALEDIR); + #endif + } + } +diff --git a/libcpp/system.h b/libcpp/system.h +index 0a0629d55..6fc28a651 100644 +--- a/libcpp/system.h ++++ b/libcpp/system.h +@@ -284,7 +284,7 @@ extern int errno; + #endif + + #ifndef _ +-# define _(msgid) dgettext (PACKAGE, msgid) ++# define _(msgid) dgettext (PACKAGE PACKAGE_SUFFIX, msgid) + #endif + + #ifndef N_ diff --git a/gcc48-libstdc++-api-reference.patch b/gcc48-libstdc++-api-reference.patch new file mode 100644 index 0000000..73a0be1 --- /dev/null +++ b/gcc48-libstdc++-api-reference.patch @@ -0,0 +1,14 @@ +Index: libstdc++-v3/doc/html/index.html +=================================================================== +--- libstdc++-v3/doc/html/index.html (revision 210144) ++++ libstdc++-v3/doc/html/index.html (working copy) +@@ -18,7 +18,7 @@ +

  • + Frequently Asked Questions +

  • +- API and Source Documentation ++ API and Source Documentation +

  • +


    Table of Contents

    The GNU C++ Library Manual
    I. + Introduction + diff --git a/gcc7-avoid-fixinc-error.diff b/gcc7-avoid-fixinc-error.diff new file mode 100644 index 0000000..4036903 --- /dev/null +++ b/gcc7-avoid-fixinc-error.diff @@ -0,0 +1,18 @@ +Index: gcc/Makefile.in +=================================================================== +--- gcc/Makefile.in (revision 255776) ++++ gcc/Makefile.in (working copy) +@@ -3066,13 +3066,6 @@ stmp-fixinc: gsyslimits.h macro_list fix + sysroot_headers_suffix=`echo $${ml} | sed -e 's/;.*$$//'`; \ + multi_dir=`echo $${ml} | sed -e 's/^[^;]*;//'`; \ + fix_dir=include-fixed$${multi_dir}; \ +- if ! $(inhibit_libc) && test ! -d ${BUILD_SYSTEM_HEADER_DIR}; then \ +- echo The directory that should contain system headers does not exist: >&2 ; \ +- echo " ${BUILD_SYSTEM_HEADER_DIR}" >&2 ; \ +- tooldir_sysinc=`echo "${gcc_tooldir}/sys-include" | sed -e :a -e "s,[^/]*/\.\.\/,," -e ta`; \ +- if test "x${BUILD_SYSTEM_HEADER_DIR}" = "x$${tooldir_sysinc}"; \ +- then sleep 1; else exit 1; fi; \ +- fi; \ + $(mkinstalldirs) $${fix_dir}; \ + chmod a+rx $${fix_dir} || true; \ + (TARGET_MACHINE='$(target)'; srcdir=`cd $(srcdir); ${PWD_COMMAND}`; \ diff --git a/gcc7-remove-Wexpansion-to-defined-from-Wextra.patch b/gcc7-remove-Wexpansion-to-defined-from-Wextra.patch new file mode 100644 index 0000000..80ee116 --- /dev/null +++ b/gcc7-remove-Wexpansion-to-defined-from-Wextra.patch @@ -0,0 +1,13 @@ +Index: gcc/c-family/c.opt +=================================================================== +--- gcc/c-family/c.opt (revision 246224) ++++ gcc/c-family/c.opt (working copy) +@@ -596,7 +596,7 @@ C ObjC C++ ObjC++ Var(warn_double_promot + Warn about implicit conversions from \"float\" to \"double\". + + Wexpansion-to-defined +-C ObjC C++ ObjC++ CPP(warn_expansion_to_defined) CppReason(CPP_W_EXPANSION_TO_DEFINED) Var(cpp_warn_expansion_to_defined) Init(0) Warning EnabledBy(Wextra || Wpedantic) ++C ObjC C++ ObjC++ CPP(warn_expansion_to_defined) CppReason(CPP_W_EXPANSION_TO_DEFINED) Var(cpp_warn_expansion_to_defined) Init(0) Warning EnabledBy(Wpedantic) + Warn if \"defined\" is used outside #if. + + Wimplicit-function-declaration diff --git a/gcc9-reproducible-builds-buildid-for-checksum.patch b/gcc9-reproducible-builds-buildid-for-checksum.patch new file mode 100644 index 0000000..7fee01a --- /dev/null +++ b/gcc9-reproducible-builds-buildid-for-checksum.patch @@ -0,0 +1,116 @@ +Use the binaries build-id as checksum for PCH purposes. + +diff --git a/gcc/c-family/c-pch.cc b/gcc/c-family/c-pch.cc +index 2cafa1387bb..7f51f977378 100644 +--- a/gcc/c-family/c-pch.cc ++++ b/gcc/c-family/c-pch.cc +@@ -64,6 +64,66 @@ static FILE *pch_outfile; + + static const char *get_ident (void); + ++#if _GNU_SOURCE ++#include ++ ++#define ALIGN(val, align) (((val) + (align) - 1) & ~((align) - 1)) ++ ++static int ++get_build_id_1 (struct dl_phdr_info *info, size_t, void *data) ++{ ++ for (unsigned i = 0; i < info->dlpi_phnum; ++i) ++ { ++ if (info->dlpi_phdr[i].p_type != PT_NOTE) ++ continue; ++ ElfW(Nhdr) *nhdr ++ = (ElfW(Nhdr) *)(info->dlpi_addr + info->dlpi_phdr[i].p_vaddr); ++ ptrdiff_t size = info->dlpi_phdr[i].p_filesz; ++ ptrdiff_t align = info->dlpi_phdr[i].p_align; ++ if (align != 8) ++ align = 4; ++ while (size >= (ptrdiff_t)sizeof (ElfW(Nhdr))) ++ { ++ if (nhdr->n_type == NT_GNU_BUILD_ID ++ && nhdr->n_namesz == 4 ++ && strncmp ((char *)nhdr ++ + sizeof (ElfW(Nhdr)), ++ "GNU", 4) == 0 ++ && nhdr->n_descsz >= 16) ++ { ++ memcpy (data, ++ (char *)nhdr ++ + ALIGN (sizeof (ElfW(Nhdr)) ++ + nhdr->n_namesz, align), 16); ++ return 1; ++ } ++ size_t offset = (ALIGN (sizeof (ElfW(Nhdr)) ++ + nhdr->n_namesz, align) ++ + ALIGN(nhdr->n_descsz, align)); ++ nhdr = (ElfW(Nhdr) *)((char *)nhdr + offset); ++ size -= offset; ++ } ++ } ++ ++ return 0; ++} ++ ++static const unsigned char * ++get_build_id () ++{ ++ static unsigned char build_id[16]; ++ if (!dl_iterate_phdr (get_build_id_1, build_id)) ++ return NULL; ++ return build_id; ++} ++#else ++static const unsigned char * ++get_build_id () ++{ ++ return NULL; ++} ++#endif ++ + /* Compute an appropriate 8-byte magic number for the PCH file, so that + utilities like file(1) can identify it, and so that GCC can quickly + ignore non-PCH files and PCH files that are of a completely different +@@ -118,8 +178,11 @@ pch_init (void) + } + target_validity = targetm.get_pch_validity (&v.target_data_length); + ++ const unsigned char *chksum = get_build_id (); ++ if (!chksum) ++ chksum = executable_checksum; + if (fwrite (partial_pch, IDENT_LENGTH, 1, f) != 1 +- || fwrite (executable_checksum, 16, 1, f) != 1 ++ || fwrite (chksum, 16, 1, f) != 1 + || fwrite (&v, sizeof (v), 1, f) != 1 + || fwrite (target_validity, v.target_data_length, 1, f) != 1) + fatal_error (input_location, "cannot write to %s: %m", pch_file); +@@ -234,7 +297,10 @@ c_common_valid_pch (cpp_reader *pfile, const char *name, int fd) + cpp_warning (pfile, CPP_W_INVALID_PCH, "%s: not a PCH file", name); + return 2; + } +- if (memcmp (ident + IDENT_LENGTH, executable_checksum, 16) != 0) ++ const unsigned char *chksum = get_build_id (); ++ if (!chksum) ++ chksum = executable_checksum; ++ if (memcmp (ident + IDENT_LENGTH, chksum, 16) != 0) + { + cpp_warning (pfile, CPP_W_INVALID_PCH, + "%s: created by a different GCC executable", name); +diff --git a/gcc/genchecksum.cc b/gcc/genchecksum.cc +index 47280f5147b..bcfdcacf954 100644 +--- a/gcc/genchecksum.cc ++++ b/gcc/genchecksum.cc +@@ -113,8 +113,13 @@ main (int argc, char ** argv) + puts ("#include \"config.h\""); + puts ("#include \"system.h\""); + fputs ("EXPORTED_CONST unsigned char executable_checksum[16] = { ", stdout); ++#if _GNU_SOURCE ++ for (i = 0; i < 16; i++) ++ printf ("0x%02x%s", 0, i == 15 ? " };\n" : ", "); ++#else + for (i = 0; i < 16; i++) + printf ("0x%02x%s", result[i], i == 15 ? " };\n" : ", "); ++#endif + + return 0; + } diff --git a/gcc9-reproducible-builds.patch b/gcc9-reproducible-builds.patch new file mode 100644 index 0000000..6625636 --- /dev/null +++ b/gcc9-reproducible-builds.patch @@ -0,0 +1,15 @@ +Avoid leaking current data on generated file for Ada. + +Index: gcc/ada/gcc-interface/Makefile.in +=================================================================== +--- gcc/ada/gcc-interface/Makefile.in (revision 268977) ++++ gcc/ada/gcc-interface/Makefile.in (working copy) +@@ -2407,6 +2407,7 @@ $(RTSDIR)/s-oscons.ads: ../stamp-gnatlib + $(OSCONS_CPP) ; \ + $(OSCONS_EXTRACT) ; \ + ../bldtools/oscons/xoscons s-oscons) ++ touch -r $(fsrcpfx)ada/gsocket.h $@ + + gnatlib: ../stamp-gnatlib1-$(RTSDIR) ../stamp-gnatlib2-$(RTSDIR) $(RTSDIR)/s-oscons.ads + test -f $(RTSDIR)/s-oscons.ads || exit 1 + diff --git a/tls-no-direct.diff b/tls-no-direct.diff new file mode 100644 index 0000000..a4720cd --- /dev/null +++ b/tls-no-direct.diff @@ -0,0 +1,20 @@ +For i?86 negative offsets to %fs segment accesses cause a hypervisor +trap for Xen. Avoid this by making accesses indirect. + +??? Note that similar to the behavior on SLE11 this only affects +the compiler built on %ix86, not that on x86_64, even with -m32. + +Index: gcc/config/i386/linux.h +=================================================================== +--- gcc/config/i386/linux.h.orig 2015-12-17 15:07:37.785650062 +0100 ++++ gcc/config/i386/linux.h 2015-12-17 15:08:06.393983290 +0100 +@@ -24,3 +24,9 @@ along with GCC; see the file COPYING3. + + #undef MUSL_DYNAMIC_LINKER + #define MUSL_DYNAMIC_LINKER "/lib/ld-musl-i386.so.1" ++ ++/* This slows down Xen, so take a very small general performance hit ++ for not accessing the %fs segment with negative offsets by making ++ GCC not emit direct accesses to %fs at all. */ ++#undef TARGET_TLS_DIRECT_SEG_REFS_DEFAULT ++#define TARGET_TLS_DIRECT_SEG_REFS_DEFAULT 0